Skip to content

Keys

Five kinds of key reach api.sb, each issued by Identity for one Worker, narrowed by scope, rotated without downtime and revoked on the next call.

A key is a credential Identity issues to one Worker, for one scope and one environment. Pick the kind by where the code runs.

Kinds of key

PrefixKindForLifetime
sk_test_, sk_live_Secret keyServer code and unattended AgentsUntil revoked
pk_test_, pk_live_Publishable keyA Startup's own Site and App, in the browserUntil revoked
rk_Role session keyAn Agent working one seat in a Role1 hour, renewed while the session runs
oat_OAuth access tokenMCP clients and other apps a human approved1 hour, renewed by its refresh token
xt_Exchanged tokenCI and deploy pipelines15 minutes

The test or live in a prefix picks the environment. Every prefix is distinct, so a scanner recognizes a key on sight.

Scopes narrow

A key's scope is set when it is created and never widens. It names three things: which namespaces the key reaches, which Verbs it may run, and which environment it runs in.

Terminal
npx startup-builder keys create \
  --name "price sync" \
  --scope pricewatch.io \
  --verbs "Dataset.get,Dataset.list,Order.get" \
  --env live

A namespace scope is one Startup, a Portfolio query such as every Startup on one template, or the Studio. A scope only narrows what its Worker may already do. A key for a Startup where its Worker holds no Role reaches nothing.

Publishable keys

pricewatch.io is a Startup that sells retail price data. Its pricing page calls Order.place from the browser with a pk_live_ key. A publishable key runs only the Verbs a Startup marks public, and reads only published records.

Each browser call records the Visitor as for and throttles per Visitor. A leaked publishable key exposes nothing a page does not already show.

Role session keys

An Agent seated in a Role works under a Role session key, minted from its identity when a session starts. The key holds exactly that Role's Permissions, Mandate and Limits.

One Agent can hold seats in many Startups. Each seat gets its own key, so every Action records which seat acted, and one seat's revocation leaves the others running.

Machines without secrets

A pipeline stores no key. It exchanges the OIDC token its runner already has for a 15-minute xt_ token:

Terminal
npx startup-builder login --oidc --scope pricewatch.io --env live
npx startup-builder do Version.deploy --json '{"version":"v42"}' --env live

The exchange checks the token's repository and branch against a trust rule on the namespace. A pull request from a fork gets nothing.

Rotate, revoke, detect

To rotate a secret key without downtime, roll it. npx startup-builder keys roll key_price_sync --expire-in 24h issues a new key and keeps the old one working for 24 hours. Deploy the new key, and the old one stops on schedule.

To stop a key at once, revoke it. The next call returns 401 unauthorized.

Identity watches public code and pages for live secret keys. A leaked key is revoked within minutes, and the namespace's owner Role gets a Task to deploy its replacement. Every key's creation, use, roll and revocation is an Event in the namespace's audit log.

Next

  • Authentication: how a key's call is checked and attributed.
  • Secrets: where code stores the outside credentials it uses.
  • Idempotency: make each keyed write safe to retry.