Access Audit Events
Every APF component writes structured audit records for the policy lifecycle steps and the decisions it makes. A few outcomes are not recorded. Refer to Gaps in the Record. Records follow one schema, apf.audit.event.v1, and are validated against it before they are written. Together they answer what happened, why, and under which policy.
Where Records Are Written
Each service writes one JSON Lines file per component into its --audit-log-dir. Both services refuse to start without an audit directory.
The interceptor and middleware files are created only when their listener is enabled. Files are created with mode 0600. Each record is one line. Because every write opens the file in append mode, the files can be rotated by renaming or truncating them.
Event Types
The schema defines 14 event types. Eleven have producers today.
Fields Every Record Carries
Operation events add outcome (success, failure, or refused) and reason_code. Authorization events add decision and reason_code instead, and the startup event adds security_state and reason_code. Policy identity fields, bundle_digest, bundle_id, policy_revision, and trust_root_id, appear where a policy is in force. Refer to Audit Event Schema for every field.
Read and Filter Records
Records are plain JSON Lines, so standard tools work. With jq:
Query on component.name and enforcement_point_id, which the producer writes, rather than on file names, which a log shipper may change.
Emission Guarantees
Whether a failed write stops the operation depends on the event, not the component.
Sanitized and Degraded Records
Every string is scanned for credential-shaped content before a record is written, and fields that come from callers are length-capped and coerced to their schema patterns. When a record cannot be written safely, the gateway, interceptor, and middleware, and the policy service for document requests, write a reduced record instead. The event type, the decision or outcome, and the reason code survive. Caller-supplied detail is replaced with sentinel values such as unspecified or unrecordable, and the record notes the degradation in reason. Other policy service records have no reduced form: they are lost with a logged warning, or the operation stops. Do not treat sentinel values as real identities. Refer to Degraded Records.
Gaps in the Record
Some outcomes leave no audit record. Collect service logs alongside audit records to cover them.
- The gateway does not record refused Unix socket peers, failed hot swaps, or its startup posture.
- When a verified bundle fails to compile, the policy service has already written a successful
policy_verificationrecord and records nothing about the failure. - The policy service records nothing when a startup check fails before its startup record, or when no manifest in an HTTP source archive verifies.
- The interceptor does not record successful configuration validations or post-commit calls.
Activation records need care too. A local POST /v1/refresh records policy.bundle_loaded, not policy.bundle_hot_swapped. An HTTP poll records policy.bundle_loaded before it decides whether to swap, so the record can be followed by policy.bundle_rejected.counter_not_newer for a bundle that never took effect. Treat the last record for a revision as authoritative.
Refer to Monitor Policy and Service Health.
Next Steps
- To read decisions and findings, refer to Understand Decisions and Findings.
- To ship records to a SIEM, refer to Export Audit Events.