Buckets, versioning & lifecycle
Create buckets (each backed by a RustFS claim) with versioning and visibility; set per-bucket lifecycle rules that expire old versions or abort stale multipart uploads. List, get and force-delete buckets.
Capability group 03
RustFS is productized as public object storage on the same claim plane: buckets with versioning and lifecycle, objects with prefix/delimiter listing, multipart uploads, scoped S3 access keys and presigned GET/PUT — under /api/v1/buckets and /api/v1/object. A native S3 wire gateway at /s3/… speaks AWS Signature V4, so aws-cli, boto3 and any S3 SDK connect directly, with the tenant resolved from the access key (no X-Tenant-Id header).
RustFS · buckets · SigV4 wire gateway
Sub-capabilities
Create buckets (each backed by a RustFS claim) with versioning and visibility; set per-bucket lifecycle rules that expire old versions or abort stale multipart uploads. List, get and force-delete buckets.
Put/get/head/delete object metadata with prefix + delimiter folder rollup and pagination; list all versions incl. delete markers; initiate multipart uploads, upload parts (etag per part), and complete with strictly ascending parts.
Issue an S3 access key (the R2 API token) — the secret is shown once — list keys (never the secret), and revoke by id. The gateway resolves the tenant from the key, so nothing trusts a header.
Presign a GET or PUT for a key (HMAC over a canonical string, TTL-bounded), and verify a presigned request server-side — valid within TTL, signature + method must match.
The /s3 endpoint reconstructs the SigV4 canonical request and resolves the tenant from the access-key-id — no header trust. A bad signature returns a real <Error>SignatureDoesNotMatch</Error> envelope with the S3 status.
Bytes served from a bucket to the SS-27 CDN are classified intra-edge and zero-rated in the usage ledger; external egress is billable. Per-bucket and tenant-wide usage summaries separate the two.
Endpoints
Method + path straight from the SS-02 OpenAPI spec. Governed routes take an SS-01 bearer token and, where marked, an X-Tenant-Id; the S3 wire gateway authenticates with AWS SigV4 instead.
/api/v1/bucketsbearertenantCreate a bucket (backed by a RustFS claim): versioning, visibility, region.
/api/v1/bucketsbearertenantList the tenant's buckets.
/api/v1/buckets/{bucket}/versioningbearertenantEnable or suspend bucket versioning.
/api/v1/buckets/{bucket}/lifecyclebearertenantSet per-bucket lifecycle rules (expire versions, abort stale uploads).
/api/v1/buckets/{bucket}/objectsbearertenantList objects with prefix + delimiter folder rollup and pagination.
/api/v1/buckets/{bucket}/objects/{key}bearertenantPut an object (control-plane metadata: size, content-type, user metadata).
/api/v1/buckets/{bucket}/versionsbearertenantList object versions (all versions incl. delete markers).
/api/v1/buckets/{bucket}/uploadsbearertenantInitiate a multipart upload; parts via PUT …/uploads/{upload}/parts/{part}.
/api/v1/buckets/{bucket}/uploads/{upload}/completebearertenantComplete a multipart upload (parts present + strictly ascending).
/api/v1/buckets/{bucket}/presignbearertenantPresign a GET or PUT for a key (HMAC over a canonical string, TTL-bounded).
/api/v1/object/access-keysbearertenantIssue an S3 access key (the R2 API token). Secret shown once.
/api/v1/object/access-keysbearertenantList access keys (never returns the secret).
/api/v1/object/presign/verifybearertenantVerify a presigned request (valid within TTL, signature + method match).
/api/v1/object/usagebearertenantTenant-wide usage summary (aggregate across buckets, zero-rated vs billable egress).
/s3/{bucket}aws sigv4S3 CreateBucket — SigV4, tenant from the access key.
/s3/{bucket}aws sigv4S3 ListObjectsV2 (GET Bucket) — real S3 XML.
/s3/{bucket}/{key}aws sigv4S3 PutObject / UploadPart.
/s3/{bucket}/{key}aws sigv4S3 GetObject.
Worked example
# --- Native API: presign a PUT (HMAC, TTL-bounded) ---------------
# POST $BASE/buckets/site-assets/presign
# {"method":"PUT","key":"app.v42.js","ttl_seconds":900}
# → {"url":"https://s3.dbaas.nexocloud.io/s3/site-assets/app.v42.js?...",
# "expires":"2026-07-05T12:15:00Z"}
# --- S3 wire gateway: boto3 talks straight to /s3 ---------------
import boto3
s3 = boto3.client(
"s3",
endpoint_url="https://s3.dbaas.nexocloud.io/s3",
aws_access_key_id=ACCESS_KEY, # POST /api/v1/object/access-keys
aws_secret_access_key=SECRET_KEY, # shown once, at creation
region_name="nexo-1",
)
s3.create_bucket(Bucket="site-assets") # → PUT /s3/site-assets
s3.upload_file("app.v42.js", "site-assets", "app.v42.js")
for o in s3.list_objects_v2(Bucket="site-assets")["Contents"]:
print(o["Key"], o["Size"])
# The gateway reconstructs the SigV4 canonical request and resolves
# the tenant from the access-key-id — there is NO X-Tenant-Id header.aws-cli works identically: aws --endpoint-url https://s3.dbaas.nexocloud.io/s3 s3 mb s3://site-assets. A bad signature returns a real <Error>SignatureDoesNotMatch</Error> S3 envelope.
In the architecture
It is the same SS-02 object engine the Edge Cloud portal fronts as R2 — one engine, two product lenses. Buckets are RustFS claims, so they inherit per-tenant KEK encryption, backup and metering. The /s3 gateway is a thin SigV4 front over the same object model; egress to the SS-27 edge is classified intra-edge and zero-rated in the SS-60 usage ledger.
Explore the rest of the platform. Relational SQL · Polyglot engines & tiers · Serverless & branching · Data governance & isolation
Get started →