S3 access keys

DanubeData access keys are S3-compatible credentials your applications use to connect to your buckets. This guide explains the two scope types — team-wide and per-bucket — and how to create, rotate, and revoke keys.

Overview

Every S3 request to DanubeData is authenticated by an access key ID and a secret access key. Access keys belong to a team and inherit that team's bucket ownership.

There are two scope types:

  • Team-wide — Full access to every bucket the team owns. This is the default and matches the behavior of existing keys.
  • Specific buckets — Restricted to a chosen list of buckets, with an independent permission level per bucket.

Scoped keys are enforced at the storage backend itself via bucket policies — not just inside the dashboard. The restriction holds even when the key is used outside our tools.

Team-wide vs scoped keys

PropertyTeam-wideSpecific buckets
Buckets reachableAll current and future buckets owned by the teamOnly the buckets explicitly granted
Permission modelFull read/write/delete on all bucketsChosen per bucket (read-only, read-write, or full)
aws s3 ls (no bucket)Lists all team bucketsReturns empty (see Known behavior)
Recommended forAdmins, backup tooling, shared CI runnersApplication credentials, per-environment isolation, third-party integrations

If a key with a leaked secret is restricted to a single bucket, only that bucket is exposed — the rest of your storage remains isolated.

Permission levels

When you create a scoped key you pick a level for each bucket:

LevelIncludesTypical use
Read-onlyGetObject, ListBucket, HeadObject, GetObjectVersion, GetBucketLocationAnalytics readers, CDN origins, backup verifiers
Read-writeAll read-only actions plus PutObject, AbortMultipartUpload, ListMultipartUploadParts, ListBucketMultipartUploadsApplication uploads, sync jobs, image processors
FullAll read-write actions plus DeleteObject, DeleteObjectVersion, GetBucketVersioning, PutBucketCors, PutBucketLifecycle, PutBucketVersioningBucket maintenance, migrations, lifecycle automation

Different buckets attached to the same key can have different levels — for example, read-only on analytics-prod and full on analytics-staging.

Creating an access key

From the Security page (any scope)

  1. Open Account → Security → S3 Credentials.
  2. Click Create access key.
  3. Enter a short name (up to 32 characters).
  4. Choose Access scope:
    • Team-wide — Skip to step 6.
    • Specific buckets — Add one row per bucket. For each row pick the bucket and a level (Read-only, Read-write, or Full). You can add up to 50 buckets per key.
  5. (Optional) Set an expiry date — the key will be auto-revoked after this date.
  6. Click Create access key.
  7. Copy the secret immediately. The secret is shown once at creation time and cannot be retrieved later. The access key ID is always visible.

From a bucket detail page (always scoped to that bucket)

  1. Open the bucket you want to scope the key to.
  2. Scroll to the Scoped access keys section.
  3. Click Create access key for this bucket.
  4. Enter a name and pick the permission level for this bucket.
  5. Click Create access key and copy the secret immediately.

This entry point creates a key scoped to that single bucket. To extend an existing scoped key to additional buckets, manage it from Security → S3 Credentials instead.

Listing and inspecting keys

The Security → S3 Credentials table shows:

  • Access key ID (the secret is never displayed again)
  • Name and creation time
  • Scope column — a Team-wide pill or a Specific buckets pill with a tooltip listing each bucket and level
  • Status (Active, Expired, Revoked, Error)
  • Last-used timestamp

On a bucket detail page, the Scoped access keys section only shows keys that include that bucket, along with the level granted to that specific bucket.

Rotating a key

DanubeData supports the standard two-key rotation pattern. Scope is immutable on an existing key, so to rotate:

  1. Create a new key with the same scope and the same per-bucket levels as the existing key.
  2. Deploy the new credentials to your applications.
  3. Confirm traffic — Watch the new key's last-used timestamp climb while the old key's stays still.
  4. Revoke the old key.

There is no "rotate in place" operation — this is deliberate so you control the cutover window.

