Skip to main content

Access Control

When you create access keys through the Partner API, three fields control what those keys can do:

  • user_role tells Tigris what the user in user_id can do in this Partner API call: which access keys the call can manage, and which bucket roles it can grant.
  • buckets_roles controls what S3 operations the access key can perform on specific buckets.
  • access_key_scope controls whether the key also receives default allowed operations such as create bucket and list buckets.

buckets_roles and access_key_scope are stored on the access key and apply to every request the key makes. user_role applies only to the call that you pass it on. Tigris does not store it on the key.

FieldWhere it appliesWhat it controls
user_roleOne Partner API callWhich keys the call can manage and which bucket roles it can set
buckets_rolesS3 requestsWhat the access key can read, write, or manage per bucket
access_key_scopeS3 and IAM requestsWhether the key receives default allowed operations
Three Access ControlsPOST /keyuser_role + buckets_roles+ access_key_scopeuser_rolebuckets_rolesaccess_key_scopeManagement ScopeAdminAny key; any bucket roleMemberOwn keys; own buckets onlyDefault if omitted: MemberS3 Operations (per bucket)ReadOnlyGet, list, headReadWrite+ put, delete, copyEditor+ bucket config, deletionAdminAll ops, all buckets ("*")Default S3 and IAM OperationsstandardCreate/list buckets; manageown keys and policiesno_default_allowDoes not receive thedefault allowed operations

Organization Role (user_role)​

The user_role field tells Tigris what privileges this user has in your system. You pass it on provisioning and access key calls.

ValueWhat the call can do
AdminView, update, rotate, and delete any access key in the org. Grant any bucket role on any bucket in the org, including "*".
MemberView, rotate, and delete only the access keys of user_id. Change the bucket roles and the scope of only those keys. Grant bucket roles only on buckets that user_id provisioned.

The behavioral difference shows up immediately. When you call List Access Keys with user_role: "Admin", the response includes all access keys in the org. With user_role: "Member" (or omitted), you get back only keys owned by that user.

If you omit user_role, the call is treated as Member. A Member call that grants a role on a bucket that user_id did not provision fails with a permission error. If your backend manages access for all of your users, pass user_role: "Admin".

user_role does not limit IAM policies. A Member call can create a policy for any bucket in the org. It can also attach a policy to, or detach a policy from, any access key in the org.

The access key that the call creates does not become an admin. Its access comes only from its buckets_roles, its access_key_scope, and its IAM policies.

Bucket Roles (buckets_roles)​

The buckets_roles field is an array of {bucket_name, role} pairs stored on the access key. See the RBAC permissions table for exactly which S3 operations each role permits.

RoleWhat the key can do on the bucket
ReadOnlyRead and list objects. Create snapshots and forks.
ReadWriteEverything in ReadOnly, plus write and delete objects. It cannot change bucket settings or delete the bucket.
EditorEverything in ReadWrite, plus bucket settings, public access, and bucket deletion. It cannot manage bucket shares or IAM policies.
AdminEvery operation on every bucket in the org. Use it only with "bucket_name": "*".

Use "*" as the bucket name to give a role on all buckets in the org, including buckets created later. A key can have only one "*" entry, and only a user_role: "Admin" call can grant it.

{"bucket_name": "*", "role": "Admin"} must be the only entry on the key. That key is a full org admin. It can do every operation on every bucket, except the deletes that delete protection blocks.

Access Key Scope (access_key_scope)​

This field controls the default allowed operations on the key. A standard key can create buckets, list buckets, and manage its own access keys and IAM policies, even with no bucket role.

ValueWhat it means
standard (default)The key receives the default allowed operations.
no_default_allowThe key does not receive the default allowed operations.

If you omit access_key_scope, the key uses standard. You can set the field on Provision, Create Access Key, and Update Access Key. If you omit the field on update, the current scope stays unchanged.

A key that creates a bucket becomes the owner of that bucket, and an owner can do every operation on it. Use no_default_allow for keys that you give to your users, so that they cannot create buckets that they own.

The Provisioned Access Key​

