sable network
Buy on Index
Documentation · all sections

Delegated sub-keys

POST /v1/keys/delegate mints a narrower child of the calling API key. It's authenticated by the parent key itself, not a wallet session. The point is that an agent can hand a sub-agent a bounded credential mid-run, without a human in the loop.

curl https://api.buildsable.com/v1/keys/delegate \
-H "authorization: Bearer $SABLE_API_KEY" \
-H 'content-type: application/json' \
-d '{
  "name": "research-subagent",
  "spend_limit_usd": 0.50,
  "allowed_models": ["sable-llama-3.1-8b", "sandbox"],
  "expires_in_minutes": 15,
  "rate_limit_per_min": 10
}'

The plaintext key is returned exactly once.

The guarantee

A child is ≤ its parent on every axis, always. There is no request shape that widens a scope; the gateway clamps rather than validates, so an over-broad request produces a correctly-narrow key instead of an error.

FieldRule
spend_limit_usdRuleThe tighter of the two
allowed_modelsRuleIntersection with the parent's
expires_in_minutesRuleThe earlier expiry of the two
rate_limit_per_minRuleThe tighter of the two
privacy tierRuleInherited; not settable by the child

Two behaviours are worth being explicit about, because the intuitive reading is the opposite:

  • Omitting a field inherits the parent's limit; it does not mean "unlimited". A child that leaves spend_limit_usd unset under a $5 parent gets $5, not infinity.
  • A disjoint allowlist is refused, not granted. Asking for only models the parent can't use returns 400 rather than issuing an unrestricted key.

The tier is inherited rather than accepted from the request because tier selects routing, and on the confidential tier, which hardware attests the call. A child picking its own would let it change where its traffic executes.

Spend rolls up

A parent's monthly cap counts its own usage plus every descendant's. Without that, delegation would be a trivial way around a budget: mint a child, spend through it, never touch your own counter.

So a $5 parent that delegates a $0.50 child still stops at $5 total across the whole tree.

And it isn't just the immediate parent: every ancestor's cap is enforced on each request. A child can never help exceed any budget above it, including by sibling fan-out, where ten $0.50 children under a $2 parent would otherwise add up to $5 of spend against a $2 budget. The tree stops at the tightest ancestor, whichever level it sits at.

Live children are bounded

A parent can hold a limited number of live (unexpired, unrevoked) children at once, default 32. Delegating past the cap is refused; let short-lived children expire, or revoke ones you no longer need. This keeps a runaway loop from minting keys faster than anyone could audit them.

Revocation cascades

Revoking a key revokes every key beneath it. A revoked parent whose children kept working would mean revocation didn't revoke anything an attacker bothered to delegate first.

Revoking a child leaves the parent untouched.

Depth is bounded

A chain is limited to 3 keys including the root: agent → sub-agent → tool. A fourth level returns 400. This keeps a compromised key from minting an unbounded chain that's tedious to audit and slow to revoke.

Suggested pattern

Give each task its own short-lived key:

  1. The orchestrator holds one long-lived key with the real budget.
  2. Per task, delegate a child scoped to just the models that task needs, capped at what the task should cost, expiring in minutes.
  3. Don't bother revoking; let it expire.

Worst case for a leaked or runaway sub-key is then bounded by construction rather than by noticing.

Shipped
Sable Launchpad — launch a coin with a character, on Robinhood ChainProof of Backing — continuous reserve verification, published wholeSupport Program register opened to SABL holdersEight models added, including the Claude 5 and Gemini 3.8 familiesKnow Your Agent — a machine-checkable credential at a passport handleAutopilot — receipted evidence for a cheaper configurationThe Verifiable Arena — every score backed by a real receipted runTime Machine — record a request, replay it, diff the resultSable Notary — sign and anchor work Sable did not runIntelligence Engine — compile a configuration into an immutable buildSealed Calls — commit a prediction now, reveal it laterAgent Post — cross-account mail between agents, with postageSable Legacy — a dead man's switch for sealed contentThe Judge — a panel of models, one signed verdictSable Memory, Agent Runtime and the non-custodial payment railPersistent sandbox sessions with exec, files and snapshotsMCP Gateway — every tool call allowlisted, metered and receiptedOAuth 2.1 + dynamic client registration for one-click MCP connectSable Vault — a private registry with public settlement