Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: opus Assistant-Process: 4515@bnt-lap001 Assistant-Session: 0bf96127-6e04-41be-bfda-d11717c3f354
86 lines
4 KiB
Markdown
86 lines
4 KiB
Markdown
---
|
|
id: NK-STD-AUDIT-CORRELATION
|
|
title: "Audit Correlation Contract"
|
|
version: "0.1"
|
|
status: accepted
|
|
owner: net-kingdom
|
|
created: "2026-10-27"
|
|
work: NK-WP-0055-T11
|
|
---
|
|
|
|
# Audit Correlation Contract v0.1
|
|
|
|
## Purpose
|
|
|
|
This contract defines one correlation id that links the audit records of a single unit of work across all of these:
|
|
|
|
- identity issuance;
|
|
- the authorization decision;
|
|
- secret access;
|
|
- workload enforcement.
|
|
|
|
Without it, the architecture's onboarding audit-readiness step (`docs/platform-identity-security-architecture.md`, step 7)
|
|
cannot be tested.
|
|
|
|
Owners:
|
|
|
|
- **NetKingdom** owns this contract.
|
|
- **audit-core** owns the `correlation_id` envelope field (AUDIT-WP-0017-T05).
|
|
- **Each emitting service** owns its own propagation.
|
|
|
|
## Rules
|
|
|
|
**AC-1. Format.** `correlation_id` is the 32-character lowercase hex trace id of
|
|
[W3C Trace Context](https://www.w3.org/TR/trace-context/). An all-zero id is invalid. The value is opaque and carries no
|
|
personal data, tenant name or secret. Receivers may store other ids of up to 128 characters, but those do not satisfy this
|
|
contract.
|
|
|
|
**AC-2. Transport.** On HTTP, the id travels in the standard `traceparent` header. The `correlation_id` is the trace-id
|
|
part of that header. There is no custom header. For non-HTTP calls (LDAP, internal queues), the emitting service records
|
|
the id it received on its inbound HTTP leg.
|
|
|
|
**AC-3. Not a token claim.** The id is never placed in an access token, ID token or other credential. A token outlives a
|
|
unit of work, so a claim would wrongly link unrelated requests.
|
|
|
|
**AC-4. Who sets it.**
|
|
|
|
- The **originator of the unit of work** sets the id: the workload or the user-facing application, at the start of the
|
|
request it is serving.
|
|
- Every downstream component copies the inbound id unchanged into its audit record and into its own outbound calls.
|
|
- A component that receives no valid `traceparent` starts a new trace. It records that fact as
|
|
`correlation_origin: generated`; propagated ids are recorded as `correlation_origin: propagated`.
|
|
- `parent_event_id` is optional, and is used only when one record directly causes another.
|
|
|
|
**AC-5. Trust.** The id is a claim made by the caller and nothing more:
|
|
|
|
- It never influences an authentication, authorization or secret decision.
|
|
- It is not evidence of who acted. The record's authenticated subject is that evidence.
|
|
- Where a decision record is signed (access-engine FLEX-WP-0024), the signature covers the id, so the record cannot be
|
|
relinked afterwards.
|
|
|
|
**AC-6. Per emitter.**
|
|
|
|
| Emitter | Where it reads the id | Owner task |
|
|
|---|---|---|
|
|
| Workload / application | Generates the id, or takes it from its own inbound request | each workload owner |
|
|
| KeyCape | Inbound `traceparent` on the token and authorize endpoints | key-cape (via NK-WP-0055-T11) |
|
|
| access-engine | Inbound `traceparent` on the check APIs; copied into the decision record | FLEX-WP-0031-T11 |
|
|
| OpenBao | Audits the `traceparent` request header in plain text via `sys/config/auditing/request-headers` (`hmac: false`) and maps it on shipping | RPF-WP-0066-T02 |
|
|
| Authelia, LLDAP, privacyIDEA | Inbound `traceparent` where the service exposes it; otherwise `correlation_origin: generated` | NK-WP-0055-T11 identity intake |
|
|
| Kubernetes API audit | Not part of the chain. It keeps its own `auditID`, and k3s does not carry the id | RCLUSTER-WP-0021 |
|
|
|
|
**AC-7. End-to-end test.** The tenant onboarding completion test (NK-WP-0055-T12) passes only when a single
|
|
`correlation_id` set by a test workload can be found in audit-core in all of these records:
|
|
|
|
- the KeyCape issuance record;
|
|
- the access-engine decision record;
|
|
- the OpenBao audit record;
|
|
- the workload enforcement record.
|
|
|
|
The test uses synthetic subjects only.
|
|
|
|
## Open for owners
|
|
|
|
- audit-core: confirm the `correlation_origin` field name and the validation for the new sources (AUDIT-WP-0017-T05).
|
|
- railiance-platform: confirm that the OpenBao version in use supports audited request headers (RPF-WP-0066-T01).
|
|
- key-cape: accept the propagation task.
|