Repository navigation
audit: preserve complete delegation lineage alongside OAuth actor history #342
Description
Problem
For a delegated operation, identifying the final actor is not enough. An investigator needs the complete path from the initiating principal through the delegating actors to the actor that performed the operation, including which evidence supports each relationship.
The audit package already supports RFC 8693 act chains, preserves issuer/subject pairs, marks malformed or truncated input, and avoids serializing extra claims. That is useful existing functionality, not something to replace.
However, an OAuth actor-history chain is not necessarily the application's delegation history. A reused agent, workflow, or service instance can have a creation parent that differs from the party delegating its current work. A bounded token-chain projection also cannot by itself preserve the full application lineage.
Existing implementation: https://github.com/stacklok/toolhive-core/blob/5ba2b36edf8051b47bab103aad93223cb3dcd0b3/audit/delegation.go
Requested enhancement
Define a generic, additive convention for retaining and following full delegation evidence using the existing audit event model. It should support:
- Qualified principal/actor identities, stable instance identifiers where relevant, and explicit parent/child delegation relationships tied to the operation or execution being investigated.
- A distinction between current execution delegation, creation ancestry, and OAuth actor history. Do not reinterpret
DelegationChainor infer missing relationships from names, depth, token nesting, or SPIFFE path text. - Evidence provenance for each relationship: which component established or reported it, and what was independently verified. A signature authenticates an assertion; it does not independently prove an application's internal state.
- Reconstruction of the complete recorded chain from any operation. Either embed the bounded complete evidence or use integrity-protected references to retained, access-controlled lineage records in the audit dataset. References must remain resolvable for the relevant audit-retention period and must not depend on mutable live session state.
- Explicit completeness/gap reporting for unresolved references, truncation, malformed relationships, conflicting parents where the selected relationship model forbids them, and cycles. Never label an incomplete chain complete.
Keep the current token-parser depth and data-minimization protections. Do not remove bounds or start serializing all token claims to satisfy completeness. Prefer a documented profile and small reusable helpers over a new graph database or service in this library. Start with a simple parent-linked chain; broader multi-parent models need not be invented here.
Acceptance criteria
- An example and tests reconstruct an initiating principal -> service/agent -> delegated child -> specialist operation, with every hop's identity and provenance retained.
- Two instances using the same definition beneath different parents remain distinguishable.
- Reusing an instance for a later delegation does not silently reuse the earlier execution's parent relationship.
- Evidence remains reconstructable after restart or deletion of transient execution state when the consumer retains the required audit records.
- Missing/truncated/malformed evidence is visibly incomplete; cycle and invalid-reference handling is bounded.
- Existing RFC 8693 chain ordering, malformed/truncation markers, and exclusion of extra claims remain unchanged in JSON and slog output.
Scope
This is generic audit evidence, not a new authorization or consent system. The consumer owns trusted relationship capture, storage, retention, and policy enforcement. The package should define how interoperable records preserve the evidence, without claiming that a chain itself grants authority or proves non-repudiation.
This supports investigative attribution under NIST SP 800-53 AU-3 and AU-6; it does not require implementing every AU control: https://csrc.nist.gov/pubs/sp/800/53/r5/upd1/final
Motivating discussion: stacklok/mecatl#2121
Activity