Revoking a key

  1. Open Security → S3 Credentials (or the bucket's Scoped access keys section).
  2. Click Revoke on the row you want to disable.
  3. Confirm the prompt.

Revocation invalidates the credentials at the storage backend immediately. For scoped keys, the bucket policy is rebuilt without that key's principal, so access stops within seconds. Revoked keys remain in the table for audit purposes but cannot be reactivated.

Changing the buckets a scoped key can access

You can edit a scoped key's per-bucket permissions at any time:

  • Add a new bucket to the key (pick a level)
  • Change the level on an existing bucket
  • Remove a bucket from the key

These changes apply within seconds — the backend bucket policy is rebuilt and pushed to the storage layer automatically.

You cannot change a key's scope type after creation (for example, you cannot convert a team-wide key into a scoped key, or vice versa). If you need a different scope type, create a new key and revoke the old one.

Using your key with the S3 API

Use the access key ID and secret as standard S3 credentials, pointing at the DanubeData endpoint.

Environment variables

Bash
export AWS_ACCESS_KEY_ID="YOUR_ACCESS_KEY_ID"
export AWS_SECRET_ACCESS_KEY="YOUR_SECRET_ACCESS_KEY"
export AWS_ENDPOINT_URL="https://s3.danubedata.ro"
export AWS_REGION="fsn1"

aws CLI example

Bash
# Upload an object to a bucket the key has access to
aws --endpoint-url https://s3.danubedata.ro s3 cp report.pdf s3://my-bucket/

# List objects in a bucket
aws --endpoint-url https://s3.danubedata.ro s3 ls s3://my-bucket/

Python (boto3) example

Python
import boto3

s3 = boto3.client(
    's3',
    endpoint_url='https://s3.danubedata.ro',
    aws_access_key_id='YOUR_ACCESS_KEY_ID',
    aws_secret_access_key='YOUR_SECRET_ACCESS_KEY',
    region_name='fsn1',
)

s3.put_object(Bucket='my-bucket', Key='hello.txt', Body=b'hello')

Known behavior: aws s3 ls and scoped keys

aws s3 ls (without a bucket name) calls the S3 ListAllMyBuckets operation, which only returns buckets owned by the requesting credentials. Scoped keys don't own any buckets — they're granted access through bucket policies — so aws s3 ls returns an empty list.

To list objects in a bucket the scoped key can access, include the bucket name:

Bash
aws --endpoint-url https://s3.danubedata.ro s3 ls s3://your-bucket-name/

This calls ListBucket, which the bucket policy grants for all three levels. Team-wide keys do see the full bucket list with aws s3 ls.

Best practices

  1. Use least privilege — Prefer scoped keys with the lowest level that works (read-only over read-write, read-write over full).
  2. One key per application — Don't share keys across services; this makes rotation safer and audit easier.
  3. Rotate periodically — Use the two-key rotation pattern at a cadence that fits your compliance needs.
  4. Set expiry dates — For temporary integrations, set an expiry so the key is auto-revoked.
  5. Never commit secrets — Inject credentials via environment variables, mounted files, or a secrets manager.
  6. Monitor last-used timestamps — Keys that haven't been used in a long time are good candidates for cleanup.
  7. Separate buckets by sensitivity — A scoped key on a sensitive bucket can't be misused to read unrelated data.

Troubleshooting

"Access Denied" on a scoped key

  1. Confirm the bucket is in the key's scope — Open the key in Security → S3 Credentials and check the bucket list in the tooltip.
  2. Check the level — A read-only level can't perform PutObject; a read-write level can't perform DeleteObject. Bump the level or use a different key.
  3. Check key status — Expired, Revoked, or Error keys all reject requests. Active is the only working status.
  4. Wait a few seconds after editing — Bucket policy changes are reconciled in the backend; brief propagation can take a few seconds after an edit.

aws s3 ls returns an empty list

Expected behavior for scoped keys. See Known behavior above. Use aws s3 ls s3://bucket-name/ with the bucket name to list objects.

Status is "Error" in the dashboard

The key's bucket policy could not be applied at the backend. This is usually transient and resolves on the next reconcile sweep (runs hourly). If the status persists, contact support with the access key ID.

Next steps


Questions? Contact support at support@danubedata.ro