Read the audit trail
Filter the immutable event stream down to one credential's biography and one operator's actions.
Everything the previous scenarios did left events. This scenario reads them back the way an investigation would: by credential, by actor, by type, by time.
Goal
Reconstruct one credential's history and isolate one operator's actions using audit filters.
Prerequisites
- An admin entry:
provider_admintoken on/v1/admin/audit-events, or an admin-scoped service token on/internal/v1/admin/audit-events— the trail is the same. - Activity from earlier scenarios (creates, a rotation, a reveal).
Steps
1. One credential's biography
curl -s "$CREDS_BASE/internal/v1/admin/audit-events?credential_id=$CRED_ID" \
-H "Authorization: Bearer $ADMIN_TOKEN" -H "X-Admin-Actor: panel:olha"
Expected 200, newest first: credential.created, then credential.updated (metadata lists the changed field names — e.g. ["credentials"] after a rotation), credential.default_changed, and so on. No secret values anywhere in metadata.
2. One operator's actions
Filter by the attributed actor:
events = httpx.get(
f"{CREDS_BASE}/internal/v1/admin/audit-events",
params={"actor_id": f"service:{CLIENT_ID}!panel:olha"},
headers=admin_headers,
).json()
assert all(e["actor_id"].endswith("panel:olha") for e in events["items"])
Expected: exactly the calls made under that X-Admin-Actor label — the attribution from scenario 07 paying off.
3. The resolve history
Filter event_type=credential.resolved (and its sibling credential.resolve_failed). Expected: one event per resolve, carrying credential_source, target_user_id, and your correlation_id — the thread that ties a runtime's request to this trail.
4. Time-box it
Add from/to (RFC 3339). Expected: only events inside the window. Remember the retention policy: the trail keeps ~10 days (default) and credential.revealed is exempt — export downstream what you must keep longer.
Verified by the test test_s09_read_the_audit_trail.