Skip to content

Storage Authentication

Configure credentials for Git and S3 storage backends.

Storage authentication manages credentials for accessing remote storage:

TypeURL FormatUse Case
SSH Keygit@host:org/repo.gitDeploy keys, personal keys
HTTPS + Passwordhttps://host/org/repo.gitUsername/password (deprecated)
HTTPS + Tokenhttps://host/org/repo.gitPersonal access tokens
┌─────────────────────────────────────────────────────────────┐
│ Create Git Authentication │
├─────────────────────────────────────────────────────────────┤
│ │
│ Name * │
│ [github-deploy-key ] │
│ │
│ Authentication Type * │
│ ● SSH Key │
│ ○ Username/Password │
│ │
│ ───────────────────────────────────────────────────────── │
│ │
│ Public Key │
│ [ssh-ed25519 AAAA... deploy@mantis ] │
│ │
│ Private Key * │
│ [•••••••••••••••••••••••••••••••••••••••• ] │
│ Paste your private key (will be encrypted) │
│ │
│ Passphrase │
│ [•••••••••••• ] │
│ Optional: enter if key is passphrase-protected │
│ │
│ [Cancel] [Create] │
│ │
└─────────────────────────────────────────────────────────────┘

Git auth credentials are created with POST /api/v1/storage/git/auth (auth_type: "ssh_key"). The SSH key fields are encrypted at rest.

Terminal window
# Create SSH authentication from a key file
curl -X POST "$MANTIS_URL/api/v1/storage/git/auth" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d "{
\"name\": \"github-deploy-key\",
\"auth_type\": \"ssh_key\",
\"ssh_private_key\": \"$(cat ~/.ssh/deploy_key)\"
}"
# With an encrypted key, also include ssh_passphrase
curl -X POST "$MANTIS_URL/api/v1/storage/git/auth" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d "{
\"name\": \"github-key-protected\",
\"auth_type\": \"ssh_key\",
\"ssh_private_key\": \"$(cat ~/.ssh/protected_key)\",
\"ssh_passphrase\": \"...\"
}"

Generate a key specifically for Mantis:

Terminal window
# Generate ED25519 key (recommended)
ssh-keygen -t ed25519 -C "mantis-deploy" -f ~/.ssh/mantis_deploy_key
# Generate RSA key (wider compatibility)
ssh-keygen -t rsa -b 4096 -C "mantis-deploy" -f ~/.ssh/mantis_deploy_rsa

GitHub:

  1. Go to repository Settings > Deploy keys
  2. Click Add deploy key
  3. Paste public key (cat ~/.ssh/mantis_deploy_key.pub)
  4. Enable Allow write access if needed

GitLab:

  1. Go to repository Settings > Repository > Deploy keys
  2. Click Add key
  3. Paste public key

Bitbucket:

  1. Go to repository Settings > Access keys
  2. Click Add key
  3. Paste public key
┌─────────────────────────────────────────────────────────────┐
│ Create Git Authentication │
├─────────────────────────────────────────────────────────────┤
│ │
│ Name * │
│ [github-token ] │
│ │
│ Authentication Type * │
│ ○ SSH Key │
│ ● Username/Password │
│ │
│ ───────────────────────────────────────────────────────── │
│ │
│ Username │
│ [oauth2 ] │
│ For tokens, use 'oauth2' or service account name │
│ │
│ Password/Token * │
│ [•••••••••••••••••••••••••••••• ] │
│ Personal access token or app password │
│ │
│ [Cancel] [Create] │
│ │
└─────────────────────────────────────────────────────────────┘

HTTPS token auth uses auth_type: "https_token" with a username and password (the token). For provider tokens, username is typically oauth2.

Terminal window
curl -X POST "$MANTIS_URL/api/v1/storage/git/auth" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{
"name": "github-token",
"auth_type": "https_token",
"username": "oauth2",
"password": "ghp_your_personal_access_token"
}'

GitHub Personal Access Token:

  1. Go to Settings > Developer settings > Personal access tokens
  2. Click Generate new token (classic)
  3. Select scope: repo (for private repos)
  4. Copy token

GitLab Personal Access Token:

  1. Go to User Settings > Access Tokens
  2. Create token with read_repository scope
  3. Copy token

Bitbucket App Password:

  1. Go to Personal settings > App passwords
  2. Create password with repository read access
  3. Copy password
Typeauth_typeUse CaseSecurity Level
Access KeysstaticStatic credentialsMedium
IAM Roleiam_roleCross-account accessHigh
┌─────────────────────────────────────────────────────────────┐
│ S3 Storage - Access Keys │
├─────────────────────────────────────────────────────────────┤
│ │
│ Authentication Type: Access Keys │
│ │
│ Access Key ID * │
│ [AKIAIOSFODNN7EXAMPLE ] │
│ │
│ Secret Access Key * │
│ [•••••••••••••••••••••••••••••••••••••••• ] │
│ Will be encrypted at rest │
│ │
└─────────────────────────────────────────────────────────────┘
Terminal window
# Create S3 storage with static credentials
curl -X POST "$MANTIS_URL/api/v1/storage/s3" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{
"name": "artifacts",
"bucket": "my-bucket",
"region": "us-west-2",
"auth_type": "static",
"access_key_id": "AKIAIOSFODNN7EXAMPLE",
"secret_access_key": "..."
}'
Terminal window
# Create IAM user
aws iam create-user --user-name mantis-storage
# Attach policy
aws iam put-user-policy \
--user-name mantis-storage \
--policy-name mantis-s3-access \
--policy-document file://policy.json
# Create access keys
aws iam create-access-key --user-name mantis-storage
┌─────────────────────────────────────────────────────────────┐
│ S3 Storage - IAM Role │
├─────────────────────────────────────────────────────────────┤
│ │
│ Authentication Type: IAM Role │
│ │
│ Role ARN * │
│ [arn:aws:iam::123456789:role/MantisS3Role ] │
│ │
│ External ID │
│ [mantis-unique-id ] │
│ Recommended for cross-account security │
│ │
└─────────────────────────────────────────────────────────────┘
  1. Create role in target account:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::SOURCE_ACCOUNT:root"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "mantis-unique-id"
}
}
}
]
}
  1. Attach S3 access policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:ListBucket"],
