You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add a mission log — an append-only, hash-chained activity trail where agents report what they actually did, scoped to a delegation chain. This bridges the gap between what ZeroID knows an agent was authorized to do (tokens, scopes, delegation chains) and what it actually did (actions, outcomes, resources accessed).
mission log entries could include the drm_hash and constraint_catalog_hash from the token that authorized the action, so a single log entry can be traced back to the policy version.
Background
What AAuth's mission log is
An ordered record of all agent↔Person Server interactions within a mission:
Entry type
Who creates it
When
Token requests
PS records automatically
Agent calls token_endpoint
Permission requests
PS records automatically
Agent calls permission_endpoint
Audit records
Agent reports
Agent calls audit_endpoint
Interaction requests
PS records automatically
Agent requests human interaction
Clarification exchanges
PS records automatically
During mission approval dialogue
The key design choice: the agent is a first-class contributor to its own audit trail. This has no equivalent in OAuth or in ZeroID today.
The AAuth spec intentionally leaves the log under-specified — no entry schema, no read API, no integrity mechanism.
What ZeroID already has
AAuth concept
ZeroID equivalent
Gap
Token request log
issued_credentials — every token with grant_type, delegation_depth, parent_jti
act chain + 3-way scope intersection on token_exchange
Exists
PS evaluation
OnClaimsIssue hook
Plumbing exists
Agent-reported actions
Nothing
Gap
Hash-chained integrity
Nothing
Gap
Design
Mission identifier = mission_id (populated by #81)
Mission ID = mission_id. A mission is the tree of tokens rooted at an orchestrator's initial credential. The mission_id claim and column introduced by #81 (expose and denormalize mission_id for delegation-chain audit queries) is the mission identifier — no parallel workflow_id, correlation_id, or root_jti is introduced. The codebase has exactly one name for this concept.
Do not invent a new UUID for mission identity, and do not interpret mission_id as a JTI at the consumer layer — it is opaque by contract (see #81). The underlying scheme (currently: the root credential's JTI) is an implementation detail that may evolve.
Endpoint
POST /oauth2/mission/log
Authorization: Bearer <agent-token>
CREATETABLEmission_log (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
mission_id VARCHAR(255) NOT NULL, -- mission identifier (see #81)
agent_jti VARCHAR(255) NOT NULL, -- which credential reported this
identity_id UUID REFERENCES identities(id) ON DELETESETNULL,
account_id VARCHAR(255) NOT NULL,
project_id VARCHAR(255) NOT NULL,
entry_type VARCHAR(50) NOT NULL, -- action, decision, error
action VARCHAR(255),
resource TEXT,
outcome VARCHAR(50),
detail JSONB,
sequence BIGINTNOT NULL, -- ordering within mission
prev_hash VARCHAR(64), -- SHA-256 of previous entry
entry_hash VARCHAR(64) NOT NULL, -- SHA-256 of this entry
created_at TIMESTAMPTZNOT NULL DEFAULT NOW()
);
CREATEINDEXidx_mission_log_mission_id_seqON mission_log (mission_id, sequence);
CREATEINDEXidx_mission_log_identityON mission_log (identity_id);
CREATEINDEXidx_mission_log_tenantON mission_log (account_id, project_id);
Read endpoint
GET /oauth2/mission/log?mission_id=<id>
Authorization: Bearer <agent-token>
Returns the ordered log for a delegation chain. Optionally filterable by identity_id, entry_type, action. Shape aligns with the #81 admin API (GET /credentials?mission_id=..., GET /signals?mission_id=...) so a single mission ID threads cleanly across mission log, credentials, and signals.
What this enables
1. Audit that answers "why" not just "what"
Today: agent B got a token with data:read scope delegated from agent A.
With mission log: agent B used that token to read 3 files, create a PR, and post a Slack message — and whether each action succeeded.
2. Policy decisions informed by history
The OnClaimsIssue hook (or a new OnTokenExchange hook) could receive the mission log as context. Example: "This sub-agent is requesting deploy:write scope, and the mission log shows 47 file reads and 0 test runs — deny until tests pass."
3. CAEP integration for trajectory drift
A monitoring layer reads the mission log, detects trajectory drift (many individually-authorized actions that collectively diverge from intent), and pushes a policy_violation CAEP signal back into ZeroID to revoke the chain. This closes the gap identified — runtime alignment monitoring that feeds back into the auth layer.
4. Tamper-evident compliance
The hash chain means any modification to a log entry invalidates all subsequent hashes. For EU AI Act traceability or SOC2 audit: cryptographic proof the log is intact, not just "here's what we logged."
Minimal implementation: one migration, one domain model, one repo, one handler endpoint (POST + GET), and a hash function. Composes with existing infrastructure rather than replacing any of it.
Summary
Add a mission log — an append-only, hash-chained activity trail where agents report what they actually did, scoped to a delegation chain. This bridges the gap between what ZeroID knows an agent was authorized to do (tokens, scopes, delegation chains) and what it actually did (actions, outcomes, resources accessed).
Inspired by the mission log concept in draft-hardt-aauth-protocol and Karl McGuinness's analysis of its governance gaps. This proposal adapts the concept to ZeroID's existing architecture.
mission log entries could include the
drm_hashandconstraint_catalog_hashfrom the token that authorized the action, so a single log entry can be traced back to the policy version.Background
What AAuth's mission log is
An ordered record of all agent↔Person Server interactions within a mission:
token_endpointpermission_endpointaudit_endpointThe key design choice: the agent is a first-class contributor to its own audit trail. This has no equivalent in OAuth or in ZeroID today.
The AAuth spec intentionally leaves the log under-specified — no entry schema, no read API, no integrity mechanism.
What ZeroID already has
issued_credentials— every token with grant_type, delegation_depth, parent_jticae_signals— signal_type, severity, payload, identity_idactchain + 3-way scope intersection on token_exchangeOnClaimsIssuehookDesign
Mission identifier =
mission_id(populated by #81)Mission ID =
mission_id. A mission is the tree of tokens rooted at an orchestrator's initial credential. Themission_idclaim and column introduced by #81 (expose and denormalizemission_idfor delegation-chain audit queries) is the mission identifier — no parallelworkflow_id,correlation_id, orroot_jtiis introduced. The codebase has exactly one name for this concept.Do not invent a new UUID for mission identity, and do not interpret
mission_idas a JTI at the consumer layer — it is opaque by contract (see #81). The underlying scheme (currently: the root credential's JTI) is an implementation detail that may evolve.Endpoint
{ "action": "tool:execute", "resource": "github.com/api/repos/org/repo/pulls", "outcome": "success", "detail": {"tool": "create_pull_request", "pr_number": 42} }The server:
mission_idfrom the bearer token (claim populated by feat: expose and denormalize mission_id for delegation-chain audit queries #81 — no chain walking required)entry_hash = SHA-256(prev_hash || entry_type || action || resource || outcome || detail || sequence || timestamp)Schema
Read endpoint
Returns the ordered log for a delegation chain. Optionally filterable by
identity_id,entry_type,action. Shape aligns with the #81 admin API (GET /credentials?mission_id=...,GET /signals?mission_id=...) so a single mission ID threads cleanly across mission log, credentials, and signals.What this enables
1. Audit that answers "why" not just "what"
Today: agent B got a token with
data:readscope delegated from agent A.With mission log: agent B used that token to read 3 files, create a PR, and post a Slack message — and whether each action succeeded.
2. Policy decisions informed by history
The
OnClaimsIssuehook (or a newOnTokenExchangehook) could receive the mission log as context. Example: "This sub-agent is requestingdeploy:writescope, and the mission log shows 47 file reads and 0 test runs — deny until tests pass."3. CAEP integration for trajectory drift
A monitoring layer reads the mission log, detects trajectory drift (many individually-authorized actions that collectively diverge from intent), and pushes a
policy_violationCAEP signal back into ZeroID to revoke the chain. This closes the gap identified — runtime alignment monitoring that feeds back into the auth layer.4. Tamper-evident compliance
The hash chain means any modification to a log entry invalidates all subsequent hashes. For EU AI Act traceability or SOC2 audit: cryptographic proof the log is intact, not just "here's what we logged."
What this does NOT require
mission_id)mission_idis THE mission identifierDependencies
mission_id) is a prerequisite. This issue consumes themission_idclaim and column that feat: expose and denormalize mission_id for delegation-chain audit queries #81 introduces. Without feat: expose and denormalize mission_id for delegation-chain audit queries #81, this issue would have to walkparent_jtichains on every mission log write and read — operationally worse and semantically identical.Scope
Minimal implementation: one migration, one domain model, one repo, one handler endpoint (POST + GET), and a hash function. Composes with existing infrastructure rather than replacing any of it.
References