Provision S3 Storage End-to-End¶
This guide walks through the complete lifecycle of setting up S3-compatible object storage: create an RGW user, inspect the credentials, create a bucket, apply a quota, and upload a file via a presigned URL.
Time to complete: ~10 minutes
Prerequisites: An organization, a project with object storage enabled, and a bearer token with rgw:create and rgw:update permissions.
Step 1 — Create an RGW user¶
POST /rgw/users
Authorization: Bearer <token>
Content-Type: application/json
{
"user": {
"name": "my-app-storage",
"project_id": "<project-uuid>"
}
}
The response includes the new user's id, access_key_id, and the unmasked secret_key. Store the secret key immediately — subsequent calls return it masked.
{
"id": "b3f1c2d4-...",
"name": "my-app-storage",
"project_id": "<project-uuid>",
"access_key_id": "AKIAIOSFODNN7EXAMPLE",
"secret_key": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
"locked": false,
"quota": {
"max_size_kb": 524288000,
"enabled": true
}
}
A default quota of 500 GB is applied automatically.
Step 2 — Create a bucket¶
Use any S3-compatible client with the credentials from step 1. Here is an example with the AWS CLI:
aws configure --profile my-app \
--region de-muc1 \
--endpoint-url https://storage.muc1.de.bnerd.com
# Enter credentials when prompted:
# AWS Access Key ID: AKIAIOSFODNN7EXAMPLE
# AWS Secret Access Key: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
aws --profile my-app s3 mb s3://my-app-assets
Alternatively, create a bucket through the platform API via the buckets endpoint or the dashboard file browser.
Step 3 — Adjust quota (admin only)¶
If the default 500 GB is insufficient, an admin can raise it:
PATCH /rgw/users/<user-id>
Authorization: Bearer <admin-token>
Content-Type: application/json
{
"quota": {
"max_size_kb": 1073741824,
"enabled": true
}
}
max_size_kb: 1073741824 = 1 TB. Use -1 to remove the size limit entirely.
Admin-only
Quota changes require platform-admin privileges. Non-admin requests with a quota field receive 403 Forbidden.
Step 4 — Generate a presigned upload URL¶
To allow a browser or client to upload directly to RGW without routing through your backend:
POST /rgw/users/<user-id>/buckets/my-app-assets/objects/upload_url
Authorization: Bearer <token>
Content-Type: application/json
{ "key": "uploads/logo.png" }
Response:
The client can PUT the file body directly to url — no additional headers required. The URL expires in 15 minutes.
Step 5 — Verify the upload¶
aws --profile my-app \
--endpoint-url https://storage.muc1.de.bnerd.com \
s3 ls s3://my-app-assets/uploads/
Or via the platform API:
GET /rgw/users/<user-id>/buckets/my-app-assets/objects?prefix=uploads/
Authorization: Bearer <token>
Rotating the secret key¶
The response includes the new unmasked secret_key. Update your application's environment variables or secrets manager before the old key is invalidated.
Locked users cannot rotate keys
If locked: true, renew_key is a no-op. An admin must unlock the user first.
Clean up¶
To delete the user and all its data:
Irreversible
purge_objects=true deletes every object in every bucket before removing the user. The platform records an audit event with the bucket names and total size before the purge runs. There is no undo.