# What is STRG? STRG is S3-compatible object storage for businesses, individuals and AI agents. You create buckets in a region, keep objects in them, and reach them however suits the moment: from the web dashboard, from any tool or SDK that speaks the S3 API, from an AI agent through the STRG MCP server - and, for managing access keys from scripts, through the STRG REST API. That makes it a good home for a nightly backup, the uploads of a web app, a static site's assets, or an agent keeping its memory in a bucket. Ease of use comes first: there is no infrastructure to configure and no request pricing to model, and agents are first-class users rather than an afterthought. ## Billing The idea is simple: you pay for the data you store, and nothing else. | | | | --- | --- | | Stored data | Billed | | API requests | No charge | | Ingress (uploads) | No charge | | Egress (downloads) | No charge | Every stored object version counts as stored data. Buckets are always versioned, so an object you delete stays billed until its older versions are removed - by you, or by a [lifecycle policy](https://docs.strg.com/lifecycle-policies). Objects under [Object Lock](https://docs.strg.com/object-locks) are billed until their lock expires. A card goes on the dashboard's *Billing* page before your first bucket or access key. In the dashboard's words: "A card is required to prevent abuse: a $1 hold checks it and is released at once, and nothing is charged until there is storage to bill." Stored data is invoiced and charged to your card. [Billing](https://docs.strg.com/billing) walks through invoices and cards. ## Ways to use STRG Each surface reaches the same buckets and keys, so you can mix them freely - create a bucket in the dashboard, fill it from a script, and let an agent read from it. | Surface | What it is | Start here | | --- | --- | --- | | Dashboard | The web interface at `https://app.strg.com`, for signing up, creating buckets, browsing and uploading objects, and managing bucket settings, access keys and billing, with the Ask our AI Assistant beside every page | [Getting started in the dashboard](https://docs.strg.com/getting-started-interactive) | | S3-compatible API | `https://s3..strg.com`, for the AWS CLI, the AWS SDKs and any other S3 client, signed with an access key | [S3 API](https://docs.strg.com/s3-api/overview) | | MCP server | `https://mcp.strg.com/mcp`, which lets an AI agent list and create buckets, run S3 operations on buckets and objects, create presigned URLs, and create, list and revoke access keys, and answers questions about STRG from its documentation | [Getting started with an AI agent](https://docs.strg.com/getting-started-mcp) | | REST API | `https://api.strg.com/v1/`, a JSON API for listing, looking up, creating and deleting access keys from scripts, CI and tools, authenticated with an access key that holds *Manage access keys through the API* | [REST API](https://docs.strg.com/rest-api/overview) | For help choosing between them, [Getting started](https://docs.strg.com/getting-started) compares the ways in. ## Features Here is what STRG offers today, each with the page that explains it in full. | Feature | What you get | | --- | --- | | [Buckets and regions](https://docs.strg.com/getting-started-interactive) | Bucket names are unique across STRG and 3-58 characters long. You pick a region per bucket; a bucket's name and region stay as they were set when it was created. Every bucket is encrypted at rest with AES-256, and its page in the dashboard shows its S3 endpoint | | [Bucket Protection](https://docs.strg.com/getting-started-interactive) | Every bucket is *Protected* (private) unless you turn protection off, which keeps it reachable only with your access keys. With protection off - handy for a public website or shared downloads - anyone can read, but not list, its objects without credentials at `https://.s3..strg.com/` - `https://s3..strg.com//` for a bucket name with a dot - and the dashboard offers *Copy public URL* for each object. An object whose own `Cache-Control` allows a shared cache is cached for that long, at most 5 minutes - so an overwrite, a delete, turning protection back on or a CORS change can take up to 5 minutes to reach anonymous readers | | [Objects and versioning](https://docs.strg.com/getting-started-interactive) | The dashboard lets you browse, upload, download and delete objects and folders. Buckets are always versioned, so nothing is lost by accident: a delete leaves a delete marker, and earlier versions can be listed, restored and undeleted | | [Access keys](https://docs.strg.com/access-keys) | S3 access keys scoped to all buckets or to specific ones, optionally to a key prefix, with the permissions you choose. A key can also be enabled for the MCP server, or for managing access keys through the [REST API](https://docs.strg.com/rest-api/overview) | | [CORS rules](https://docs.strg.com/cors-rules) | Per-bucket CORS configuration in S3's own JSON format, so an existing AWS configuration pastes straight in. The rules apply to browser requests to the bucket on the S3 endpoints - which is what a web app uploading straight from the browser needs | | [Lifecycle policies](https://docs.strg.com/lifecycle-policies) | Rules per prefix that, after a number of days, expire current versions, permanently delete previous versions and abort incomplete multipart uploads - a tidy way to keep old backups and their cost in check | | [Object Lock](https://docs.strg.com/object-locks) | Write-once-read-many retention in governance or compliance mode, with a default retention per bucket and legal holds per object. Enabling it on a bucket is permanent | | [Ask our AI Assistant](https://docs.strg.com/assistant) | A chat panel beside every dashboard page that does storage work for you, reads the page you are on and fills in its forms for you to review and submit. It asks you to confirm anything that cannot be undone | | [Two-factor authentication and account settings](https://docs.strg.com/account-settings) | *Account settings*, opened from the avatar menu, is where you can change your email address, turn on two-factor authentication with an authenticator app, or close your account | | [S3 API](https://docs.strg.com/s3-api/overview) | The common S3 operations for buckets, objects, multipart uploads, versions, CORS, lifecycle, default encryption and Object Lock. The page lists every supported operation and how each differs from AWS S3 | ## Regions A bucket lives in the region you create it in. These are the regions available today: | Region | Name | S3 endpoint | | --- | --- | --- | | `us-east-1` | US East | `https://s3.us-east-1.strg.com` | | `eu-central-1` | EU Central | `https://s3.eu-central-1.strg.com` | Each regional endpoint serves that region's buckets, so a client is configured with the endpoint and region of the bucket it talks to. [S3 API](https://docs.strg.com/s3-api/overview) covers the addressing styles and the differences from AWS S3. --- # Getting started There are four ways to work with STRG, and they all lead to the same place: one account, one set of buckets and one set of access keys. That means there is no wrong place to begin. Most people start with whichever feels most familiar and add the others when they need them - a bucket created in the dashboard is right there for an agent or an S3 tool a minute later. Whichever way you start, your account needs a card before its first bucket or access key. It goes on [*Billing*](https://docs.strg.com/billing) in the dashboard, and a $1 hold checks it and is released at once - nothing is charged until there is storage to bill. ## Which should I pick Each row is a common starting point and the way in that suits it best. | You want to | Start with | | --- | --- | | Create buckets, upload and browse files, and manage settings by clicking | [The dashboard](https://docs.strg.com/getting-started#the-dashboard) | | Let an AI agent create buckets, read and write objects, and create keys for you | [The MCP server](https://docs.strg.com/getting-started#the-mcp-server) | | Point existing S3 tools, SDKs or applications at STRG | [The S3-compatible API](https://docs.strg.com/getting-started#the-s3-compatible-api), after creating a key in the dashboard | | Create, list and delete access keys from scripts, CI or your own tools | [The REST API](https://docs.strg.com/getting-started#the-rest-api), after creating a key in the dashboard | ## The dashboard The dashboard is a web application at `https://app.strg.com`, and it is where everything can be seen and changed by clicking: buckets, objects, access keys and bucket settings such as CORS rules, lifecycle policies and Object Lock. It is also the natural first stop for setting up an account, because the card and the first access key are a few clicks away. | | | | --- | --- | | Suits | Anyone setting up an account, and anyone who prefers a browser to a command line | | You need | An email address or a GitHub account. Signing in and signing up are the same screen: a new address or GitHub identity gets an account on its first sign-in. There is no password - we email you a six-digit code. A card, added on *Billing*, before your first bucket or access key | | Next | [Getting started with the dashboard](https://docs.strg.com/getting-started-interactive) walks through it | ## The MCP server The MCP server, at `https://mcp.strg.com/mcp`, gives an AI agent its own tools for your storage, so it can do the work for you without any API integration. Through it an agent can list and create buckets, run S3 operations, create presigned URLs, create, list and revoke access keys, and search this documentation - handy for an agent keeping its memory in a bucket, or for asking your assistant to set up storage for a new project. | | | | --- | --- | | Suits | AI agents and the people who run them | | You need | An MCP client that supports remote servers over HTTP. The client either opens a browser where you sign in - or sign up - and choose what the agent may do, or sends an existing access key that holds the *Use the MCP server* permission. Connecting through the browser creates an access key, so an account without a card is asked to add one first - that is something only you can do, not the agent | | Next | [Getting started with MCP](https://docs.strg.com/getting-started-mcp). With an account already, **Connect your own agent** in the dashboard's top bar shows the setup for your client, ready to copy | ## The S3-compatible API Each region has an S3-compatible endpoint, `https://s3..strg.com`, so the AWS CLI, the AWS SDKs and other S3 tools work with STRG as they are - an existing application or a nightly backup only needs a new endpoint and a key. | | | | --- | --- | | Suits | Applications, scripts, backups and any tool that already speaks S3 | | You need | An access key and the region of your bucket. The regions are `us-east-1` (US East) and `eu-central-1` (EU Central) | | Next | The [S3 API overview](https://docs.strg.com/s3-api/overview) covers endpoints, supported operations and differences from Amazon S3 | The S3 API has no getting-started guide of its own, because most S3 users begin in the dashboard anyway: that is where a bucket and an access key are created. [Getting started with the dashboard](https://docs.strg.com/getting-started-interactive) ends with exactly that step, configuring the AWS CLI, rclone and an SDK, and [Access keys](https://docs.strg.com/access-keys) has every permission a key can hold. ## The REST API The REST API is a JSON API at `https://api.strg.com/v1/` for managing access keys: listing them, looking one up, creating one and deleting one. It is there so that keys can be handled by code - a CI job that creates a narrowly scoped key, uses it and deletes it afterwards, for example. It manages access keys only; buckets and objects are the S3 API's. | | | | --- | --- | | Suits | Scripts, CI pipelines and tools that create a narrowly scoped key for a job and delete it afterwards, or clean up old keys | | You need | An access key that holds the *Manage access keys through the API* permission, created on the *Access Keys* page in the dashboard, sent as `Authorization: Bearer :`. A key it creates can never have more access than that key has. Creating a key needs a card on file, as in the dashboard | | Next | The [REST API overview](https://docs.strg.com/rest-api/overview) covers authentication, errors, paging and the operations | --- # Getting started with the dashboard Welcome to STRG. This guide walks with you through your first ten minutes, from signing up to reading and writing objects from your own tools. First, you'll sign in; then a card goes on the account, you create a bucket to hold your objects and an access key for your tools to sign their requests with, and finally an S3 tool you already know talks to your new bucket. All it takes is a browser, an email address or a GitHub account, and a payment card. Each step leaves you with something you need for the next one: | Step | What you end up with | | --- | --- | | [1. Signing in](https://docs.strg.com/getting-started-interactive#1-signing-in-or-creating-an-account) | A STRG account | | [2. Adding a card](https://docs.strg.com/getting-started-interactive#2-adding-a-card) | A verified card, which creating buckets and access keys requires | | [3. Creating a bucket](https://docs.strg.com/getting-started-interactive#3-creating-a-bucket) | A bucket in the region of your choice | | [4. Creating an access key](https://docs.strg.com/getting-started-interactive#4-creating-an-access-key) | An access key ID and secret access key | | [5. Using the key](https://docs.strg.com/getting-started-interactive#5-using-the-key-from-your-tools) | The AWS CLI, rclone or an SDK talking to your bucket | ## 1. Signing in or creating an account Everything starts at [`https://app.strg.com`](https://app.strg.com). One screen serves both signing up and signing in, so there is no separate registration to go through, and no password to remember either. (image: The sign-in screen, titled "Sign in or create an account", with a "Sign in with GitHub" button and an "Email address" field above a "Continue" button) There are two ways in: - **By email**: you enter your address and select **Continue**, and we email you a six-digit code. Entering it and selecting **Sign in** signs you in. An address without an account gets one with its first verified code. - **With GitHub**: **Sign in with GitHub** takes you to GitHub to approve the request. A GitHub account without a STRG account gets one on its first sign-in, as long as it has a verified email address. (image: The code step: "Enter the code we sent to you@example.com", a six-digit code field and a "Sign in" button) **Note:** Each email address belongs to one STRG account, so **Sign in with GitHub** does not create a second account for an address that already has one. For an address that already has an account, the emailed code is the way in. If you later turn on two-factor authentication, signing in also asks for the six-digit code from your authenticator app, whichever way you sign in. [Account settings](https://docs.strg.com/account-settings) has the details. Once you are signed in, the sidebar holds **Dashboard**, **Access Keys**, **Billing**, a **Documentation** link that opens this documentation in a new tab, and your buckets. **Create new Bucket** sits at the top of the bucket list, with a refresh button beside it that lists your buckets again, and **View all** sits beside its *Buckets* heading. Each bucket shows its region, and a public one is marked *Public*. A name too long for the sidebar is shortened in the middle, and hovering over it shows it whole. Beside the STRG mark in the top bar, **Ask our AI** opens the [assistant](https://docs.strg.com/assistant) over the page you are on - and so does ⌘J on a Mac, or Ctrl+J elsewhere, which closes it again too. Next to it, **Connect your own agent** shows how to connect an AI coding agent to STRG, as [Getting started with MCP](https://docs.strg.com/getting-started-mcp) describes. The menu behind your initial, at the right of the top bar, leads to **Account settings** and **Sign out**. The **Dashboard** page gives you an overview at a glance: what you store now, the estimate for the current billing period, what you stored on average last period, your buckets and your active access keys, beside a *Did you know?* tip that changes every minute. An *S3 endpoints* card lists every region's endpoint with a button that copies it, and a link to this documentation. Below it, *What are you building today?* offers ideas - agent memory, backups, user uploads and more - and each one opens the [Ask our AI Assistant](https://docs.strg.com/assistant) in a new chat to walk you through it. **Something else?** takes your own description instead. (image: The dashboard: the top bar with the "Ask our AI" button, showing its keyboard shortcut, and the "Connect your own agent" button beside the STRG mark; the sidebar listing Dashboard, Access Keys, Billing, Documentation and a Buckets section with a "View all" link, "Create new Bucket" with a refresh button and a search field above the bucket list; and the Dashboard page with a greeting, a "Create a bucket" button, and the Stored now, This period, Last period, Buckets, Active access keys and Did you know? tiles above an S3 endpoints card with a copy button per region) ## 2. Adding a card The next step is a card. Your account needs a verified card before its first bucket or access key, which is how we keep STRG free of abuse: a $1 hold checks the card and is released at once, and nothing is charged until there is storage to bill. The card goes on **Billing**, in the sidebar, where **Add card** opens the *Add a card* dialog. (image: The Billing page: the explanation of why a card is required, the Cards list with an "Add card" button above a saved card, and the Billing details form below it) The dialog asks for the card number, expiration date and security code. On a new account, it also asks for your billing details, which appear on your invoices: | Field | What it holds | | --- | --- | | **Country** | Required: the country of your billing address | | **Address line 1**, **Address line 2**, **City**, **Postal code**, **State / region** | Optional | | **Company name** | Optional | | Your country's tax ID, such as **European VAT number** for an EU country | Optional. The field is named after the selected country's tax ID, and does not appear for a country without one | Selecting **Add card** saves your billing details first and checks the card after them. If a tax ID cannot be accepted, the reason appears under the field before anything happens to the card, so the number can be corrected - or the field left empty - and **Add card** selected again. Once your account has billing details, the dialog asks for the card alone, and the card takes your saved billing address. Billing details, tax ID included, can be changed at any time in the **Billing details** form below the cards, with **Save billing details**. (image: The top of the "Add a card" dialog: the note about the $1 hold, then the card number, expiration date and security code fields) The card is checked within seconds and then appears under **Cards**. If your bank wants you to confirm the payment, that happens right in the page, while the dialog says *Waiting for your bank's confirmation…*. Until you have a verified card, the *Create a bucket* page and the **Access Keys** page show *Add a card before creating a bucket.* (or *an access key*) where their forms would be, with an **Add a card** button that opens the same *Add a card* dialog on that page. Once the card is verified, the form appears in its place. [Billing](https://docs.strg.com/billing) covers cards, billing details and invoices. ## 3. Creating a bucket A bucket is where your objects live, and it is the next thing to make. **Create new Bucket** in the sidebar opens the form, and so does **Create a bucket** at the top of the dashboard - which reads **Create your first bucket** while you have none. (image: The "Create a bucket" form with an empty Name, the Region picker and the Protection choice set to Protected) The form has three fields: | Field | What it holds | | --- | --- | | **Name** | 3 to 58 characters: lowercase letters, digits, hyphens and dots, starting and ending with a letter or digit. No two adjacent dots, and not formatted like an IP address. Names are **unique across all of STRG**, exactly as on S3, so a name someone else already uses is not available | | **Region** | Where the bucket's objects are stored: **US East** (`us-east-1`) or **EU Central** (`eu-central-1`) | | **Protection** | **Protected** by default: the bucket is private and your access keys are the way to its objects. With **Public**, anyone with an object's URL can download it without credentials, at `https://.s3..strg.com/` - or `https://s3..strg.com//` for a name containing a dot. Listing, uploading, changing and deleting still need an access key | **Warning:** A bucket's name and region stay as they were set when it was created. Moving to another region means a new bucket there, with the objects copied across. Protection is different: it can be changed at any time on the bucket's *Settings* tab, under *Bucket Protection*. Bucket names can be up to **58 characters** long, a little shorter than S3's 63. A name without dots is the easy choice: a bucket whose name contains a dot is reached with path-style requests, and the form reminds you of that as soon as you type one. [Step 5](https://docs.strg.com/getting-started-interactive#5-using-the-key-from-your-tools) shows the setting for each tool. (image: The form filled in with the name my-first-bucket, the region EU Central and Protection set to Protected) **Create bucket** creates it. Your first bucket in a region takes a little longer while storage is set up there, and the page says so below the button. When it is done, the page confirms that the bucket is ready and the bucket appears in the sidebar. If it takes longer still, the page says *my-first-bucket is still being set up and will appear in your buckets shortly.* That is not an error - the bucket is still being created, and selecting **Create bucket** again with the same name and region picks up that same creation rather than starting another. **View all**, beside the sidebar's *Buckets* heading, opens a table of every bucket you have, in every region. It can be searched by name and sorted by any column: | Column | Shows | | --- | --- | | **Name** | The bucket's name, which opens its page | | **Created** | The date the bucket was created | | **Region** | The bucket's region | | **Protection** | *Protected* or *Public* | | **Size** | The data stored, from the daily storage report, and how long ago it was reported - so it trails what is stored now. A new bucket shows *Not reported yet* until its first report | | **Object Lock** | *Off* or *On*, and the default retention if one is set | A value that is not known yet shows as `-`. The page also has a **Create Bucket** button, and a refresh button that reloads the list and the sizes. Selecting the bucket in the sidebar opens its page. A card at the top shows when the bucket was created, its region, its protection, its size and the **S3 endpoint** of its region - such as `https://s3.eu-central-1.strg.com` - with a button that copies it. A public bucket's card adds an **HTTPS endpoint**, the address its objects can be fetched from in a browser, such as `https://my-first-bucket.s3.eu-central-1.strg.com`, or the path-style address for a bucket whose name contains a dot, such as `https://s3.eu-central-1.strg.com/my.bucket`. Below it, the object browser is on the *Objects* tab, and Bucket Protection, lifecycle rules, CORS rules, Object Lock, *Delete bucket* and the access keys that can reach the bucket are on the *Settings* tab. In a wide enough window, the card and the settings sit in a column beside the object browser instead. Every bucket is encrypted at rest with AES-256. In a public bucket, selecting an object offers **Copy public URL**, which copies the address anyone can download the object from without credentials. It always serves the object's latest version. **Danger:** Deleting a bucket cannot be undone. A bucket can be deleted once it is empty - no object versions and no delete markers left - and the deletion is confirmed by typing its name. Access keys limited to the bucket stop reaching it, even if a bucket with the same name is created again, and once it is deleted anyone can take the name. (image: The page of my-first-bucket: the card with Created, Region, Protection, Size and S3 endpoint with a copy button, above the Objects and Settings tabs and the object browser listing four folders) ## 4. Creating an access key An access key is what an S3 tool signs its requests with: an ID that says which key it is, and a secret that proves the request came from you. Keys live on the **Access Keys** page in the sidebar, where **Create access key** opens the form. (image: The Access Keys page: a "Create access key" button above the list of keys, each with its buckets, permissions and a Status row) The form decides what the key can reach and what it may do: | Field | What it holds | | --- | --- | | **Name** | For you: what uses this key, at most 64 characters | | **Buckets** | **All buckets**, or **Only some buckets** with the ones this key may reach ticked. A key reaches the buckets that exist when it is created, so a bucket created later needs a new key | | **Only objects whose name starts with…** | Optional. Limits the key to object names starting with this prefix, such as `reports/` | | **Template** | Fills in the permissions for you: **Full Access** (selected by default), **Write Access**, **Read-only Access** or **Custom**. For this guide, **Write Access** is enough to list, download and upload objects, and **Read-only Access** leaves out uploading. Every template except Custom includes *Use the MCP server*, which lets the key sign in to the [MCP server](https://docs.strg.com/getting-started-mcp). **Full Access** also adds *Manage access keys through MCP* and *Manage access keys through the API*, the second for the [REST API](https://docs.strg.com/rest-api/overview) | | **Permissions** | Ticked by the template. *List buckets* and *Read bucket settings* are always included. Ticking or unticking any permission switches the template to **Custom** | Each permission has a **(?)** button explaining what it allows. A permission that needs another one to be useful stays disabled until that one is ticked. [Access keys](https://docs.strg.com/access-keys) describes every permission. A key with the *Manage Object Lock* permission - which the **Full Access** template includes - can turn on Object Lock for a bucket, and that can never be undone. The key is created straight away; the bucket's own Object Lock settings ask for a confirmation before anything is switched on. [Object Lock](https://docs.strg.com/object-locks) explains what that means. (image: The "Create an access key" dialog: the name backup-script, All buckets selected, the Template choices with Full Access selected, the Permissions list, and the Cancel and Create access key buttons) **Create access key** creates it, and the dialog then shows the **Access key ID** and the **Secret access key**, each with a copy button. (image: The "Save your secret access key" dialog, warning that this is the only time the secret is shown, with the Access key ID and Secret access key fields) **Warning:** **The secret access key is shown only once.** This is the moment to put it in a password manager or your tool's configuration, before selecting **Done**: nobody can show it again afterwards. 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 or permissions simply means a new key, and the old one can then be deleted. Deleting a key takes effect everywhere and cannot be undone. The key starts working in each region within a few minutes. Its **Status** row shows *Setting up in …* until then and *Ready in …* once it works there, and the page updates by itself. A key starts working in a region once you have a bucket there - or once it has created the first one there through the API ([Step 5](https://docs.strg.com/getting-started-interactive#5-using-the-key-from-your-tools)). (image: An access key in the list, showing All buckets, its permissions, and "Ready in EU Central" and "Ready in US East") ## 5. Using the key from your tools Now for the part where your own tools come in. STRG speaks the S3 API, so any S3 tool works once it knows the endpoint of **the region your bucket is in**, and that region's name: | Region | Endpoint | | --- | --- | | `us-east-1` (US East) | `https://s3.us-east-1.strg.com` | | `eu-central-1` (EU Central) | `https://s3.eu-central-1.strg.com` | Buckets are also reachable virtual-hosted style, at `https://.s3..strg.com`. The examples below use `eu-central-1` and `my-first-bucket`, which your own region and bucket replace. **Warning:** Each endpoint serves the buckets in its own region. A request for a bucket in another region answers `NoSuchBucket`, even though the dashboard shows the bucket. S3 would redirect to the right region; STRG answers straight away, so the AWS SDKs do not retry. If your account has no bucket in the endpoint's region at all, a request for a bucket answers `NoSuchBucket` as well and [`ListBuckets`](https://docs.strg.com/s3-api/ListBuckets) an empty list, while [`CreateBucket`](https://docs.strg.com/s3-api/CreateBucket) creates your first bucket there. That sets storage up in the region first, so it takes longer and may answer `503 SlowDown`, which the SDKs retry. A key still *Setting up in …* a region where you do have a bucket answers `InvalidAccessKeyId` to every request but `CreateBucket` until it is *Ready in …* there ([Step 4](https://docs.strg.com/getting-started-interactive#4-creating-an-access-key)). The region shown on the bucket's page settles which endpoint to use, and the **S3 endpoint** there, like the dashboard's *S3 endpoints* card, is that region's endpoint from the table above - the tool adds the bucket name itself. The secret stays out of your code: every example reads the key from the environment or from the tool's own credential store. ```sh export AWS_ACCESS_KEY_ID="your access key ID" export AWS_SECRET_ACCESS_KEY="your secret access key" ``` **AWS CLI** A profile of its own keeps the key apart from any other credentials. `aws configure` asks for the access key ID and the secret access key; `eu-central-1` goes in as the default region, and the output format can stay as it is. ```sh aws configure --profile strg ``` Every command then carries the endpoint: ```sh aws s3 ls --profile strg --endpoint-url https://s3.eu-central-1.strg.com aws s3 cp ./hello.txt s3://my-first-bucket/hello.txt --profile strg --endpoint-url https://s3.eu-central-1.strg.com aws s3 ls s3://my-first-bucket/ --profile strg --endpoint-url https://s3.eu-central-1.strg.com aws s3 cp s3://my-first-bucket/hello.txt ./hello-copy.txt --profile strg --endpoint-url https://s3.eu-central-1.strg.com ``` For a bucket whose name contains a dot, the profile switches to path-style requests with: ```sh aws configure set s3.addressing_style path --profile strg ``` **rclone** rclone reaches STRG through a remote in its configuration file (`rclone config file` prints its location). This one reads the key from `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`: ```ini title="rclone.conf" [strg] type = s3 provider = Other env_auth = true region = eu-central-1 endpoint = https://s3.eu-central-1.strg.com force_path_style = true no_check_bucket = true ``` `no_check_bucket = true` stops rclone from trying to create the bucket before it uploads, since the bucket already exists in the dashboard. ```sh rclone lsd strg: rclone copy ./hello.txt strg:my-first-bucket/ rclone ls strg:my-first-bucket ``` **Python (boto3)** ```python title="example.py" import boto3 s3 = boto3.client( "s3", endpoint_url="https://s3.eu-central-1.strg.com", region_name="eu-central-1", ) s3.put_object(Bucket="my-first-bucket", Key="hello.txt", Body=b"Hello, STRG!") for obj in s3.list_objects_v2(Bucket="my-first-bucket").get("Contents", []): print(obj["Key"], obj["Size"]) print(s3.get_object(Bucket="my-first-bucket", Key="hello.txt")["Body"].read().decode()) ``` For a bucket whose name contains a dot, the client takes `config=botocore.config.Config(s3={"addressing_style": "path"})` as well (with `import botocore.config`). **JavaScript (AWS SDK v3)** ```js title="example.mjs" import { S3Client, PutObjectCommand, ListObjectsV2Command, GetObjectCommand, } from "@aws-sdk/client-s3"; const s3 = new S3Client({ endpoint: "https://s3.eu-central-1.strg.com", region: "eu-central-1", }); await s3.send( new PutObjectCommand({ Bucket: "my-first-bucket", Key: "hello.txt", Body: "Hello, STRG!" }), ); const listing = await s3.send(new ListObjectsV2Command({ Bucket: "my-first-bucket" })); for (const object of listing.Contents ?? []) console.log(object.Key, object.Size); const object = await s3.send(new GetObjectCommand({ Bucket: "my-first-bucket", Key: "hello.txt" })); console.log(await object.Body.transformToString()); ``` It runs with `node example.mjs`, once `npm install @aws-sdk/client-s3` has added the SDK. For a bucket whose name contains a dot, the client takes `forcePathStyle: true` as well. A single `PutObject` takes an object of up to 5 GiB. The AWS CLI, rclone and the SDKs' upload helpers switch to multipart uploads for large files by themselves; with a plain `PutObject`, anything larger goes up in parts. [The S3 API](https://docs.strg.com/s3-api/overview) lists every supported operation and how each differs from S3. ## Next steps That's it - your tools and your bucket are talking. Where to go next depends on what you are building: | You want to | Page | | --- | --- | | Choose exactly what a key may do, or limit it to some buckets or a prefix | [Access keys](https://docs.strg.com/access-keys) | | Let a web application in the browser use a bucket directly | [CORS rules](https://docs.strg.com/cors-rules) | | Expire old objects and versions automatically | [Lifecycle policies](https://docs.strg.com/lifecycle-policies) | | Make objects impossible to delete for a period | [Object Lock](https://docs.strg.com/object-locks) | | Look up an S3 operation | [The S3 API](https://docs.strg.com/s3-api/overview), e.g. [`PutObject`](https://docs.strg.com/s3-api/PutObject), [`GetObject`](https://docs.strg.com/s3-api/GetObject), [`ListObjectsV2`](https://docs.strg.com/s3-api/ListObjectsV2) | | Create and delete access keys from your own code | [The REST API](https://docs.strg.com/rest-api/overview) | | Connect an AI agent instead | [Getting started with MCP](https://docs.strg.com/getting-started-mcp) | --- # Connecting an AI agent over MCP Connecting an AI agent to STRG lets it create buckets, read and write objects and manage access keys for you, asked in plain words - and if you have no account yet, connecting signs you up. The server is at `https://mcp.strg.com/mcp`, and the easiest start is **Connect your own agent** in the dashboard's top bar, which shows the setup for your client ready to copy. ## Setting up your client Each client has its own place for MCP servers. The configuration needs only the server URL, and the client opens a browser sign-in when it first connects: **Claude Code** ```bash claude mcp add --transport http strg https://mcp.strg.com/mcp ``` With `--scope project`, it goes into `.mcp.json` in your project instead, ready to share with your team: ```json title=".mcp.json" { "mcpServers": { "strg": { "type": "http", "url": "https://mcp.strg.com/mcp" } } } ``` The sign-in then runs from `/mcp` in Claude Code, or from your shell with `claude mcp login strg`. **Claude Desktop and claude.ai** The connector is a custom one: in **Customize** → **Connectors**, **Add custom connector** takes the server URL, `https://mcp.strg.com/mcp`. Claude asks you to sign in when you connect. On a Team or Enterprise plan, an owner of your organization adds the connector, and each member then connects it from **Customize** → **Connectors**. **Codex** ```toml title="~/.codex/config.toml" [mcp_servers.strg] url = "https://mcp.strg.com/mcp" ``` The sign-in then runs with: ```bash codex mcp login strg ``` **Antigravity** The configuration is in the agent panel's **…** menu, under **MCP Servers**, **Manage MCP Servers** and **View raw config** - or in `~/.gemini/config/mcp_config.json` (all workspaces) or `.agents/mcp_config.json` (one workspace). Antigravity takes `serverUrl`, not `url`: ```json title="mcp_config.json" { "mcpServers": { "strg": { "serverUrl": "https://mcp.strg.com/mcp" } } } ``` Antigravity handles the sign-in itself. **Authenticate** beside strg, on the **Customizations** tab of Agent settings (Cmd + , on macOS, Ctrl + , on Windows and Linux), opens it in your browser. The authorization code the sign-in ends with then goes into the settings panel with **Submit**, and strg reconnects on its own. **Cursor** The **Add to Cursor** button in the dashboard's **Connect your agent** dialog installs it in one click. It can also go into `~/.cursor/mcp.json` for every project, or `.cursor/mcp.json` for one project: ```json title="mcp.json" { "mcpServers": { "strg": { "url": "https://mcp.strg.com/mcp" } } } ``` **Devin Desktop (Windsurf)** The Cascade panel's **…** menu has **Open MCP config file**, which opens `~/.config/devin/mcp_config.json` - `%APPDATA%\devin\mcp_config.json` on Windows: ```json title="mcp_config.json" { "mcpServers": { "strg": { "serverUrl": "https://mcp.strg.com/mcp" } } } ``` **Zed** The server goes into `context_servers` in Zed's settings - or through **Settings** → **AI** → **MCP Servers**, **Add Server** and **Add Remote Server**: ```json title="settings.json" { "context_servers": { "strg": { "url": "https://mcp.strg.com/mcp" } } } ``` **Rulesync** ```jsonc title=".rulesync/mcp.jsonc" { "mcpServers": { "strg": { "type": "http", "url": "https://mcp.strg.com/mcp" } } } ``` This command then generates each tool's own configuration, and the sign-in runs from the tool itself: ```bash rulesync generate --features mcp ``` **Other clients** Most clients accept this for a remote HTTP server: ```json { "mcpServers": { "strg": { "type": "http", "url": "https://mcp.strg.com/mcp" } } } ``` A client that works with local (stdio) servers only, or with remote servers but without OAuth, can reach STRG through the `mcp-remote` bridge, which runs the sign-in in your browser: ```json { "mcpServers": { "strg": { "command": "npx", "args": ["mcp-remote", "https://mcp.strg.com/mcp"] } } } ``` ## What happens when you connect A browser window signs you in to STRG - or signs you up, with an email code or GitHub. You then choose the access key the agent will act as: its buckets, an optional key prefix and its permissions, on the same form as the *Access Keys* page ([Access keys](https://docs.strg.com/access-keys)). Granting *Manage Object Lock* asks you to confirm once more, since an Object Lock can never be undone. **Connect** creates the key and takes you back to your client. The key appears on the *Access Keys* page like any other, and deleting it there disconnects the agent. ### Connecting with an access key instead A client can also skip the sign-in and send an access key holding *Use the MCP server* as a header: ```text Authorization: Bearer : ``` The dashboard's **Connect your agent** dialog makes this easy: under **Static credentials** it creates such a key and shows each client's setup with the key written in. The secret is shown only that once. ## Example prompts Once connected, an agent takes requests in plain words, such as: - Create a private bucket called `my-bucket` in `eu-central-1`. - List my buckets and the endpoint for each. - Create an access key that can only read and list objects in `my-bucket`, and show me how to use it with the AWS CLI. - Create an access key that can read and write objects under `photos/` in `my-bucket` only. - Revoke the access key labelled `ci-uploader`. - Upload this file to `my-bucket` as `notes/todo.md`. - Give me a download link for `photos/2024/cat.jpg` in `my-bucket` that is valid for one day. - Set up CORS on `my-bucket` so that my web app at `https://example.com` can upload from the browser. - Add a lifecycle rule to `my-bucket` that deletes old versions after 30 days. ## What an agent can do An agent acts as **one access key**, and can do exactly what that key permits - its permissions, its buckets and its key prefix - so its reach is always the one you gave it when connecting. A key the agent creates never exceeds its own. Billing and account settings stay with you, in the dashboard. If the key has *Act without confirmation*, the agent also receives its secret access key, so that it can configure its own S3 tools for bulk transfers. ## What you are asked to confirm Unless the key has *Act without confirmation*, your MCP client asks you before the agent does anything that cannot be undone - in broad terms, deleting object versions or buckets, locking objects, changing lifecycle rules, making a bucket public, and creating or revoking access keys. The question says what is affected, in plain words, and nothing happens until you accept. Everything else - reads, uploads, ordinary deletes - simply runs, since versioning keeps an earlier version to go back to. A client that cannot ask is turned away rather than let through, so a question is never skipped. ## A card first Connecting creates an access key, so an account without a verified card is asked to add one on the connect page first. Until then, the tools that create a bucket or an access key answer that a card is needed and that only you can add one - [Billing](https://docs.strg.com/billing) covers it. ## Next steps - [Access keys](https://docs.strg.com/access-keys) - every permission a key can carry. - [Object Lock](https://docs.strg.com/object-locks) - worth reading before granting an agent *Manage Object Lock*. - [The S3 API](https://docs.strg.com/s3-api/overview) - the operations available and how STRG differs from Amazon S3. - [Billing](https://docs.strg.com/billing) - your card and your invoices. --- # Ask our AI Assistant The dashboard comes with the *Ask our AI Assistant*: a chat window that opens over every page, so help is always one click away. You can ask it about your buckets, objects and access keys in plain words, and it takes care of the steps for you. It also sees the page you are on - "this bucket" means the one in front of you - and can fill in the page's forms for you to review and submit. Anything that cannot be undone waits for you to confirm it first, so you stay in charge. ## Opening the assistant **Ask our AI**, in the top bar beside the STRG mark, opens the window right over the page you are on, so you never lose your place. ⌘J on a Mac, or Ctrl+J elsewhere, does the same from anywhere on the page, even while you are typing in a field. Selecting the button or pressing the keys again closes the window. (image: The assistant's window open over a bucket's page, answering that one bucket is public, naming its region, and that the rest are private) ## Example prompts A few questions to start with, with your own bucket names in place of the examples: - Which of my buckets are public, and in which region? - What is in this bucket? *(On a bucket's page.)* - Add a lifecycle rule to `my-bucket` that deletes old versions after 30 days. - Prepare a read-only access key that can only reach `my-bucket`. *(It fills in the form on the Access Keys page; creating the key is yours.)* For an agent of your own, in your editor or terminal, [Getting started with MCP](https://docs.strg.com/getting-started-mcp) shows how to connect it to STRG. --- # 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](https://docs.strg.com/rest-api/overview) 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](https://docs.strg.com/access-keys#scope) has the details | | Object prefix | Optional - [Object prefix](https://docs.strg.com/access-keys#object-prefix) explains it | | Permissions | What the key may do - [Permissions](https://docs.strg.com/access-keys#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](https://docs.strg.com/rest-api/create-access-key) work the same way. [Billing](https://docs.strg.com/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`](https://docs.strg.com/s3-api/ListBuckets) lists nothing, and [`CreateBucket`](https://docs.strg.com/s3-api/CreateBucket) creates your first bucket there - the [Buckets](https://docs.strg.com/access-keys#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`](https://docs.strg.com/s3-api/CreateBucket), which works. The endpoints are listed in [the S3 API overview](https://docs.strg.com/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. **Warning: A re-created bucket needs 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`](https://docs.strg.com/s3-api/ListObjectsV2), [`ListObjects`](https://docs.strg.com/s3-api/ListObjects), [`ListObjectVersions`](https://docs.strg.com/s3-api/ListObjectVersions), [`ListMultipartUploads`](https://docs.strg.com/s3-api/ListMultipartUploads) | The request must set `prefix` to the key's prefix or a longer one. A listing without it is answered `403 AccessDenied` | | [`CopyObject`](https://docs.strg.com/s3-api/CopyObject), [`UploadPartCopy`](https://docs.strg.com/s3-api/UploadPartCopy) | The source (`x-amz-copy-source`) must be in the key's buckets and start with the prefix too | | [`DeleteObjects`](https://docs.strg.com/s3-api/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** ```bash aws s3api list-objects-v2 \ --bucket my-bucket \ --prefix reports/ \ --endpoint-url https://s3.eu-central-1.strg.com \ --region eu-central-1 ``` **Python (boto3)** ```python 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"]) ``` **JavaScript (AWS SDK v3)** ```javascript 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](https://docs.strg.com/access-keys#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](https://docs.strg.com/access-keys#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](https://docs.strg.com/access-keys#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`](https://docs.strg.com/s3-api/ListBuckets), [`HeadBucket`](https://docs.strg.com/s3-api/HeadBucket) | | `buckets:read-config` | Read bucket settings | Read a bucket's location, versioning, ACL and CORS settings | [`GetBucketLocation`](https://docs.strg.com/s3-api/GetBucketLocation), [`GetBucketVersioning`](https://docs.strg.com/s3-api/GetBucketVersioning), [`GetBucketAcl`](https://docs.strg.com/s3-api/GetBucketAcl), [`GetBucketCors`](https://docs.strg.com/s3-api/GetBucketCors), [`GetBucketPolicy`](https://docs.strg.com/s3-api/GetBucketPolicy), [`GetBucketTagging`](https://docs.strg.com/s3-api/GetBucketTagging), [`GetBucketOwnershipControls`](https://docs.strg.com/s3-api/GetBucketOwnershipControls), [`GetPublicAccessBlock`](https://docs.strg.com/s3-api/GetPublicAccessBlock), [`GetBucketAccelerateConfiguration`](https://docs.strg.com/s3-api/GetBucketAccelerateConfiguration), [`GetBucketRequestPayment`](https://docs.strg.com/s3-api/GetBucketRequestPayment), [`GetBucketNotificationConfiguration`](https://docs.strg.com/s3-api/GetBucketNotificationConfiguration), [`GetBucketNotification`](https://docs.strg.com/s3-api/GetBucketNotification) | With `buckets:list`, a key limited to some buckets lists its own buckets and no others; [Scope](https://docs.strg.com/access-keys#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`](https://docs.strg.com/s3-api/ListObjectsV2), [`ListObjects`](https://docs.strg.com/s3-api/ListObjects), [`ListObjectVersions`](https://docs.strg.com/s3-api/ListObjectVersions), [`ListMultipartUploads`](https://docs.strg.com/s3-api/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`](https://docs.strg.com/s3-api/GetObject), [`HeadObject`](https://docs.strg.com/s3-api/HeadObject), [`GetObjectAcl`](https://docs.strg.com/s3-api/GetObjectAcl), [`GetObjectTagging`](https://docs.strg.com/s3-api/GetObjectTagging); the source side of [`CopyObject`](https://docs.strg.com/s3-api/CopyObject) and [`UploadPartCopy`](https://docs.strg.com/s3-api/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`](https://docs.strg.com/s3-api/PutObject), [`CopyObject`](https://docs.strg.com/s3-api/CopyObject), [`CreateMultipartUpload`](https://docs.strg.com/s3-api/CreateMultipartUpload), [`UploadPart`](https://docs.strg.com/s3-api/UploadPart), [`UploadPartCopy`](https://docs.strg.com/s3-api/UploadPartCopy), [`CompleteMultipartUpload`](https://docs.strg.com/s3-api/CompleteMultipartUpload), [`AbortMultipartUpload`](https://docs.strg.com/s3-api/AbortMultipartUpload), [`ListParts`](https://docs.strg.com/s3-api/ListParts), [`DeleteObjectTagging`](https://docs.strg.com/s3-api/DeleteObjectTagging); [`DeleteObject`](https://docs.strg.com/s3-api/DeleteObject) and [`DeleteObjects`](https://docs.strg.com/s3-api/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`](https://docs.strg.com/s3-api/DeleteObject) and [`DeleteObjects`](https://docs.strg.com/s3-api/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](https://docs.strg.com/lifecycle-policies) 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](https://docs.strg.com/object-locks) 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`](https://docs.strg.com/s3-api/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`](https://docs.strg.com/s3-api/PutObjectRetention); the `x-amz-object-lock-mode` and `x-amz-object-lock-retain-until-date` headers on [`PutObject`](https://docs.strg.com/s3-api/PutObject), [`CopyObject`](https://docs.strg.com/s3-api/CopyObject), [`CreateMultipartUpload`](https://docs.strg.com/s3-api/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`](https://docs.strg.com/s3-api/DeleteObject), [`DeleteObjects`](https://docs.strg.com/s3-api/DeleteObjects), [`PutObjectRetention`](https://docs.strg.com/s3-api/PutObjectRetention) | | `object-legal-hold:read` | Read legal holds | Read whether an object is under legal hold | [`GetObjectLegalHold`](https://docs.strg.com/s3-api/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`](https://docs.strg.com/s3-api/PutObjectLegalHold); the `x-amz-object-lock-legal-hold` header on [`PutObject`](https://docs.strg.com/s3-api/PutObject), [`CopyObject`](https://docs.strg.com/s3-api/CopyObject), [`CreateMultipartUpload`](https://docs.strg.com/s3-api/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`](https://docs.strg.com/s3-api/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`](https://docs.strg.com/s3-api/CreateBucket), [`PutBucketAcl`](https://docs.strg.com/s3-api/PutBucketAcl), [`PutBucketCors`](https://docs.strg.com/s3-api/PutBucketCors), [`DeleteBucketCors`](https://docs.strg.com/s3-api/DeleteBucketCors), [`PutBucketVersioning`](https://docs.strg.com/s3-api/PutBucketVersioning), [`PutObjectAcl`](https://docs.strg.com/s3-api/PutObjectAcl), [`DeleteBucketTagging`](https://docs.strg.com/s3-api/DeleteBucketTagging) | | `buckets:delete` | Delete buckets | All buckets only | Delete any empty bucket in your account | [`DeleteBucket`](https://docs.strg.com/s3-api/DeleteBucket) | [`CreateBucket`](https://docs.strg.com/s3-api/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](https://docs.strg.com/access-keys#when-a-key-starts-working); until then, that region's other operations answer `403 InvalidAccessKeyId`. `ListBuckets` answers with the buckets in the endpoint's region - the [`ListBuckets`](https://docs.strg.com/s3-api/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`](https://docs.strg.com/s3-api/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`](https://docs.strg.com/s3-api/PutObjectLockConfiguration) | | `bucket-encryption:read` | Read encryption settings | Read a bucket's default server-side encryption | [`GetBucketEncryption`](https://docs.strg.com/s3-api/GetBucketEncryption) | | `bucket-encryption:write` | Manage encryption | Change a bucket's default server-side encryption | [`PutBucketEncryption`](https://docs.strg.com/s3-api/PutBucketEncryption). STRG answers `DeleteBucketEncryption` with `501 NotImplemented` | | `bucket-lifecycle:read` | Read lifecycle rules | Read a bucket's lifecycle rules | [`GetBucketLifecycleConfiguration`](https://docs.strg.com/s3-api/GetBucketLifecycleConfiguration), [`GetBucketLifecycle`](https://docs.strg.com/s3-api/GetBucketLifecycle) | | `bucket-lifecycle:write` | Manage lifecycle rules | Change or remove a bucket's lifecycle rules | [`PutBucketLifecycleConfiguration`](https://docs.strg.com/s3-api/PutBucketLifecycleConfiguration), [`PutBucketLifecycle`](https://docs.strg.com/s3-api/PutBucketLifecycle), [`DeleteBucketLifecycle`](https://docs.strg.com/s3-api/DeleteBucketLifecycle) | **Danger: Object Lock is permanent** 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](https://docs.strg.com/getting-started-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 :`. 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](https://docs.strg.com/access-keys#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](https://docs.strg.com/access-keys#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`](https://docs.strg.com/s3-api/DeleteObject), [`DeleteObjects`](https://docs.strg.com/s3-api/DeleteObjects)) | A `versionId` is given. Deleting by name only adds a delete marker, so it is not asked | | Setting retention ([`PutObjectRetention`](https://docs.strg.com/s3-api/PutObjectRetention)) | Always | | Placing or lifting a legal hold ([`PutObjectLegalHold`](https://docs.strg.com/s3-api/PutObjectLegalHold)) | Always | | Changing a bucket's Object Lock configuration ([`PutObjectLockConfiguration`](https://docs.strg.com/s3-api/PutObjectLockConfiguration)) | Always | | Replacing a bucket's lifecycle rules ([`PutBucketLifecycleConfiguration`](https://docs.strg.com/s3-api/PutBucketLifecycleConfiguration)) | Always | | Uploading or copying an object under Object Lock ([`PutObject`](https://docs.strg.com/s3-api/PutObject), [`CopyObject`](https://docs.strg.com/s3-api/CopyObject), [`CreateMultipartUpload`](https://docs.strg.com/s3-api/CreateMultipartUpload)) | A retention mode is set, or a legal hold is `ON` | | Making a bucket public ([`PutBucketAcl`](https://docs.strg.com/s3-api/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`](https://docs.strg.com/s3-api/CreateBucket)) | Any ACL or grant other than the canned ACL `private` | | Deleting a bucket ([`DeleteBucket`](https://docs.strg.com/s3-api/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](https://docs.strg.com/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 :`, 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](https://docs.strg.com/rest-api/list-access-keys), [Get an access key](https://docs.strg.com/rest-api/get-access-key), [Create an access key](https://docs.strg.com/rest-api/create-access-key), [Delete an access key](https://docs.strg.com/rest-api/delete-access-key) | **Warning: This permission reaches every 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](https://docs.strg.com/access-keys#creating) has the details. - A key can delete itself, after which it stops working like any deleted key. - [The dashboard's own key](https://docs.strg.com/access-keys#the-dashboards-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. **Warning: This permission reaches every key** 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](https://docs.strg.com/access-keys#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](https://docs.strg.com/access-keys#the-dashboards-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`](https://docs.strg.com/s3-api/GetObject) shows how. --- # CORS rules Cross-origin resource sharing (CORS) is how a browser decides whether JavaScript on one website may talk to another. When a page on `https://www.example.com` uses `fetch()` or an S3 SDK to reach `https://s3.eu-central-1.strg.com`, that is a cross-origin request, and the browser lets the page send it, or read the answer, only if the bucket's CORS rules allow that page's origin. Browsers do this to protect the people using them; CORS rules are how a bucket tells the browser which websites it is happy to hear from. A bucket needs CORS rules when a browser application talks to it directly: a web app taking uploads straight from the browser with presigned URLs, a page reading JSON or images into a script, a photo editor drawing objects onto a canvas, or an S3 SDK running in the page. Plain ``, `