Provision returns an access key, and that key is the owner of the bucket it provisions. The owner can do every operation on the bucket. It can delete the bucket, change its settings, and turn off soft delete. Bucket roles, IAM policies, and access_key_scope cannot limit what an owner can do on its bucket.

Keep the provisioned key in your backend, or delete it. Give your users a separate key that has only the access they need. See Give Users Data Access Without Bucket Admin.

Each Provision call creates a new owner key. If your backend manages the bucket with the Partner API, it does not need this key. You can delete the key with Delete Access Key after Provision. The Partner API calls for the bucket continue to work, and no access key owns the bucket.

If your users already have the provisioned key, see Move Users Off the Provisioned Key.

How Tigris Evaluates a Request​

Tigris checks each S3 request in this order. It stops at the first step that gives a result.

StepCheckResult
1The bucket has delete protection and the request deletes a bucket or dataDeny
2The key has {"bucket_name": "*", "role": "Admin"}Allow
3The key owns the bucketAllow
4A bucket role on the key permits the operationAllow
5An IAM policy on the key matches. A Deny statement wins over an AllowDeny or allow
6The key uses standard and the operation is a default allowed operationAllow
7No step gave a resultDeny

A policy cannot take away an operation that steps 2 to 4 allow. For example, a Deny on s3:DeleteBucket has no effect on a key with the Editor role, because the role allows the delete at step 4. To limit a key, give it a smaller role, or give it no role and grant access with a policy.

Permission Recipes​

Each recipe shows one request. Replace the IDs and bucket names with your own.

The recipes that grant a bucket role use user_role: "Admin", so that your backend can grant a role on any bucket in the org. You can use Member instead when user_id is the user that provisioned the bucket.

Give Users Data Access Without Bucket Admin​

Use this recipe when your users read and write their own data and your backend manages the buckets.

POST /v1/providers/{provider_id}/orgs/{org_id}/key
Content-Type: application/json

{
"user_id": "user-123",
"user_role": "Admin",
"name": "user-123-data",
"access_key_scope": "no_default_allow",
"buckets_roles": [
{ "bucket_name": "user-data", "role": "ReadWrite" }
]
}

The key can read, write, and delete objects in user-data. It cannot delete the bucket, change bucket settings, turn off soft delete, create buckets, or create access keys.

Move Users Off the Provisioned Key​

Use this recipe when your users already have the provisioned key. You cannot move the ownership of a bucket to a different key. You must replace the secret of the provisioned key instead.

With the provisioned key, a user can create more access keys. These keys continue to work after you rotate the provisioned key. You must also delete them.

  1. Create a key for the user with the Give Users Data Access Without Bucket Admin recipe. Give the new key to the user.

  2. Rotate the provisioned key with Rotate Access Key:

    POST /v1/providers/{provider_id}/orgs/{org_id}/key/rotate
    Content-Type: application/json

    {
    "user_id": "user-123",
    "user_role": "Admin",
    "id": "tid_provisioned_key_id"
    }
  3. Keep the new secret from the response in your backend.

  4. Get all of the access keys in the org with List Access Keys and user_role: "Admin".

  5. If a key is not in the records of your backend, delete it with Delete Access Key.

The old secret and the deleted keys can continue to work for up to 15 minutes.

Read-Only Access to One Bucket​

POST /v1/providers/{provider_id}/orgs/{org_id}/key
Content-Type: application/json

{
"user_id": "user-123",
"user_role": "Admin",
"access_key_scope": "no_default_allow",
"buckets_roles": [
{ "bucket_name": "assets", "role": "ReadOnly" }
]
}

The key can read and list objects in assets. It cannot write or delete objects, and it cannot list or create buckets.

Read-Only Access to All Buckets​

POST /v1/providers/{provider_id}/orgs/{org_id}/key
Content-Type: application/json

{
"user_id": "reporting",
"user_role": "Admin",
"access_key_scope": "no_default_allow",
"buckets_roles": [
{ "bucket_name": "*", "role": "ReadOnly" }
]
}

The key can read every bucket in the org, including buckets created later. Only a user_role: "Admin" call can grant a role on "*".

Different Access per Bucket​

POST /v1/providers/{provider_id}/orgs/{org_id}/key
Content-Type: application/json

