# Keys

URL: /code/api/guides/keys · Id: `page:code/api/guides/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](/code/platform/identity) issues to one [Worker](/business/nouns/worker), for one scope and one environment. Pick the kind by where the code runs.

## Kinds of key
| Prefix | Kind | For | Lifetime |
| --- | --- | --- | --- |
| `sk_test_`, `sk_live_` | [Secret](/business/nouns/secret) key | Server code and unattended [Agents](/business/nouns/agent) | Until revoked |
| `pk_test_`, `pk_live_` | Publishable key | A [Startup](/business/nouns/startup)'s own [Site](/business/nouns/site) and [App](/business/nouns/app), in the browser | Until revoked |
| `rk_` | [Role](/business/nouns/role) session key | An Agent working one seat in a Role | 1 hour, renewed while the session runs |
| `oat_` | OAuth access token | MCP clients and other apps a human approved | 1 hour, renewed by its refresh token |
| `xt_` | Exchanged token | CI and deploy pipelines | 15 minutes |

The `test` or `live` in a prefix picks the [environment](/code/cli/guides/environments). 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](/business/nouns/verb) it may run, and which environment it runs in.

```bash
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](/business/nouns/portfolio) query such as every Startup on one template, or the [Studio](/business/nouns/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](/business/nouns/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](/business/nouns/permission), [Mandate](/business/nouns/mandate) and [Limits](/business/nouns/limit).

One Agent can hold seats in many Startups. Each seat gets its own key, so every [Action](/business/nouns/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:

```bash
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](/code/api/errors/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](/business/nouns/task) to deploy its replacement. Every key's creation, use, roll and revocation is an [Event](/business/nouns/event) in the namespace's [audit log](/systems/trust-and-governance/audit-log).

## Next
- [Authentication](/code/api/guides/authentication): how a key's call is checked and attributed.
- [Secrets](/code/platform/secrets): where code stores the outside credentials it uses.
- [Idempotency](/code/api/guides/idempotency): make each keyed write safe to retry.