---
title: "Scoped API keys and the durable-key model"
description: "The durable, account-scoped key a tenant mints for an end user — how it stays live, the two tiers, inquiry-key export, Cold Vault accounts, capacity eviction, and coarse revocation."
---

> Documentation Index
> Fetch the complete documentation index at: https://tee.hypetrade.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Scoped API keys and the durable-key model

A **scoped API key** is a single opaque string a tenant mints for one end user,
bound to one account — or one wallet within it. Unlike a workspace token, it is
**durable**: it keeps working, and keeps its account unlocked, until the service
restarts. The end user holds the one string (for example in `localStorage`) and
never sees the workspace password.

The canonical flow is a tenant minting a key for an end user who later redeems a
key export against it — the workspace password never leaving the tenant's side:

<Mermaid
  caption="The end user generates a keypair, the tenant mints a scoped key bound to their inquiry key, and later the user exports a key that only their private half can open."
  code={`sequenceDiagram
  autonumber
  actor U as End user
  participant T as Tenant backend
  participant S as TEE Docker
  U->>U: generate an X25519 keypair, keep the private half
  U->>T: ask for access, hand over the inquiry public key
  T->>S: POST /v1/auth/api-key — tier unlimited, inquiryKey, accountPassword if Cold Vault
  Note over S: the account is unlocked and pinned open inside the enclave
  S-->>T: 201 — one durable scoped-key string
  T-->>U: the scoped key, kept in the browser
  Note over U,S: later — the workspace password is never shared
  U->>S: POST /v1/accounts/slug/wallets/id/export?vm=evm — Bearer scoped key
  S-->>U: a blob sealed to the inquiry key
  U->>U: unseal with the private half to recover the private key`}
/>

The endpoint shapes for minting and introspection are on
[API keys](/api/api-keys/); this page is the model behind them.

## Durable, and in memory

A live key is **stay-exposed**: while it exists it pins its workspace and its
bound account open, so the idle, absolute, and account-custody timers do not
apply to it. All of that state — the binding, the tier, the inquiry key — lives
in memory only. Nothing about a scoped key is written to disk, and **a restart
voids every key**. "Durable" means "until the process restarts," not "forever on
disk."

Nothing decrypted is persisted to achieve this: the never-lock behaviour comes
from keeping an already-unsealed session alive in the enclave, never from storing
a re-unlock secret. No workspace or account password is ever held at rest.

## Two tiers

A key is minted at one of two fixed tiers, expressed as its scopes:

| Tier | Scopes | What a scoped key can reach (this release) |
|---|---|---|
| `basic` (default) | `read`, `write` | Read its bound account, wallets, and addresses |
| `unlimited` | `read`, `write`, `sign`, `export` | The above, plus sealed export (with a live inquiry key) |

The `write` and `sign` scopes sit on the lease but are not reachable by a scoped
key: it is confined to its bound account's read routes plus export. Signing and
account/wallet management require a **workspace token**, so `unlimited` over
`basic` buys a scoped key only sealed export. Mint it deliberately, for users who
need export. See [Scopes and tiers](/concepts/scopes/).

## Export needs an inquiry key

Export is the highest-consequence operation, so it is never sealed to an operator
key. The end user generates their own X25519 keypair, keeps the private half, and
gives the tenant only the public **inquiry key** at mint. Every export the key
performs is sealed to it, and opens only for the holder of the private half.

- The inquiry key unlocks a small **functionality list** — today just `export`.
- It is **time-boxed** by `validationDuration` (default four hours). After it
  lapses the base key keeps working, but export locks again.
- Without an inquiry key, export is refused even on an Unlimited key.

The client-side unseal is in [Export key material](/guides/export-key-material/).

## Cold Vault accounts

An account may carry its **own password** — an extra secret beyond the workspace
password. Such an account can still be minted for: the tenant relays that
password as `accountPassword` at mint, the service unlocks the account, and the
durable key keeps it open. The password is used once and never stored.

## Capacity and eviction

A durable key holds a decrypted workspace handle in memory until restart, so
handle capacity is finite. When admitting a new key would exceed a tenant's
capacity, the tenant's **least-recently-used** durable key is evicted to make
room. An evicted key's next request fails exactly as after a restart — re-mint
it. Each use touches the key's recency, and every eviction is recorded in the
audit log so an evicted client knows to re-mint.

## Revocation is coarse

There is no per-key revoke. `DELETE /v1/auth/token` is accepted for a scoped key
but does nothing — a restart (or an eviction) is what ends it. Plan to re-mint
after a restart rather than to revoke, and keep the blast radius of any one key
small by scoping it to a single account or wallet.

## Identity binding

A key is bound to its account by the account's `slug` (and to a wallet by its
stable `id`). A slug can be reused after an account is deleted, so deleting an
account that a live key is bound to is recorded in the audit log — a later
account created with the same slug would otherwise inherit that key's authority.

## Related

- [API keys](/api/api-keys/) — the mint and introspection endpoints
- [Scopes and tiers](/concepts/scopes/) — the capability model
- [Export key material](/guides/export-key-material/) — the client-unseal flow
- [Workspaces and tokens](/concepts/workspaces-and-tokens/) — the session model a token uses instead

Source: https://tee.hypetrade.xyz/concepts/scoped-api-keys/index.mdx
