Gateway side: enabling the S3 listener
The S3 listener is off by default and binds its own address, separate from the read API. The gateway also needs a delegate keypair: the key that tapes delegate writes to.max_buffered_bytes) and verified before anything lands; declared-size, chunked, and unsigned payloads stream with bounded memory, up to max_object_bytes.
Operator side: credentials and policy
Credentials are managed through an admin API on a separate, operator-token-authenticated listener. It issues and revokes SigV4 credentials. A credential is scoped to specific buckets or to the principal’s own tape. Rules are default-deny, and an explicit deny always wins. The same API sets per-principal budgets and carries an emergency kill switch for all writes. Every authorization decision is logged.gateway.s3.write.admin.listen (default 127.0.0.1:3451, loopback only) and every request must carry Authorization: Bearer <token> matching gateway.s3.write.admin.operator_token. With no token configured, the admin API refuses all requests. Routes: /credentials (create, list; DELETE /credentials/{access_key_id} revokes, PUT .../grade assigns a metering grade), /policy/rules (create, list; delete by /{priority}/{id}), /kill-switch, /budgets, and /ledger/{principal} (usage; PUT/DELETE .../budget overrides a principal’s budget).
Tape side: delegating writes
One on-chain step, performed by the bucket owner: point the tape’s delegate at the gateway’s key. From then on the gateway can register, certify, and delete tracks on your behalf without ever holding your tape keypair (how delegation works). The gateway publishes the key atGET /v1/s3, and tape delegate <address> sets it from the CLI (set up a bucket). From code:
Rust
revoke_tape_delegate removes the delegate again (managing tapes).
The failure you’ll actually see when this step is missing: an S3 write returns 403 AccessDenied with a message saying the bucket tape has not delegated writes to this gateway.
How a write gets approved
When an S3 write arrives, the gateway runs six checks in order. If any check fails, the write is refused. Nothing passes by default.- Is writing enabled at all? The kill switch stops every write on the gateway when the operator flips it.
- Is this credential in good standing? It must be active, not revoked, and inside its size and rate caps.
- May this credential touch this bucket? Each credential is scoped to specific buckets, or to the principal’s own tape.
- Do the operator’s rules allow it? Anything not explicitly allowed is refused, and an explicit deny beats any allow.
- Does the chain agree? The bucket’s tape must have delegated writes to this gateway’s key, must not be expired, and must have capacity left.
- Is there budget left? The write’s bytes are counted against the credential’s budget.