"Resource": ["arn:aws:s3:::target-bucket", "arn:aws:s3:::target-bucket/*"]
}
]
}

All sensitive credentials are encrypted:

Credential TypeEncryption
SSH private keysAES-256-GCM
SSH passphrasesAES-256-GCM
HTTPS passwordsAES-256-GCM
S3 secret keysAES-256-GCM

Encryption includes AAD (Additional Authenticated Data) binding to the credential ID, preventing credential swapping attacks.

Sensitive values are never displayed in full:

┌─────────────────────────────────────────────────────────────┐
│ Git Authentication: github-deploy-key │
├─────────────────────────────────────────────────────────────┤
│ │
│ Type: SSH Key │
│ Public Key: ssh-ed25519 AAAA...abc123 │
│ Private Key: •••••••••••••••• │
│ Has Passphrase: Yes │
│ │
│ Created: January 15, 2024 │
│ Last Used: 5 minutes ago │
│ │
│ [Update Key] [Delete] │
│ │
└─────────────────────────────────────────────────────────────┘

Update credentials without service disruption:

Terminal window
# Update an SSH git auth credential (by auth ID)
curl -X PUT "$MANTIS_URL/api/v1/storage/git/auth/<auth-id>" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d "{\"ssh_private_key\": \"$(cat ~/.ssh/new_deploy_key)\"}"
# Update an HTTPS token credential
curl -X PUT "$MANTIS_URL/api/v1/storage/git/auth/<auth-id>" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"password": "ghp_new_token"}'
# Rotate S3 access keys (by storage ID)
curl -X PUT "$MANTIS_URL/api/v1/storage/s3/<storage-id>" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"access_key_id": "AKIA...", "secret_access_key": "..."}'
Terminal window
# List all git auth credentials (sensitive fields are redacted)
curl "$MANTIS_URL/api/v1/storage/git/auth" \
-H "Authorization: Bearer $TOKEN"
┌─────────────────────────────────────────────────────────────┐
│ Git Authentications │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌────────────────────┬──────────┬─────────────┬─────────┐ │
│ │ Name │ Type │ Used By │ Actions │ │
│ ├────────────────────┼──────────┼─────────────┼─────────┤ │
│ │ github-deploy-key │ SSH Key │ 3 storages │ [···] │ │
│ │ gitlab-token │ Token │ 1 storage │ [···] │ │
│ │ bitbucket-ssh │ SSH Key │ 0 storages │ [···] │ │
│ └────────────────────┴──────────┴─────────────┴─────────┘ │
│ │
│ [+ New Authentication] │
│ │
└─────────────────────────────────────────────────────────────┘
Terminal window
# Delete a git auth credential (by auth ID)
curl -X DELETE "$MANTIS_URL/api/v1/storage/git/auth/<auth-id>" \
-H "Authorization: Bearer $TOKEN"
ApproachScopeRevocationRecommendation
Deploy keysSingle repoEasyRecommended
Personal tokensAll user reposBroad impactDevelopment only
Credential TypeRotation Frequency
Deploy keysAnnually or on compromise
Access tokensEvery 90 days
S3 access keysEvery 90 days

Prefer iam_role (STS AssumeRole) over static access keys when running on AWS:

  • Short-lived credentials instead of long-lived secrets
  • Centralized role management
  • Audit trail via CloudTrail

Grant minimum required permissions:

{
"Effect": "Allow",
"Action": ["s3:GetObject"],
"Resource": ["arn:aws:s3:::bucket/specific-prefix/*"]
}

Regularly review which authentications are in use:

Terminal window
# List git auth credentials, then cross-reference against storage sources
curl "$MANTIS_URL/api/v1/storage/git/auth" -H "Authorization: Bearer $TOKEN"
curl "$MANTIS_URL/api/v1/storage/git" -H "Authorization: Bearer $TOKEN" | \
jq '[.data[].auth_id] | unique'

Cause: Key not added to Git provider or wrong key

Solution:

  1. Verify public key is added to repository
  2. Check key permissions: chmod 600 ~/.ssh/deploy_key
  3. Test manually: ssh -T git@github.com

Cause: Unknown host key

Solution:

  1. Add host to known_hosts
  2. Or configure SSH to accept new hosts (less secure)

Cause: Invalid or expired token

Solution:

  1. Regenerate token in Git provider
  2. Update authentication in Mantis
  3. Verify token has required scopes

Cause: Access key doesn’t exist or is disabled

Solution:

  1. Verify key is active in IAM Console
  2. Check for typos in key ID
  3. Regenerate keys if needed

Cause: Secret key mismatch

Solution:

  1. Re-enter secret key carefully
  2. Check for hidden characters
  3. Regenerate keys if persistent