{
"user_id": "user-123",
"user_role": "Admin",
"access_key_scope": "no_default_allow",
"buckets_roles": [
{ "bucket_name": "assets", "role": "ReadOnly" },
{ "bucket_name": "uploads", "role": "ReadWrite" }
]
}

The key can read assets, and it can read and write uploads.

Upload-Only Key​

Use a policy for this recipe, because no bucket role allows uploads without reads. The key gets no bucket role, so Tigris evaluates the policy.

POST /v1/providers/{provider_id}/orgs/{org_id}/key
Content-Type: application/json

{
"user_id": "user-123",
"name": "uploader",
"access_key_scope": "no_default_allow",
"create_policies": [
{
"name": "uploads-put-only",
"document": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:PutObject", "s3:AbortMultipartUpload"],
"Resource": ["arn:aws:s3:::uploads/*"]
}
]
}
}
]
}

The key can upload objects to uploads, with multipart uploads too. It cannot read, list, or delete objects. It can overwrite an object that has the same name.

s3:PutObject covers the create, upload part, and complete steps of a multipart upload. Tigris rejects s3:CreateMultipartUpload and s3:UploadPart in a policy.

Policy names are unique in the org. To give the same policy to more keys, create it one time, then pass its name in attach_policies.

Backend Admin Key​

Your backend can use the provisioned key for its bucket. To manage all buckets in the org from one key, create an org admin key:

POST /v1/providers/{provider_id}/orgs/{org_id}/key
Content-Type: application/json

{
"user_id": "platform-backend",
"user_role": "Admin",
"buckets_roles": [
{ "bucket_name": "*", "role": "Admin" }
]
}
warning

Keep this key in your backend. Do not give it to your users. The key can delete every bucket in the org.

Protect Buckets From Accidental Deletion​

Turn on soft delete when you provision the bucket:

POST /v1/providers/{provider_id}/orgs/{org_id}/provision
Content-Type: application/json

{
"bucket_name": "user-data",
"org_name": "Acme Corp",
"user_id": "user-123",
"bucket_options": {
"soft_delete": { "enabled": true, "retention_days": 30 }
}
}

For an existing bucket, use Set Soft Delete.

When a user deletes the bucket, it moves to the deleted buckets list. Use List Deleted Buckets to find it, and Restore Bucket to bring it back.

A soft-deleted bucket stays until you restore it or delete it permanently. It counts toward storage usage until then.

Soft delete protects the bucket from a usual delete request. It does not stop a key that can change bucket settings:

  • The bucket owner, Editor keys, and org admin keys can turn off soft delete.
  • These keys can also permanently delete a soft-deleted bucket over S3.
  • A ReadWrite key cannot do these operations.

Change Bucket Settings for Your Users​

No bucket role allows bucket settings without bucket deletion. Editor includes DeleteBucket, and a policy cannot take it away (see How Tigris Evaluates a Request).

Keep your users on ReadWrite, and change bucket settings from your backend with the Partner API:

Rotate or Revoke a Key​

To replace a leaked secret, call Rotate Access Key. It returns a new secret and keeps the key ID, so the key keeps its roles, policies, and bucket ownership.

To revoke a key, call Delete Access Key. Deleting a key does not delete the buckets that it owns.

note

After you rotate or delete a key, the old secret can continue to work for up to 15 minutes. After you change the bucket roles or the scope of a key, the old access can also continue for up to 15 minutes.

A Member call can rotate or delete only the keys of its user_id. A user_role: "Admin" call can rotate or delete any key in the org.

Fine-Grained Access with IAM Policies​

For access that bucket roles cannot give, use IAM policies. You can create a policy with Create Policy and attach it with attach_policies on Create Access Key or add_policies on Update Access Key. You can also create and attach a policy in one call with create_policies.

Policies only add access. Tigris reads them only when the key's bucket roles and bucket ownership do not already allow the operation (see How Tigris Evaluates a Request):

  • To grant access with a policy, give the key no bucket role on that bucket.
  • A Deny statement blocks only access that a policy or a default allowed operation gives. It does not block access that a bucket role, bucket ownership, or the "*" Admin role gives.