Run Tokens¶
Workloads — agent runs, agents, planner sessions and Ballet services — authenticate with short-lived run tokens issued by Core (ADR-0006: OIDC Claims-Based RBAC for Humans, Scoped Run Tokens for Agents). Humans never use run tokens.
Format¶
JWT signed with Ed25519 (alg: EdDSA), kid header naming the
signing key, iss: "ballet-core".
Claim |
Meaning |
|---|---|
|
Workload: |
|
Services that accept the token: |
|
Expiry, issue time, unique id |
|
|
|
Organization and project scope (required for |
|
Ticket (required for |
|
Planner session (required for |
|
Human a planner acts for (RFC 8693 actor claim; required for
|
|
Capabilities, see below |
Capabilities¶
Capability |
Grants |
|---|---|
|
Read the token’s own ticket and plan context |
|
Report progress, stage reports, questions, assumptions, proposals |
|
Search and read the organization’s knowledge |
|
Create and update knowledge entries |
|
Call the LLM gateway |
|
Connect an agent to Core |
|
(gateway) Read LLM credentials from Core |
|
(gateway) Report LLM usage to Core |
|
Compute embeddings through the gateway |
A service accepts a token only if its own name is in aud, and checks
both the scope (cust/proj/tkt) and the capability for every
operation.
Service tokens¶
Ballet’s own services authenticate to each other with kind: service
tokens that Core issues at startup and re-issues every quarter of their
lifetime ([services] token_ttl, default 30 days). Core writes one file
per service into [services] tokens_dir (mode 0600):
File |
Subject |
Audience |
Capabilities |
|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
Services read their file with runtoken.FileSource (re-read when it
changes). In a single-host installation the directory is shared with the
services; elsewhere it must be distributed as a secret.
Core’s internal API (/internal/v1/) accepts only service tokens
and checks a capability per endpoint; GET /internal/v1/whoami
returns the caller’s subject and capabilities.
Keys and verification¶
Core keeps its signing keys in the file set by [tokens] (core) (created on first start, mode
0600). Back it up with the Core database; losing it invalidates all running sessions’ tokens.Public keys are published, unauthenticated, at
GET /.well-known/jwks.jsonon Core.Other services verify with
kit/auth/runtoken.NewRemoteVerifier: keys are fetched lazily, cached, and refetched when a token names an unknown key (throttled for repeated unknown keys).Rotation makes a new key active while the previous key keeps verifying for a retirement period that must exceed the longest token lifetime.
Clock skew of up to 30 seconds is tolerated.