Skip to content

Keys & authorizations ​

This page explains the keys that can write data under your wallet, where those grants live, and how to review or revoke them. It also covers agent keys: the keys you create so an agent, a script or a server can publish and manage your uploaded sites without your browser.

Prerequisite: signed in. Background: Your data on-chain.

Prompt for your agent

Copy this into Claude Code, Cursor or any agent that can run shell commands. Creating a key is yours alone; the agent tells you exactly which key to create, then proves it works.

text
Read https://docs.stasho.xyz/guides/keys-and-authorizations.md. I want you to manage my
Stasho sites. Tell me exactly which agent key to create in Settings → Authorizations: which
Sites choice, which scopes you need and why, the shortest expiry that fits, and whether to
pick "My agent signs" (if so, generate your own signing keypair and give me the public key
to paste; never show me the private key). I will put the key in the STASHO_AGENT_KEY
environment variable: never ask me to paste it in chat. Then verify the key works with a
read call and tell me what it lists. Never ask for my wallet key.

Why other keys write under your wallet ​

Your project data lives on-chain under your wallet address — but you wouldn't want to approve a wallet popup for every status change of every deploy. So the network supports delegation: your wallet signs, once, a security record listing other keys allowed to write specific kinds of messages on your behalf. Everything in that record is public and auditable.

Three keys are always involved; two more appear once you work with an agent.

Your wallet key authorizes two things: the Stasho delegate, which writes deployment progress and pins artifacts, and a browser session key that signs your writes and rotates every 24 hours. Both can write project and deployment records, but only the Stasho delegate can also write custom-domain records. Neither can touch your wallet's security settings.Your wallet key authorizes two things: the Stasho delegate, which writes deployment progress and pins artifacts, and a browser session key that signs your writes and rotates every 24 hours. Both can write project and deployment records, but only the Stasho delegate can also write custom-domain records. Neither can touch your wallet's security settings.
What each of the three everyday keys is allowed to write. Revoking a grant removes exactly one arrow. Agent keys (below) ride on the delegate's arrow or add one of their own.
KeyHeld byWhat it's for
Your walletYouThe owner. Signs the grants below; the only key that can change them.
Browser session keyYour browserSigns your own writes (creating projects, saving settings) without a wallet popup each time. Rotates on a 24-hour cycle; a new one is created and the old one revoked automatically as you use the app.
Stasho delegateOur backendWrites deployment progress (queued → building → live) and pins artifacts as your builds run — the writes that happen while your browser is closed.
Agent keyYour agent, script or serverA bearer token (stasho_ak_…), not an on-chain key. Acts as you on your uploaded sites, within the scopes you gave it, over the agent API. Stasho stores only its hash.
Agent signing keyYour agentOptional. A public key you paste when creating an agent key with My agent signs: the agent then signs its own site records on the network, and the key is listed here as an Agent signer row.

The grants are scoped: the session key can write project and deployment records only; the Stasho delegate can write those, plus your custom-domain records, on a separate channel. Neither can touch the security record itself — so a leaked session key can forge deploy statuses for a day at worst, never lock you out or grant itself more power. An agent key that can create, change or remove sites needs one of two things on-chain, chosen when you create it: with Stasho signs for me, your signature lets the delegate write site records on the agent's behalf (the delegate row then wears an Agent keys badge); with My agent signs, the agent's signing key gets a row of its own and the delegate gains nothing.

The Authorizations section ​

Settings → Authorizations lists every key currently (or previously) authorized under your wallet, labelled by what it is:

RowWhat it is
Stasho (current)The Stasho delegate. Wears an Agent keys badge, with a Withdraw button, while it may create, change and remove sites for your agent keys.
Stasho (retired)A previous delegate key, kept so its old writes stay verifiable.
This browserYour active session key. This browser (expired) is one of this browser's that has rotated out.
Another browser or sessionA session key registered by a different browser or device of yours — or not.
Agent signer · key namesAn agent's signing key, naming the agent keys that use it; Agent signer (key revoked) when none is left.
OtherA grant Stasho did not create, for instance from another tool.

Each row shows what the key may write and offers Revoke; the delegate row offers Re-authorize when a grant is missing. Below the list, the Agent keys section holds every agent key of your account with Create key.

Agent keys ​

An agent key is created in one of two places, and both lists show the same keys:

  • Settings → Authorizations → Agent keys, for a key that works on one site or on all your uploaded sites.
  • An uploaded site's Settings page → Agent publishing, for a key tied to that site.

Only uploaded sites can be managed with a key; what an agent can do with one is the whole agent API. Each key in the list shows its name, which sites it reaches, its scopes, its expiry and when it was last used, with Rotate (a new key with the same settings, shown once; the old one stops at once) and Revoke. Each build a key publishes reads "Published with key" in the site's deployment list.

Creating a key ​

