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
83 lines
3.3 KiB
Markdown
83 lines
3.3 KiB
Markdown
---
|
|
id: KEY-WP-0044
|
|
type: workplan
|
|
title: "Audit correlation (traceparent) and audit-core intake for KeyCape"
|
|
domain: infotech
|
|
repo: key-cape
|
|
status: proposed
|
|
owner: claude-code
|
|
topic_slug: custodian
|
|
created: "2026-10-27"
|
|
updated: "2026-10-27"
|
|
flavor: extension
|
|
depends_on: []
|
|
state_hub_workstream_id: "7d8c5e7a-0291-58eb-a1cb-284d663468aa"
|
|
---
|
|
|
|
Accepted from net-kingdom NK-WP-0055-T11 under the NetKingdom Audit Correlation
|
|
Contract (`net-kingdom/canon/standards/audit-correlation_v0.1.md`, AC-1 to AC-7).
|
|
KeyCape's intake package for audit-core AUDIT-WP-0017-T04 is
|
|
`docs/audit-core-sender-package.md`. Nothing here registers a sender, mints a
|
|
credential or changes a live deployment; activation stays owner-run.
|
|
|
|
## Read inbound traceparent and record correlation_id
|
|
|
|
```task
|
|
id: KEY-WP-0044-T01
|
|
status: todo
|
|
priority: high
|
|
state_hub_task_id: "f059548e-f6eb-57a9-8ad2-9c7bcf2da2dc"
|
|
```
|
|
|
|
On `/authorize` (including the login, MFA and handoff legs of the same flow)
|
|
and `/token` (all grants), parse the inbound W3C `traceparent` header. If it is
|
|
valid (version 00, 32 lowercase hex trace-id, not all zeros, valid parent-id),
|
|
record its trace-id as `correlation_id` with `correlation_origin: propagated`;
|
|
otherwise generate a fresh random trace-id and record `correlation_origin:
|
|
generated`. Carry the value through the request context into every
|
|
`telemetry.Event` (today `TraceID` is always empty) and add a
|
|
`CorrelationOrigin` field. For the authorize flow, keep the id from the first
|
|
`/authorize` request on the login session so the success/failure record for
|
|
that flow carries it; `/token` uses its own inbound header.
|
|
|
|
Rules (AC-3, AC-5): the id is never placed in an access token, ID token,
|
|
refresh token, authorization code or userinfo response; it never influences an
|
|
authentication, authorization or token decision; a malformed header is ignored,
|
|
never an error. Outbound calls KeyCape makes while serving the request
|
|
(Authelia, LLDAP, privacyIDEA) send a `traceparent` with the same trace-id.
|
|
|
|
Tests: propagated, absent, malformed and all-zero headers; a decoded token from
|
|
each grant carries no trace id; the token/authorize response is identical with
|
|
and without the header.
|
|
|
|
## Emit audit-grade records for every issuance and refusal
|
|
|
|
```task
|
|
id: KEY-WP-0044-T02
|
|
status: todo
|
|
priority: high
|
|
state_hub_task_id: "b126f10a-d301-5512-8447-d1131608e4b5"
|
|
```
|
|
|
|
Close the gaps the intake package lists: emit on `/token` failures
|
|
(`invalid_client`, `invalid_grant`, `unauthorized_client`, `invalid_scope`),
|
|
on revoke and introspection, and on denied scope/tenant/principal-type
|
|
preconditions; add `sub`/`uid`, `tenant` and `principal_type` to
|
|
`token_issued`; add a stable `event_id` (UUIDv7 minted once per event, reused on
|
|
retry); set `environment` on every event. No secret, token, code, password,
|
|
OTP or email on any event.
|
|
|
|
## Forward to audit-core (after admission)
|
|
|
|
```task
|
|
id: KEY-WP-0044-T03
|
|
status: wait
|
|
priority: medium
|
|
state_hub_task_id: "721254d8-6b50-575c-9715-feaf2ef7e414"
|
|
```
|
|
|
|
Waits on audit-core admitting `netkingdom.keycape` (AUDIT-WP-0017-T04) and on
|
|
AUDIT-WP-0017-T05 confirming `correlation_origin`. Implement the envelope
|
|
mapping from the intake package (log-tail collector or direct POST, owner's
|
|
choice), heartbeat, and fixture tests against audit-core's receiver. Sender
|
|
credential is read from an OpenBao-delivered Secret; activation is owner-run.
|