Delegated access (owner-signed grants)
For a browser session, an agent or a device: a grant hands another key a narrow, short-lived slice of a tenant, signed by the owner alone. No issuer, no app server, no shared secret to leak.
Example: a user lets a photo-sorting agent read and write u/alice/ in one bucket for a day. The agent talks plain S3. It can’t touch anything else, and the user can cut it off with one signature.
How it works
Section titled “How it works”- The owner signs a grant: the delegate’s public key, one bucket, a key prefix, the actions and a validity window.
- The delegate signs its own short-lived tokens carrying the grant, each valid at most fifteen minutes and never past the grant.
- The deployment checks both. The tenant is the owner’s.
The delegate sends Authorization: Bearer <token> on the S3 API, path-style, or virtual-hosted where your deployment has it on. The grant format and test vectors come with onboarding.
What a grant can allow
Section titled “What a grant can allow”| Action | Allows |
|---|---|
get |
reading objects under the prefix |
put |
writing them, multipart included |
list |
listing keys under the prefix |
delete |
deleting them |
bucket |
creating the named bucket (with its retention and space settings), checking it, its bucket policy, and deleting it. The prefix must be empty. |
agent-space |
creating the named bucket as an agent space, and nothing else. bucket alone can’t. The prefix must be empty. |
- Never allowed: listing the owner’s buckets, multi-object delete.
- Outside the grant:
403. - Buckets a delegate creates are the owner’s; the owner’s limits cover delegate traffic.
Revoking
Section titled “Revoking”The owner signs a revoke naming the grant. Every token under it then gets 401. The owner’s signature is the only credential needed, and each revoke goes on the public ledger.
Once a grant is revoked or expires, or its holder asks for something outside it, the refusal goes on the owner’s ledger: which grant, what was asked, and how often witnessed. It never records any data. A refused request that can’t be tied to one of your grants isn’t recorded against you.
Permafrost runs on Sui testnet and Walrus testnet. Everything here describes a shipped testnet instance, not a production service.