net-kingdom/canon/standards/audit-correlation_v0.1.md
tegwick f2956334bf
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
NK-WP-0055: correlation contract accepted; T13 break-glass findings in the backup docs
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
2026-10-27 22:44:22 +01:00

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.