Docs Connecting an S3 bucket

Connecting an AWS S3 bucket

Each collection in Studio can pick its own storage backend from its Storage settings (the gear/cloud icon on its card) — either local storage or a user-supplied S3-compatible bucket. This guide walks through setting up a bucket on AWS specifically, including the IAM policy Graxeon actually needs.

1. Create an IAM user

Use a dedicated IAM user scoped to this bucket — not your root account credentials.

  1. In the AWS Console, go to IAM → Users → Create user.
  2. Give it a descriptive name, e.g. graxeon-s3-<collection>.
  3. Skip console access — this user only needs programmatic (API) access.

2. Attach a scoped policy

Avoid AmazonS3FullAccess. Graxeon's S3 backend only ever calls ListObjectsV2, GetObject, PutObject, DeleteObject, and CopyObject against the one bucket you give it, so scope the policy to exactly that.

In IAM, go to Users → your user → Permissions → Add permissions → Create inline policy, switch to the JSON tab, and paste this — replacing YOUR-BUCKET-NAME with your actual bucket name:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["s3:ListBucket"],
      "Resource": "arn:aws:s3:::YOUR-BUCKET-NAME"
    },
    {
      "Effect": "Allow",
      "Action": ["s3:GetObject", "s3:PutObject", "s3:DeleteObject"],
      "Resource": "arn:aws:s3:::YOUR-BUCKET-NAME/*"
    }
  ]
}

Name the policy something like graxeon-bucket-access and create it.

Public access blocks on the bucket are fine to leave on — Graxeon serves assets via presigned URLs, not public links.

3. Generate an access key

  1. Go to IAM → Users → your user → Security credentials → Access keys → Create access key.
  2. Choose "Third-party service" as the use case.
  3. Copy both the Access key ID and Secret access key immediately — the secret is shown only once and cannot be retrieved again later.

4. Configure the collection in Studio

Open the collection's settings → Storage tab, choose S3-compatible bucket, and fill in:

Leave Endpoint URL blank for real AWS. That field exists only for S3-compatible alternatives that need a custom host — MinIO, Cloudflare R2, etc. For AWS, boto3 derives the correct regional endpoint from the region you provide, and setting it to anything else will produce Invalid endpoint or route requests to the wrong service entirely.

Saving copies any existing files in the collection to the new location, so a bad bucket name or credential pair surfaces immediately as an error rather than silently failing later.

Troubleshooting

InvalidAccessKeyId — "The Access Key Id you provided does not exist in our records."

Invalid endpoint

To verify a key/secret pair independently of Graxeon, test it directly with the AWS CLI:

aws s3 ls s3://your-bucket-name --profile your-test-profile

A clean exit (even with no output, if the bucket is empty) confirms the credentials and bucket are valid at the AWS level — if Graxeon still rejects them after that, the issue is in how the values reached the form rather than the credentials themselves.