Run Authorization and Capability Tokens
Authorize one immutable deployment before execution, keep broad credentials out of the runtime, and issue short-lived proof for exactly one downstream action.
The enterprise problem and today’s slice
Enterprise problem: Starting an agent from a valid session and giving its runtime reusable connector tokens turns one stale membership, prompt injection, or compromised dependency into broad and persistent enterprise access.
Whole-course context: Day 01 produced durable agents, immutable version digests, team-specific deployments and capability bindings, public-safe visibility, and release evidence; today consumes those exact IDs and snapshots at run admission.
Today’s slice: We authorize a run, issue audience-bound admission and delegation tokens, require workload identity as a second key, broker one action-bound capability token, and bound revocation freshness across provider, hosted-runtime, and connector boundaries.
End-of-day evidence: A reviewer receives an allowed run, a denied cross-team run, a two-key runtime proof, a single-use capability replay denial, and a mid-run revocation result with complete actor/resource/scope/precondition/observed evidence.
Still unsolved: Connector discovery, detailed tool and argument policy, human approval, Model Context Protocol (MCP) mediation, agent-to-agent delegation, source data trimming, and production infrastructure are deliberately deferred.
Customer use cases
If a run starts before the platform checks current user, team, deployment, version, and risk state, expensive execution begins with ambiguous authority and later services cannot tell what was actually admitted.
| Use case ID | Actor | Customer job | Success outcome | Denial or recovery evidence |
|---|---|---|---|---|
| D06-UC-01 | Team agent operator | Start one approved deployment under one explicit team | Control plane evaluates current organization, user, membership, agent.run, deployment, immutable version, model availability, and risk policy before allocating runtime | Cross-team, inactive, unapproved, unavailable-model, or missing-permission requests deny before runtime allocation and retain a decision ID |
| D06-UC-02 | Runtime security operator | Admit only the intended workload carrying the intended human delegation | Runtime entry requires both an attested workload identity and short-lived run authority bound to organization, team, subject, version, deployment, run, membership version, issuer, and audience | Stolen run authority from an untrusted workload and trusted workload without valid delegation both deny; no connector credential reaches runtime |
| D06-UC-03 | Agent runner and connector adapter | Execute one already-authorized action without giving the model reusable authority | Tool gateway mints an audience-, tool-, resource-, argument-, decision-, and lifetime-bound capability token; adapter verifies it before retrieving external credential | Changed arguments, wrong adapter, expired token, replay, foreign connector, or undeclared tool denies while a fresh valid action remains allowed |
| D06-UC-04 | Security administrator | Revoke user, deployment, connector, tool, or approval during a long run | Low-risk reads use bounded freshness; high-risk writes revalidate immediately; revocation event cancels or blocks the next privileged action | Post-revocation action denies within objective, caches show invalidation, and an unrelated subject or deployment remains a positive control |
Run admission uses an intersection:
CanRunAgent(user, team, deployment) =
organization is active
AND user is active
AND user belongs to organization
AND current user membership includes selected team
AND deployment targets selected team
AND deployment is active
AND user has agent.run for this agent
AND immutable version is approved
AND required model is available to this team
AND session and risk policy permit this run
The result is not general tool authority. It means only that this subject may execute this immutable deployment under this team for a bounded period.
Actor-centred user stories
When an “allowed” result omits the facts and version that produced it, operators cannot reproduce a decision or know when it became stale, so incident response degenerates into guesswork.
| Story ID | Use case IDs | User story | Observable acceptance conditions |
|---|---|---|---|
| D06-US-01 | D06-UC-01 | As a team agent operator, I want run permission checked before runtime allocation, so that a denied request incurs no model cost and cannot enter another team's deployment | Marketing member starts Marketing v17; the same user targeting Finance receives deployment_not_available_to_team; evidence names membership, grant, policy, model, deployment, and decision revisions |
| D06-US-02 | D06-UC-02 | As a runtime security operator, I want workload identity and human delegation checked as two independent keys, so that stealing either one is insufficient | Attested runtime plus current run delegation admits; token from an untrusted workload denies; trusted workload without delegation denies; runtime secret inventory contains no downstream credential |
| D06-US-03 | D06-UC-03 | As a responsible agent runner, I want each approved side effect represented by a single-use capability token, so that a model or compromised runtime cannot widen or replay it | Adapter accepts exact Slack channel and argument digest once; changed channel, changed body, wrong adapter, and second presentation deny with distinct decision reasons |
| D06-US-04 | D06-UC-04 | As a security administrator, I want revocation to interrupt long-running authority, so that removing membership or disabling a deployment is effective before the next consequential action | Revocation increments version, publishes event, evicts cache, cancels eligible runs, and makes the next high-risk write deny while independent positive control stays healthy |
The runtime should hold only a short-lived run context, immutable workflow, approved visible tool catalogue, and workload credential used for mutual authentication. It must not hold every team's API keys, connector refresh tokens, or permission to choose any tool.
Agent runtime
run-scoped delegation
immutable workflow
filtered tool catalogue
no downstream credentials
Tool gateway
current authorization facts
credential broker interface
argument and risk policy
approval state
immutable audit writer
A model output is an untrusted proposal:
{
"tool": "slack.post_message",
"arguments": {
"channel_id": "C_CAMPAIGN_OPS",
"text": "The autumn campaign draft is ready for review."
}
}
It has no authority until an independent policy decision binds that exact operation and canonicalized argument digest.
End-to-end product flows
Bearer tokens become confused deputies when they are reusable across services or operations, so each flow narrows audience and purpose as authority moves closer to the side effect.
| Flow ID | Use case IDs | Path | Trigger | Numbered steps | Terminal evidence |
|---|---|---|---|---|---|
| D06-FLOW-01 | D06-UC-01 | Happy | Marketing operator clicks “Run” on deploy_marketing_prod | 1. Submit selected team, deployment, and input.<br>2. Resolve active organization and user.<br>3. Load current team membership and explicit agent.run grant.<br>4. Verify deployment targets team, version approval, model availability, session strength, and risk policy.<br>5. Persist decision and allocate run only after allow. | Evidence records operator, deployment resource, agent.run scope, all fact preconditions, expected admission, observed run ID, environment, timestamp, policy and membership versions, version digest, and immutable decision ID |
| D06-FLOW-02 | D06-UC-02 | Denied | A copied run-admission token is presented by an untrusted workload | 1. Validate issuer, signature, audience, expiry, subject, team, deployment, version, run, and decision.<br>2. Verify runtime workload attestation and service audience.<br>3. Compare workload to deployment environment.<br>4. Deny on mismatch before execution.<br>5. Admit the intended workload with a fresh token as positive control. | Evidence records presenting workload, run resource, delegation scope, precondition token copied, expected deny, observed workload_binding_mismatch, positive-control result, environment, timestamp, attestation ID, and immutable runtime-admission decision ID |
| D06-FLOW-03 | D06-UC-03 | Denied | Runtime proposes an approved Slack post, then replays its capability token with a changed channel | 1. Send proposal plus run delegation over mutually authenticated channel.<br>2. Gateway revalidates current run, deployment, tool, connector, argument, risk, and approval facts.<br>3. Canonicalize arguments and persist tool decision.<br>4. Mint single-use capability for exact adapter, connector, resource, and digest.<br>5. Adapter accepts original once, then rejects changed-channel replay.<br>6. Fresh allowed action succeeds as positive control. | Evidence records initiating user and acting agent, Slack channel resource, slack.post_message scope, original and changed argument digests, expected one allow then replay deny, observed provider request IDs, environment, timestamp, tool decision, and immutable trace ID |
| D06-FLOW-04 | D06-UC-04 | Recovery | Administrator removes the operator from Marketing during a long run | 1. Membership Service increments version and records revoke.<br>2. Revocation stream evicts authorization caches and signals active runs.<br>3. Runtime reaches next high-risk action.<br>4. Gateway reloads current membership and denies.<br>5. Cancel run or continue only non-privileged cleanup by policy.<br>6. Probe an unaffected operator as positive control. | Evidence records administrator and revoked subject, membership and pending-action resources, scopes, precondition run active, expected privileged deny, observed cancellation or bounded cleanup, unaffected result, environment, timestamp, revocation-event and run IDs |
Audience separation prevents token reuse. One secure pattern is:
- Control plane issues a one-time runtime-admission token with audience
agent-runtime. - The attested runtime exchanges it for a run delegation with audience
tool-gatewayand no direct downstream scope. - After a per-action allow, the gateway issues a capability with audience
connector-adapter:slack. - The adapter verifies token and workload channel, consumes nonce once, then obtains the real external credential through the broker.
An illustrative run delegation carries bounded context:
{
"iss": "https://authorization.platform.example",
"aud": "tool-gateway",
"sub": "user_8472",
"org": "org_acme",
"team": "team_marketing",
"agent_id": "agent_campaign_launch",
"agent_version": "version_17",
"deployment_id": "deploy_marketing_prod",
"run_id": "run_01K1HZH8",
"membership_version": 39182,
"decision_id": "decision_run_f781",
"iat": 1785527300,
"exp": 1785527600
}
The per-action capability is narrower:
{
"iss": "https://authorization.platform.example",
"aud": "connector-adapter:slack",
"sub": "user_8472",
"act": {"sub": "agent_campaign_launch", "version": "17"},
"org": "org_acme",
"team": "team_marketing",
"connector_instance": "connector_slack_marketing",
"tool": "slack.post_message",
"resource_constraints": {"channel_id": "C_CAMPAIGN_OPS"},
"argument_digest": "sha256:7814...",
"nonce": "cap_nonce_4d91",
"single_use": true,
"decision_id": "decision_tool_91d8",
"iat": 1785527390,
"exp": 1785527450
}
System design derived from the flows
A runtime that can read the credential vault or mint its own capabilities can bypass every higher-level policy, so token creation, credential retrieval, and execution must reside in separately authenticated services.
| Use case ID | Entry point | Responsible services | Authoritative store | Failure evidence |
|---|---|---|---|---|
| D06-UC-01 | POST /agent-runs from selected deployment page | Run Authorization Service loads current subject and membership; Grant Service checks agent.run; Deployment and Version Services validate target and digest; Model and Risk Policy Services evaluate availability | Run Decision Store owned by Authorization Service; current facts stay authoritative in Membership, Grant, Deployment, Version, Model Policy, and Risk Policy stores | organization_inactive, subject_inactive, not_current_team_member, missing_agent_run_permission, deployment_not_available_to_team, version_unapproved, or model_not_available, with decision ID |
| D06-UC-02 | Runtime admission and delegation exchange | Token Service signs audience-bound admission; Workload Identity Service verifies attestation; Runtime Admission Service checks deployment/environment binding; Delegation Service issues tool-gateway audience | Workload Trust Store owned by Runtime Identity; token signing keys owned by Authorization Service; Run Store owned by Run Orchestrator | invalid_token_audience, untrusted_workload, workload_binding_mismatch, admission_replayed, or run_not_active, with attestation and admission decision IDs |
| D06-UC-03 | Tool Gateway action-intent endpoint and connector adapter | Tool Gateway loads current run and action facts; Argument Canonicalizer computes digest; Capability Issuer signs narrow token; Adapter Verifier consumes nonce; Credential Broker alone retrieves downstream credential | Tool Decision and Capability Consumption stores owned by Tool Gateway; secret material owned by Vault; downstream provider owns final resource ACL and request log | tool_not_declared, argument_outside_scope, wrong_capability_audience, argument_digest_mismatch, capability_replayed, or downstream deny, with tool decision and provider request IDs |
| D06-UC-04 | Membership/deployment/connector administration and revocation stream | Owning service increments resource version; Revocation Bus publishes event; Cache Coordinator invalidates facts; Run Supervisor cancels or flags active run; Tool Gateway revalidates consequential action | Source grant store owned by revoking service; Revocation Event Store owned by Security Operations; Run State Store owned by Run Orchestrator | authorization_stale, membership_revoked, deployment_disabled, connector_revoked, approval_withdrawn, or missed freshness objective, with event and run IDs |
The two-key rule requires both valid workload identity and valid delegated run authority. Workload identity proves which hosted service is calling; run delegation proves which current user, team, agent, version, deployment, and run authorized the work. Neither key grants access alone.
Revocation freshness depends on risk. Low-risk reads may use a short token and bounded, versioned cache. High-risk writes reload current membership, deployment, connector, approval, and downstream token immediately before execution. The product states measurable objectives for propagation and records when they are missed.
Data model and ownership
If token claims are the only durable record, expiry erases the reason an action was allowed and revocation cannot find active authority, leaving the customer unable to investigate or contain a run.
Generated-application database: Not created in this slice — run admission, workload binding, capability consumption, revocation, and evidence are durable provider/runtime records; generated-app tenants and domain authorization remain owned by the application introduced in Day 02.
| Record or entity | Store and owner | Primary key | Foreign key or opaque reference | Tenant key | Material constraint | Lifecycle and deletion | Use case IDs |
|---|---|---|---|---|---|---|---|
| RunAuthorizationDecision | Run Decision Store; Authorization Service | run_decision_id | Opaque references to session, subject, membership version, agent grant, deployment, version digest, model policy, and risk policy | organization_id | Immutable full conjunct result; allow is bound to one selected team and deployment; deny also persisted | Created before allocation; sealed; retained by audit policy; archived or deleted after legal-hold checks | D06-UC-01 |
| AgentRun | Run State Store; Run Orchestrator | run_id | Opaque references to RunAuthorizationDecision, deployment, version, runtime environment, and initiating subject | organization_id plus team_id | State machine prevents execution before allow; exact version and deployment immutable for run | Admitted, running, cancelling, completed, failed, or revoked; payload deleted by data policy while minimal evidence remains | D06-UC-01, D06-UC-02, D06-UC-04 |
| WorkloadAttestation | Workload Trust Store; Runtime Identity Service | attestation_id | Opaque workload, deployment, environment, issuer, and key references | organization_id | Short-lived, issuer- and audience-validated, bound to approved workload; never substitutes for human delegation | Issued and rotated automatically; expires quickly; security metadata retained with run evidence | D06-UC-02 |
| TokenGrant | Token Metadata Store; Authorization Service | token_grant_id | Opaque references to run decision, run, workload attestation, signing-key version, and parent grant | organization_id plus team_id | Audience and purpose can only narrow across exchange; expiry cannot exceed parent; token value is never stored | Metadata created on mint; token expires quickly; grant revoked with parent; metadata retained for traceability | D06-UC-02, D06-UC-03 |
| ToolDecision | Tool Decision Store; Tool Gateway | tool_decision_id | Opaque references to run, deployment binding, connector, tool policy, approval, credential binding, and downstream principal | organization_id plus team_id | Exact canonical arguments and digest, resource constraints, actor and agent, expected outcome, and policy revisions immutable | Created for allow and deny; sealed before capability mint; retained with provider request trace, then archived | D06-UC-03, D06-UC-04 |
| CapabilityGrant | Capability Store; Tool Gateway | capability_grant_id | Local ToolDecision reference; opaque adapter, connector, resource, nonce, and signing-key references | organization_id plus team_id | Audience-, operation-, resource-, argument-, decision-, lifetime-bound; optionally single-use; never broader than decision | Minted only after allow; expires in seconds; revoked with parent; metadata retained through audit window | D06-UC-03 |
| CapabilityConsumption | Capability Store; Adapter Verifier | capability_nonce | Local CapabilityGrant reference; opaque workload attestation and downstream request references | organization_id plus team_id | Atomic first-consumer wins; digest and audience must match; replay records deny without repeating side effect | Created on first presentation; immutable; retained for replay investigation; archived or deleted under policy | D06-UC-03 |
| RevocationEvent | Append-only Revocation Store; Security Operations | revocation_event_id | Opaque target reference to membership, grant, deployment, connector, tool, approval, token grant, or run | organization_id plus optional team_id | Monotonic target version, idempotency key, occurred time, received time, and propagation status mandatory | Appended by owner action; never rewritten; retained to prove freshness objective; later archived or deleted | D06-UC-04 |
| RunAndCapabilityEvidence | Append-only Audit Store; Audit Service | evidence_id | Opaque references to run, decisions, token grants, attestations, capability consumption, revocation, and provider request | organization_id plus team_id | Actor, resource, scope, precondition, expected, observed, environment, timestamp, and immutable identifiers mandatory | Appended throughout run; sealed at terminal state; exportable; legal-hold aware retention and deletion | D06-UC-01, D06-UC-02, D06-UC-03, D06-UC-04 |
The retention split is deliberate: secret token values disappear at expiry, while hashes, nonces, policy versions, subject/resource references, and observed outcomes remain long enough to prove what happened. Retaining the bearer credential itself would enlarge breach impact without improving audit.