Access keys
An access key is how an S3 tool, an SDK or an AI agent proves it may reach your buckets. Each key carries its own set of buckets and permissions, so every program can have exactly the access it needs and no more: a nightly backup job can write to one bucket and read nothing else, a web app's server can hand out upload links for its own bucket, and an agent can keep its memory in a bucket of its own without being able to touch the rest. When a program is retired, deleting its key closes its door without disturbing any other.
Keys live on the Access Keys page of the dashboard (https://app.strg.com/access-keys), where
you can create, list and delete them. The REST API does the same for a
key that has Manage access keys through the API.
What a key is
Every key is made of these parts:
| Access key ID and secret access key | The pair any S3 client signs its requests with (AWS Signature Version 4). They go into AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY |
| Name | Required, at most 64 characters. For you: what uses the key |
| Buckets | All buckets, or a list of buckets - Scope has the details |
| Object prefix | Optional - Object prefix explains it |
| Permissions | What the key may do - Permissions lists every one |
- The secret access key is shown once, in the dialog that creates the key, and STRG has no way to show it again. If it ever goes missing, a new key takes only a moment to create, and deleting the old one makes sure nobody else can use it.
- Keys stay exactly as they were created, which makes them easy to reason about: a key that worked yesterday does the same today. Different buckets, a different prefix or different permissions simply means a new key, and the old one can then be deleted.
- Deleting a key cannot be undone. Within 60 seconds, everywhere, STRG stops accepting requests signed with it - presigned URLs included.
- The list tags a key made by an AI agent through the MCP server Created by an agent, and a key made through the REST API Created through the API.
A card on file
Creating a key needs a verified card on your account. Until there is one, the Access Keys page
shows Add a card before creating an access key. in place of the form, with an Add a card
button that opens card entry right there on the page. Connecting an agent, an agent's
create_access_key and creating a key through the REST API
work the same way. Billing explains why the card is asked for.
Deleting a key always works.
When a key starts working
A key works in a region once you have a bucket there. After you create it, each region it needs shows Setting up in region and then Ready in region - usually within a few minutes. The Access Keys page refreshes this by itself while any key is still being set up.
In a region where you have no bucket yet, a key answers just as it would for a bucket that does not
exist: a bucket or object operation is 404 NoSuchBucket,
ListBuckets lists nothing, and
CreateBucket creates your first bucket there - the
Buckets permissions say more.
Until a key is ready in a region where you do have a bucket - while it shows Setting up in
rather than Ready in - that region's S3 endpoint answers requests signed with it with
403 InvalidAccessKeyId, for every operation but CreateBucket,
which works. The endpoints are listed in the S3 API overview.
A key for all buckets also reaches buckets you create later, including in a region you had not used before, once it shows Ready there. With Manage buckets, it can even create your first bucket in a region itself.
Scope
A key's scope is the set of buckets it can reach. There are two choices:
| Choice | Reaches |
|---|---|
| All buckets | Every bucket in your account, in every region |
| Only some buckets | Up to 100 buckets you pick. Each must exist when you create the key |
A key limited to some buckets reaches the buckets that exist when it is created. A bucket created later is reached by a new key.
A key limited to some buckets stops reaching a bucket that is deleted and created again under the same name - even though the Access Keys page still shows the name on the key. A new key, made after the bucket was created again, reaches the new bucket.
The Access Keys page marks a bucket on a key's list as deleted once it no longer exists.
A few permissions depend on the scope:
| Permission | Needs |
|---|---|
Manage buckets (buckets:write) | A key for all buckets |
Delete buckets (buckets:delete) | A key for all buckets |
List all bucket names (buckets:list-all) | A key limited to some buckets |
The dashboard keeps a permission the chosen scope cannot carry disabled, and takes it off again if the scope changes after it was chosen.
With a key limited to some buckets, STRG answers ListBuckets with 403 AccessDenied unless
the key has List all bucket names. Many S3 tools and SDKs call ListBuckets before anything
else, so that permission is what lets such a tool get started with a limited key.
Object prefix
An object prefix narrows a key further, to the objects whose key starts with a given text - handy
when several programs share one bucket, each in a folder of its own. Ticking
Only objects whose name starts with… opens a field for the prefix, such as reports/. The
prefix is at most 1,024 bytes and cannot contain control characters. It is matched literally and
is case-sensitive - there are no wildcards.
With a prefix set, each kind of request is held to it like this:
| Request | Rule |
|---|---|
| Any operation on an object | The object key must start with the prefix |
ListObjectsV2, ListObjects, ListObjectVersions, ListMultipartUploads | The request must set prefix to the key's prefix or a longer one. A listing without it is answered 403 AccessDenied |
CopyObject, UploadPartCopy | The source (x-amz-copy-source) must be in the key's buckets and start with the prefix too |
DeleteObjects | Every key in the request must start with the prefix; one that does not means nothing in the request is deleted |
| Bucket settings (CORS, lifecycle, encryption, Object Lock) | Not limited by the prefix |
STRG answers a request outside the key's buckets or prefix with 403 AccessDenied.
For example, here is a listing with a key limited to reports/:
- AWS CLI
- Python (boto3)
- JavaScript (AWS SDK v3)
aws s3api list-objects-v2 \
--bucket my-bucket \
--prefix reports/ \
--endpoint-url https://s3.eu-central-1.strg.com \
--region eu-central-1
import boto3
s3 = boto3.client(
"s3",
endpoint_url="https://s3.eu-central-1.strg.com",
region_name="eu-central-1",
)
response = s3.list_objects_v2(Bucket="my-bucket", Prefix="reports/")
for item in response.get("Contents", []):
print(item["Key"])
import { S3Client, ListObjectsV2Command } from "@aws-sdk/client-s3";
const s3 = new S3Client({
endpoint: "https://s3.eu-central-1.strg.com",
region: "eu-central-1",
});
const response = await s3.send(
new ListObjectsV2Command({ Bucket: "my-bucket", Prefix: "reports/" }),
);
for (const item of response.Contents ?? []) {
console.log(item.Key);
}
Permissions
Permissions say what a key may do inside its scope. Each one has a name, shown under its label in the dashboard and used in the tables below, and a (?) button with a short explanation. A key needs at least one permission from the Objects, Object Lock, Buckets or Bucket settings groups: a key with nothing but AI agents (MCP) and REST API permissions could reach nothing, so the dashboard asks for a storage permission before it creates one.
STRG answers a request the key's permissions do not allow with 403 AccessDenied.
Templates
The dashboard fills in the permissions from a Template, chosen above the list, so a common key takes one click. A new key starts on Full Access.
| Template | Permissions |
|---|---|
| Full Access | Every permission the key's scope allows, except Act without confirmation - so Manage access keys through MCP and Manage access keys through the API included |
| Write Access | The read-only set, plus Write objects |
| Read-only Access | List objects, Read objects, Read retention, Read legal holds, Read Object Lock settings, Read encryption settings, Read lifecycle rules - and List all bucket names on a key limited to some buckets |
| Custom | The permissions as you tick them |
Every template includes Use the MCP server. Unticking it makes a key no agent can use through the MCP server.
No template includes Act without confirmation. You can tick it yourself for an agent that should act without asking you first - Confirmation explains what it changes.
Ticking or unticking any permission switches the template to Custom, and the permissions stay just as you left them. Changing the key's buckets between All buckets and Only some buckets applies the chosen template again for the new scope. Connecting an agent offers the same templates, with Use the MCP server always on.
Full Access includes Manage Object Lock, which can enable Object Lock on a bucket - and that is permanent, as the note under Bucket settings explains.
Always included
Every key has these two, because every S3 client needs them before it can use a bucket at all. They stay on.
| Permission | Label | Allows | S3 operations |
|---|---|---|---|
buckets:list | List buckets | List the buckets the key can reach and check that one exists. Every S3 client needs this before it can use a bucket | ListBuckets, HeadBucket |
buckets:read-config | Read bucket settings | Read a bucket's location, versioning, ACL and CORS settings | GetBucketLocation, GetBucketVersioning, GetBucketAcl, GetBucketCors, GetBucketPolicy, GetBucketTagging, GetBucketOwnershipControls, GetPublicAccessBlock, GetBucketAccelerateConfiguration, GetBucketRequestPayment, GetBucketNotificationConfiguration, GetBucketNotification |
With buckets:list, a key limited to some buckets lists its own buckets and no others;
Scope has more.
Objects
These are the permissions most keys are about: listing, reading, writing and deleting objects.
| Permission | Label | Allows | S3 operations |
|---|---|---|---|
objects:list | List objects | List objects, object versions and unfinished multipart uploads. With an object prefix, every listing must name that prefix or a longer one | ListObjectsV2, ListObjects, ListObjectVersions, ListMultipartUploads |
objects:read | Read objects | Download objects and read their metadata, and use an object as the source of a copy - which needs Write objects as well | GetObject, HeadObject, GetObjectAcl, GetObjectTagging; the source side of CopyObject and UploadPartCopy |
objects:write | Write objects | Upload objects, including multipart uploads. Also deleting an object by name, which hides it behind a delete marker rather than removing a version. A copy also needs Read objects; uploading an object that is already locked needs Set retention or Set legal holds | PutObject, CopyObject, CreateMultipartUpload, UploadPart, UploadPartCopy, CompleteMultipartUpload, AbortMultipartUpload, ListParts, DeleteObjectTagging; DeleteObject and DeleteObjects without a versionId |
objects:delete-versions | Delete object versions | Permanently delete a specific object version. This permission - not Write objects - is what that needs | DeleteObject and DeleteObjects with a versionId |
We keep every version of every object for you, so deleting by name leaves the earlier versions stored - and billed as stored data. Delete object versions or a lifecycle policy is what removes them.
Object Lock
These act on single objects in a bucket with Object Lock enabled - the kind of protection a compliance archive or a ransomware-proof backup relies on. Object Lock explains how it works.
| Permission | Label | Allows | S3 operations |
|---|---|---|---|
object-retention:read | Read retention | Read an object's retention mode and retain-until date | GetObjectRetention |
object-retention:write | Set retention | Set or extend an object's retention, and upload an object with a retention already set. A lock in compliance mode cannot be shortened or removed by anyone | PutObjectRetention; the x-amz-object-lock-mode and x-amz-object-lock-retain-until-date headers on PutObject, CopyObject, CreateMultipartUpload |
object-retention:bypass-governance | Bypass governance retention | Delete, or shorten the retention of, objects locked in governance mode, by sending x-amz-bypass-governance-retention: true. Without it, governance mode is as immovable for this key as compliance mode | x-amz-bypass-governance-retention on DeleteObject, DeleteObjects, PutObjectRetention |
object-legal-hold:read | Read legal holds | Read whether an object is under legal hold | GetObjectLegalHold |
object-legal-hold:write | Set legal holds | Place or lift a legal hold on an object, and upload an object already under one | PutObjectLegalHold; the x-amz-object-lock-legal-hold header on PutObject, CopyObject, CreateMultipartUpload |
Buckets
These manage the buckets themselves - useful for a deployment script or an agent that sets up storage on its own.
| Permission | Label | Scope | Allows | S3 operations |
|---|---|---|---|---|
buckets:list-all | List all bucket names | Some buckets only | List the names of every bucket in your account, not only the ones this key can reach. Many S3 tools and SDKs need this for a key limited to some buckets to work | ListBuckets |
buckets:write | Manage buckets | All buckets only | Create buckets, make a bucket public or private, and change its CORS and versioning settings. Also creating a bucket through the MCP server's create_bucket tool | CreateBucket, PutBucketAcl, PutBucketCors, DeleteBucketCors, PutBucketVersioning, PutObjectAcl, DeleteBucketTagging |
buckets:delete | Delete buckets | All buckets only | Delete any empty bucket in your account | DeleteBucket |
CreateBucket creates the bucket in the endpoint's region, your
first bucket there included. A first bucket in a region sets storage up there first, so that
request takes longer - up to about 90 seconds - and may answer 503 SlowDown with a Retry-After
header, which the AWS SDKs retry for you; the retry simply joins the creation already under way.
The key is set up in that region as part of the request, so its next request there works. If that
could not be finished in time, the key shows Setting up in that region and is ready within a
few minutes, as described above; until then, that region's other
operations answer 403 InvalidAccessKeyId.
ListBuckets answers with the buckets in the endpoint's region - the
ListBuckets page has the details.
Bucket settings
These read and change a bucket's Object Lock, encryption and lifecycle settings.
| Permission | Label | Allows | S3 operations |
|---|---|---|---|
bucket-object-lock:read | Read Object Lock settings | Read a bucket's Object Lock configuration | GetObjectLockConfiguration |
bucket-object-lock:write | Manage Object Lock | Change a bucket's default retention, and enable Object Lock - which can never be turned off again. Needs Read Object Lock settings as well: the current configuration is read before every change | PutObjectLockConfiguration |
bucket-encryption:read | Read encryption settings | Read a bucket's default server-side encryption | GetBucketEncryption |
bucket-encryption:write | Manage encryption | Change a bucket's default server-side encryption | PutBucketEncryption. STRG answers DeleteBucketEncryption with 501 NotImplemented |
bucket-lifecycle:read | Read lifecycle rules | Read a bucket's lifecycle rules | GetBucketLifecycleConfiguration, GetBucketLifecycle |
bucket-lifecycle:write | Manage lifecycle rules | Change or remove a bucket's lifecycle rules | PutBucketLifecycleConfiguration, PutBucketLifecycle, DeleteBucketLifecycle |
A key with Manage Object Lock can enable Object Lock on your buckets, which can never be turned off. Objects it locks cannot be deleted until their lock expires, and are billed as stored data until then.
AI agents (MCP)
These permissions are for the STRG MCP server at https://mcp.strg.com/mcp, which lets an AI
agent work with your storage, and grant no storage access of their own.
Getting started with MCP walks through connecting one.
| Permission | Label | Allows |
|---|---|---|
mcp:enabled | Use the MCP server | Sign in to the MCP server with this key, sent as Authorization: Bearer <access key id>:<secret>. A key created for an agent through the MCP sign-in always carries this. The agent can do no more there than the key's other permissions allow |
mcp:access-management | Manage access keys through MCP | Let an MCP client using this key list and revoke any of your access keys, whatever their access, with the list_access_keys and revoke_access_key tools, and create new ones with the create_access_key tool - never with more access than this key has. Needs Use the MCP server as well. Keys managed by an agent has the details |
mcp:skip-confirmation | Act without confirmation | Let an MCP client using this key act without asking you first - Confirmation explains what that skips. Applies to the MCP server only. Needs Use the MCP server as well |
Confirmation
An agent works quickly, and a few operations cannot be taken back. So, without Act without confirmation, the MCP server asks you to confirm each of these before it runs it:
| Operation | Asked when |
|---|---|
Deleting an object version (DeleteObject, DeleteObjects) | A versionId is given. Deleting by name only adds a delete marker, so it is not asked |
Setting retention (PutObjectRetention) | Always |
Placing or lifting a legal hold (PutObjectLegalHold) | Always |
Changing a bucket's Object Lock configuration (PutObjectLockConfiguration) | Always |
Replacing a bucket's lifecycle rules (PutBucketLifecycleConfiguration) | Always |
Uploading or copying an object under Object Lock (PutObject, CopyObject, CreateMultipartUpload) | A retention mode is set, or a legal hold is ON |
Making a bucket public (PutBucketAcl) | Any ACL or grant other than the canned ACL private |
Creating a public bucket (create_bucket) | The visibility is public |
Creating a bucket (CreateBucket) | Any ACL or grant other than the canned ACL private |
Deleting a bucket (DeleteBucket) | Always |
| Bypassing governance retention | On any operation |
Creating an access key (create_access_key) | Always |
Revoking an access key (revoke_access_key) | Always |
- Your MCP client shows the question, naming the bucket, object, version or key it is about. Nothing happens until you accept. If you decline, the agent is told not to try again.
- When an MCP client has no way to ask you, nothing is done, and the agent is told so. The same operation works in the dashboard, or through a key that has Act without confirmation.
- The MCP server keeps a key's secret access key from an agent whose key does not have this permission, so the agent cannot step around the question with S3 tools of its own.
- The same key used directly by an S3 client is never asked.
Keys that could use the MCP server before Act without confirmation existed have it, so they behave just as they always did.
REST API
This permission is for the STRG REST API at https://api.strg.com/v1/ - the way for your own
code to create and rotate keys automatically - and grants no storage access of its own.
The REST API overview explains how it works.
| Permission | Label | Allows | REST API operations |
|---|---|---|---|
api:access-management | Manage access keys through the API | Lets this key use the REST API, sent as Authorization: Bearer <access key id>:<secret>, to list, look up and delete any of your access keys, and to create new ones - never with more access than this key has. It has no partner permission of its own, though like every key it carries at least one storage permission | List access keys, Get an access key, Create an access key, Delete an access key |
A key with Manage access keys through the API can delete every other key in your account - even a key limited to one bucket can delete a key for all buckets. A deleted key stops working within 60 seconds, everywhere, and cannot be restored. This permission belongs with a program you trust with all of your keys.
- The REST API never asks for confirmation. Act without confirmation is about the MCP server alone.
- A key created through the REST API follows the same rules as one an agent creates: never more permissions, buckets or a wider prefix than the calling key - Creating has the details.
- A key can delete itself, after which it stops working like any deleted key.
- The dashboard's own key and the assistant's are never listed or deletable through the REST API.
Permissions that need another
A few permissions do nothing on their own, so each comes with a partner:
| Permission | Needs at least one of |
|---|---|
Bypass governance retention (object-retention:bypass-governance) | Delete object versions (objects:delete-versions) or Set retention (object-retention:write) |
Manage Object Lock (bucket-object-lock:write) | Read Object Lock settings (bucket-object-lock:read) |
Manage access keys through MCP (mcp:access-management) | Use the MCP server (mcp:enabled) |
Act without confirmation (mcp:skip-confirmation) | Use the MCP server (mcp:enabled) |
The dashboard keeps such a permission disabled, with the reason beside it (for example Needs Read Object Lock settings as well.), until its partner is chosen - and takes it off again if the partner is unticked.
Keys managed by an agent
When you connect an agent through the MCP sign-in, you pick its key's buckets, prefix and permissions on the same form as on the Access Keys page, with Use the MCP server always on and Act without confirmation off unless you tick it. The same form, with the same templates, opens under Choose agent permissions when you pick Static credentials in the Connect your agent dialog at the top of the dashboard. A key made there is listed like one made on the Access Keys page, without the Created by an agent tag.
An agent whose key has Manage access keys through MCP can list, revoke and create keys - useful when an agent hands narrower keys to the tools it sets up.
Listing and revoking
The agent can list every access key in your account with list_access_keys - never a secret -
and revoke any of them with revoke_access_key, whatever the key's access. Unlike creating,
listing and revoking reach beyond what the agent's own key can reach.
A key with Manage access keys through MCP can revoke every other key in your account - even a key limited to one bucket can revoke a key for all buckets. A revoked key stops working within 60 seconds, everywhere, and cannot be restored. This permission belongs with an agent you trust with all of your keys.
- Unless the agent's key has Act without confirmation, you are asked to confirm each revoke first - Confirmation has the details.
- An agent can revoke the key it is connected with, which disconnects it.
- The keys STRG manages for you - the dashboard's own key and the assistant's - are never listed or revocable through the MCP server.
Creating
The agent can create further keys with the create_access_key tool. A key created that way never
has more access than the key the agent is using:
| The new key | |
|---|---|
| Permissions | Only permissions the agent's key has - so Act without confirmation only if the agent's key has it |
| Buckets | Only buckets the agent's key can reach. All buckets only if the agent's key is for all buckets |
| Object prefix | If the agent's key has a prefix, the new key's prefix must start with it |
STRG creates nothing for a request that goes beyond this, and says which part did. Unless the agent's key has Act without confirmation, you are asked to confirm each new key first. The secret of a key created this way is returned once, to the agent. Such keys appear on the Access Keys page tagged Created by an agent, and you can delete them like any other.
The dashboard's own key
The dashboard's object browser uploads and downloads with a key of its own, which we look after for you:
| Name | STRG Dashboard |
| Buckets | All buckets |
| Permissions | Read objects, Write objects |
It does not appear on the Access Keys page, and the dashboard manages it for you. The name
STRG Dashboard is kept for this key, so none of your own keys can carry it.
Not available
These are not available as key permissions:
- Managing access keys through the S3 API - keys are created in the dashboard, through the MCP server or through the REST API
- Access logging
- Replication
- Event notifications
Sharing a single object works through a presigned URL, made with a key that has Read objects -
GetObject shows how.