Documentation Index Fetch the complete documentation index at: https://mintlify.com/deuxfleurs-org/garage/llms.txt
Use this file to discover all available pages before exploring further.
Key management endpoints allow you to create, update, and manage S3 access keys for your Garage cluster.
List Keys
Returns all API access keys in the cluster.
Response
Array of key information objects Access key ID (also used as AWS_ACCESS_KEY_ID)
Human-friendly name for the key
Creation date (ISO 8601 format)
Expiration date (ISO 8601 format, null if never expires)
Whether the key is currently expired
Example
curl -H 'Authorization: Bearer s3cr3t' \
http://localhost:3903/v2/ListKeys | jq
[
{
"id" : "GK31c2f218a2e44f485b94239e" ,
"name" : "my-app-key" ,
"created" : "2025-06-15T10:23:45.123Z" ,
"expiration" : null ,
"expired" : false
},
{
"id" : "GK8a7b3c9d4e5f6a1b2c3d4e5f" ,
"name" : "temporary-key" ,
"created" : "2025-06-01T08:00:00.000Z" ,
"expiration" : "2025-07-01T08:00:00.000Z" ,
"expired" : false
}
]
Get Key Info
Returns detailed information about a specific access key.
Query Parameters
Exact access key ID to look up
Partial key ID or name to search for
Whether to return the secret access key (default: false)
You must specify exactly one of: id or search
Response
Access key ID (AWS_ACCESS_KEY_ID)
Expiration date (ISO 8601, null if never expires)
Whether the key is currently expired
Secret access key (AWS_SECRET_ACCESS_KEY). Only returned if showSecretKey=true
Key-level permissions Whether this key can create new buckets
Buckets this key has access to Global aliases for this bucket
Local aliases for this bucket under this key
Permissions this key has on this bucket
Example
curl -H 'Authorization: Bearer s3cr3t' \
'http://localhost:3903/v2/GetKeyInfo?id=GK31c2f218a2e44f485b94239e&showSecretKey=true' | jq
{
"accessKeyId" : "GK31c2f218a2e44f485b94239e" ,
"name" : "my-app-key" ,
"created" : "2025-06-15T10:23:45.123Z" ,
"expiration" : null ,
"expired" : false ,
"secretAccessKey" : "b8d57c3f9e2a1b4c6d8e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1" ,
"permissions" : {
"createBucket" : false
},
"buckets" : [
{
"id" : "70ec0cd3e60f0a6f934a1f1ab1e0c84e4b0e3e5a1c7e3b4a" ,
"globalAliases" : [ "my-bucket" ],
"localAliases" : [ "my-local-bucket" ],
"permissions" : {
"read" : true ,
"write" : true ,
"owner" : false
}
}
]
}
Create Key
Creates a new API access key.
Request Body
Human-friendly name for the key
Expiration date (ISO 8601 format)
Set to true if the key should never expire (default: true)
Permissions to grant Allow creating new buckets
The access key ID and secret key are automatically generated by Garage.
Response
Returns the same response as GetKeyInfo, including the secretAccessKey field.
The secret access key is returned only once upon creation. Save it securely!
Example
curl -X POST -H 'Authorization: Bearer s3cr3t' \
-H 'Content-Type: application/json' \
-d '{
"name": "my-new-key",
"neverExpires": true,
"allow": {
"createBucket": false
}
}' \
http://localhost:3903/v2/CreateKey
{
"accessKeyId" : "GK9f8e7d6c5b4a3928171615" ,
"name" : "my-new-key" ,
"created" : "2025-06-15T14:30:00.000Z" ,
"expiration" : null ,
"expired" : false ,
"secretAccessKey" : "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2" ,
"permissions" : {
"createBucket" : false
},
"buckets" : []
}
Import Key
Imports an existing API key with known credentials.
This feature should only be used for migrations and backup restore. Do not use it to generate custom key identifiers or you will break your Garage cluster.
Request Body
Secret access key to import
Human-friendly name for the key (default: “Imported key”)
Response
Returns the same response as GetKeyInfo, but without the secretAccessKey field.
Example
curl -X POST -H 'Authorization: Bearer s3cr3t' \
-H 'Content-Type: application/json' \
-d '{
"accessKeyId": "GK1234567890abcdef123456",
"secretAccessKey": "abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890",
"name": "migrated-key"
}' \
http://localhost:3903/v2/ImportKey
Update Key
Updates information about an existing access key.
POST /v2/UpdateKey?id= < key-i d >
Query Parameters
Request Body
New expiration date (ISO 8601 format)
Set to true to remove expiration
Permissions to grant Allow creating new buckets
Permissions to revoke Deny creating new buckets
The secret access key is not returned in the response. It cannot be changed after key creation.
Response
Returns the same response as GetKeyInfo, with secretAccessKey set to null.
Example: Rename Key
curl -X POST -H 'Authorization: Bearer s3cr3t' \
-H 'Content-Type: application/json' \
-d '{"name": "updated-key-name"}' \
'http://localhost:3903/v2/UpdateKey?id=GK31c2f218a2e44f485b94239e'
Example: Set Expiration
curl -X POST -H 'Authorization: Bearer s3cr3t' \
-H 'Content-Type: application/json' \
-d '{"expiration": "2025-12-31T23:59:59Z"}' \
'http://localhost:3903/v2/UpdateKey?id=GK31c2f218a2e44f485b94239e'
Example: Grant Permission
curl -X POST -H 'Authorization: Bearer s3cr3t' \
-H 'Content-Type: application/json' \
-d '{
"allow": {
"createBucket": true
}
}' \
'http://localhost:3903/v2/UpdateKey?id=GK31c2f218a2e44f485b94239e'
Example: Revoke Permission
curl -X POST -H 'Authorization: Bearer s3cr3t' \
-H 'Content-Type: application/json' \
-d '{
"deny": {
"createBucket": true
}
}' \
'http://localhost:3903/v2/UpdateKey?id=GK31c2f218a2e44f485b94239e'
Delete Key
Deletes an access key from the cluster.
POST /v2/DeleteKey?id= < key-i d >
Query Parameters
The key’s access will be removed from all buckets. Buckets are not automatically deleted and may become dangling. You should manually clean them up before deleting keys.
Example
curl -X POST -H 'Authorization: Bearer s3cr3t' \
'http://localhost:3903/v2/DeleteKey?id=GK31c2f218a2e44f485b94239e'
Response
Returns 200 OK on success with an empty response body.
Key Permissions on Buckets
Key permissions on buckets are managed using the bucket management endpoints:
These endpoints allow you to control read, write, and owner permissions for specific keys on specific buckets.
Permission Levels
Key-Level Permissions
createBucket : Allows the key to create new buckets using the S3 API
Bucket-Level Permissions
read : Allows reading objects from the bucket
write : Allows creating, updating, and deleting objects in the bucket
owner : Allows managing bucket configuration (website, quotas, etc.)
Owner permission on a bucket also implicitly grants read and write permissions.
Key Naming Best Practices
Use descriptive names that indicate the key’s purpose:
production-app-key
backup-service-key
dev-environment-key
Include environment or application identifiers
Use expiration dates for temporary or shared keys
Avoid generic names like “key1” or “test”
Security Best Practices
Rotate keys regularly : Create new keys and delete old ones periodically
Use expiration dates : Set expiration for keys that don’t need permanent access
Principle of least privilege : Grant only the minimum required permissions
Store secrets securely : Never commit secret keys to version control
Monitor key usage : Use Garage metrics to track key activity
Delete unused keys : Remove keys that are no longer needed
Use separate keys : Don’t share keys between different applications or environments
Example: Complete Key Lifecycle
1. Create a key
curl -X POST -H 'Authorization: Bearer s3cr3t' \
-H 'Content-Type: application/json' \
-d '{"name": "app-production-key"}' \
http://localhost:3903/v2/CreateKey
2. Grant permissions on a bucket
curl -X POST -H 'Authorization: Bearer s3cr3t' \
-H 'Content-Type: application/json' \
-d '{
"bucketId": "70ec0cd3e60f0a6f934a1f1ab1e0c84e4b0e3e5a1c7e3b4a",
"accessKeyId": "GK9f8e7d6c5b4a3928171615",
"permissions": {"read": true, "write": true, "owner": false}
}' \
http://localhost:3903/v2/AllowBucketKey
3. Use the key with S3 client
export AWS_ACCESS_KEY_ID = "GK9f8e7d6c5b4a3928171615"
export AWS_SECRET_ACCESS_KEY = "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2"
aws s3 ls s3://my-bucket --endpoint-url https://s3.garage.local
4. Rotate the key (create new, update app, delete old)
# Create new key
curl -X POST -H 'Authorization: Bearer s3cr3t' \
-H 'Content-Type: application/json' \
-d '{"name": "app-production-key-v2"}' \
http://localhost:3903/v2/CreateKey
# Grant same permissions
curl -X POST -H 'Authorization: Bearer s3cr3t' \
-H 'Content-Type: application/json' \
-d '{
"bucketId": "70ec0cd3e60f0a6f934a1f1ab1e0c84e4b0e3e5a1c7e3b4a",
"accessKeyId": "<NEW_KEY_ID>",
"permissions": {"read": true, "write": true, "owner": false}
}' \
http://localhost:3903/v2/AllowBucketKey
# Update application configuration with new credentials
# ...
# Delete old key after verification
curl -X POST -H 'Authorization: Bearer s3cr3t' \
'http://localhost:3903/v2/DeleteKey?id=GK9f8e7d6c5b4a3928171615'