SPIFFE: Can We Reconstruct What Happened? Audit and Investigation

A useful audit trail must reconstruct whose authority applied, which software acted, what was approved, and what actually changed. A single username field cannot represent that model.

Create a verified request-scoped identity

At authentication, construct an immutable context from validated claims or trusted introspection: subject with issuer, current actor, prior actor history, OAuth client, transport peer, delegation reference, token identifier, granted constraints, and policy version. Propagate it through authorization and business-event logging. Do not use a mutable global user context across concurrent requests or workers.

For delegated tokens, the outermost act identifies the current actor; nested actors represent earlier actors. Prior actors are informational rather than an additional permission source. Preserve history for traceability without authorizing from a union of actor privileges.

A proposed structured business event

{
"event": "case.update",
"identity_mode": "user_delegation",
"effective_subject": {
"issuer": "https://identity.example.org",
"id": "user:lisa"
},
"current_actor": {
"id": "spiffe://agents.example.org/agent/xyz"
},
"transport_peer": "spiffe://services.example.org/tool/case-editor",
"oauth_client_id": "agent-xyz-client",
"delegation_id": "approval-81a6",
"token_id": "token-4b781",
"request_id": "req-a740",
"agent_run_id": "run-93a2",
"resource": "case/4821",
"authorization": {
"decision": "allow",
"policy_version": "case-policy-17"
},
"outcome": "committed"
}

These field names are recommendations, not a standards-defined event schema. A run ID helps correlation but does not prove identity. A token ID helps join events but does not make a token single-use. One-time semantics require protected state and atomic consumption at the appropriate transaction boundary.

One approval, five API calls

Call Observed behavior Expected investigation conclusion
1 Read case/4821 under approved read authority Authorized read, if included in approval
2 Update status on case/4821 Authorized mutation and committed result
3 Update another field on case/4821 Denied field-level violation
4 Update case/9920 Denied resource mismatch
5 Repeat one-time status update Denied replay or recorded idempotent retry under policy

 

Join the approval event, STS decision, API decision, and business commit. A 200 response in an agent trace does not independently prove a database commit. An authorization allow does not prove the operation succeeded. Conversely, a failed response after a commit can cause a retry; the audit model must distinguish this from deliberate duplicate execution.

Background work and provenance

Queue messages should reference a protected grant and carry authenticated provenance. Re-evaluate permission when the worker executes. Record the originating agent and current worker separately, because the worker may become the current actor in a new token exchange. Preserve request and job correlation without trusting identity fields supplied by arbitrary producers.

Mark log fields by provenance: token-verified, authorization-service-issued, infrastructure-derived, or application-supplied. This prevents an agent-provided display name from being mistaken for the verified SPIFFE actor. Use stable identifiers for joins and display names only for presentation.

Logging controls

  • Never log bearer tokens, private keys, or full authorization headers.
  • Redact business payloads and approval details according to sensitivity.
  • Record denied attempts as well as successful operations.
  • Protect log transport, administrative access, and retention configuration.
  • Synchronize clocks and retain event time separately from ingestion time.
  • Version audit schemas and ensure downstream parsers preserve nested identity context.
  • Record configuration/policy changes so investigators can reconstruct the decision in force.

Takeaway: attribution becomes useful only when it survives all the way to the committed business event.

Leave a Reply

Your email address will not be published. Required fields are marked *