Create key opens a dialog with:

  • Name — the attribution: it shows on every build, domain and site the key touches, so name it after what holds it ("Worker prod", "Claude chat").
  • Sites — This site or All sites. A key for one site cannot create sites.
  • Scopes — publish, create, domains, delete. delete needs an expiry (90 days at most) and an email on file for your account, so you can be told when a key deletes a site or detaches a domain.
  • Expires — 1, 7, 30 or 90 days, or Never. For a chat agent, 1 or 7 days; Never only for a server you control.
  • Who signs the site records — shown when a scope writes site records (create, domains, delete):
    • Stasho signs for me: Stasho's delegate creates, changes and removes site records for this key. One signature now: the next step, Allow Stasho to manage your sites, ends in Sign and create key.
    • My agent signs: paste the agent's public signing key (an uncompressed secp256k1 key, 0x04 followed by 128 hex characters). The agent signs its own site records, and the key is listed as an Agent signer row. Only on an All sites key with at least one of those scopes.

The key is shown once, on the Key created view, together with a ready-made prompt to hand your agent. Copy it then: anyone who has it can act on your sites within its scopes until it expires, including anyone who can read the chat you paste it into. A publish-only key needs no signature at all.

Revoking ​

Revoke a session key any time — for instance one from a device you've lost. Your next write bundles the removal into the on-chain record.

Revoke an agent key from either list: anything using it stops working at once. When it is the last key that needed Stasho's permission to manage sites, the dialog offers Also withdraw (one signature) so the delegate's grant goes with it. When a signer key is revoked, its signing key stays authorized while another key still uses it; with the last one the dialog also revokes the Agent signer row, one signature.

Withdraw, on the delegate row, removes the delegate's permission to create, change and remove sites and revokes every key that relied on it; keys under My agent signs and publish-only keys keep working.

Revoke an Agent signer row directly, and the agent keys that use it can no longer create, change or remove sites; publishing with them keeps working, and existing deployments are unaffected.

Revoke all other sessions removes every session key that is not this browser's in one signature. It also revokes all agent keys and their signing keys, and withdraws the delegate's grant: the clean-slate button.

Revoke the Stasho delegate and deploys stop working: builds can't report status and artifacts can't be pinned. The deployment that hits the wall shows Re-authorization required (awaiting_resign), and the Redeploy button becomes Re-authorize. This is reversible — re-authorizing is one wallet signature, and the next deploy proceeds.

The same Re-authorization required state can appear without you revoking anything — e.g. when the app needs a grant that didn't exist when you first signed up (this happened to alpha users when custom domains shipped). The fix is the same single signature in Settings → Authorizations.

Verification ​

  • The Authorizations section shows the delegate and your current browser, both marked authorized; every agent key you created is in the Agent keys list, and a key under My agent signs has its Agent signer row
  • The same list, from outside the app: https://api.stasho.xyz/api/audit/<your-address> — or on-chain via any public explorer
  • After a revoke + re-authorize cycle, a Redeploy completes normally
  • After revoking an agent key, a call with it answers 401 key_invalid

What can go wrong ​

SymptomCauseFix
Deployment stuck at "Re-authorization required"The delegate lacks a grant (revoked, or a newer feature needs more scope)Settings → Authorizations → sign the re-authorize prompt → Redeploy
Authorizations section shows a browser you don't recognizeA session key from another device or browser profile of yours — or notRevoke it; sessions elsewhere will just re-prompt to sign in
An agent key or an Agent signer row you don't recognizeA key you forgot, a key someone created in a session of yours, or a signing key you never pastedRevoke it. A signer row's revoke stops those keys from changing site records at once; the keys themselves are in the Agent keys list
Creating a key fails with "Your authorizations grant the Stasho delegate the security aggregate"A row for the Stasho delegate, written outside the app, names the security record among what the delegate may write. Stasho never widens such a row, so the key's one signature is refused (409 delegate_row_forbidden)Rewrite that row with the tool that wrote it so it no longer names security (the app's own Re-authorize only adds to a row, never removes), then create the key again

Working with an agent ​

Key management is yours alone: an agent cannot create, rotate or revoke a key, and it should never see the dashboard. Its part is to tell you which key to create and to prove it works afterwards.

What the agent hands you, in these words:

text
In the Stasho dashboard open Settings → Authorizations, scroll to Agent keys and click
Create key. Name: "<name>". Sites: <This site / All sites>. Scopes: <publish, create,
domains>. Expires: <7 days>. Who signs the site records: <Stasho signs for me, then Sign and
create key / My agent signs, paste this public key: 0x04…>. On the Key created view, copy
the key and set it as the STASHO_AGENT_KEY environment variable where I run; do not paste it
here. Tell me when it is set.

How the agent verifies it afterwards. The key itself is the proof, with one read call:

bash
curl -s -o /dev/null -w '%{http_code}\n' -H "Authorization: Bearer $STASHO_AGENT_KEY" \
     https://api.stasho.xyz/api/agent/sites

200 means an All sites key with publish; a key for one site answers 403 wallet_key_required there and 200 on GET /api/agent/sites/<projectId> instead; 401 key_invalid means the key was mistyped, has expired or is revoked. A write scope is checked only by a write: a 403 scope_missing names the scope the key lacks. A key under My agent signs also has a public trace: the signing key's address (shown on the Key created view) appears in the audit endpoint's authorized senders, currently authorized, with projects among its aggregate keys:

bash
curl -s https://api.stasho.xyz/api/audit/$ADDRESS \
  | jq '.authorizedSenders.sessionKeys[] | select(.address | ascii_downcase == "<signer address>")'