Expand description
AuditRecord, AuditSink, and the default TracingAuditSink — the
audit primitive per AUTHZ-PRIVACY-1.
AUTHZ default-deny dispatch (AUTHZ-CORE-5) must write one audit record per scope check (allow or deny) before the dispatch responds. The no- enumeration error policy (AUTHZ-PRIVACY-4) depends on this primitive: the wire response is generic per AUTHZ-S01-output §9; the real reason for a deny lives in the audit record.
§Module surface
AuditRecord— the record shape (per AUTHZ-S01-output §1 + §8, with AUTHZ-0 ratification revisions §2 and AUTHLANG-S01-output §4 fields).AuditRecordKind— discriminant:ScopeCheck(default) orForwardPolicyApplied(AUTHLANG-3 writes this kind).AuditDecision—AlloworDeny { reason }.AuditDenyReason— the layered-denial detail captured per AUTHZ-0.AuditSink— async trait the framework awaits to persist a record.TracingAuditSink— default sink, emitstracing::info!to theplexus::audittarget. Free observability for every deployment.ScopeCheck/ForwardPolicyApplied— empty marker types matching theAuditRecordKindvariants (introduced per the ticket’sintroduces:frontmatter so the variant names have type-level reachability without conflating with the discriminant).SensitiveField— registry marker introduced for AUTHZ-PRIVACY-2 to populate (#[sensitive]field tagging). Today’s redaction is a stub: no fields are redacted because the registry is empty.UserId,SessionId,RoleName— strong-typed newtype primitives for the principal-chain capture. See module-level run-note below.
§UserId, SessionId, RoleName ownership
AUTHZ-PRIVACY-1’s imports: frontmatter lists these three types, but no
upstream ticket actually owns them — the spec author flagged this for
resolution before launch. Per the resolution path in the agent prompt and
the strong-typing skill, this ticket owns them. They are introduced
here as transparent String newtypes alongside the rest of the audit
primitive. See plans/AUTHZ/AUTHZ-PRIVACY-1-RUN-NOTES.md for the
expansion of the introduces: list.
§Sealing posture
Unlike Principal / VerifiedUser / Credential, the audit primitive is
NOT sealed. The framework constructs AuditRecord values internally, but
tests, sink reference implementations, and downstream observers all need
to construct them — there is no safety property that demands a sealed
constructor. AuditRecord derives Debug, Clone, Serialize, Deserialize
per acceptance criterion 1.
§Sink failure
Per AUTHZ-S01-output §8 default policy: a sink that returns / panics-as-
error from write is logged at tracing::error and dispatch continues.
The audit-vs-availability tradeoff defaults to availability; critical-
sink semantics are deferred (AUTHZ-S01-output §8 open question; future
ticket).
Structs§
- Audit
Record - One audit observation: a scope check or a forward-policy application.
- Forward
Policy Applied - Marker type for the
ForwardPolicyAppliedaudit-record kind. - Role
Name - IdP-issued role name within a realm/tenant.
- Scope
Check - Marker type for the
ScopeCheckaudit-record kind. - Sensitive
Field - Tags a parameter or field as containing sensitive material that audit payloads must redact.
- Session
Id - IdP-issued session identifier — the
sidclaim or equivalent. - Tracing
Audit Sink - The default
AuditSink: emittracing::info!events undertarget = "plexus::audit". - UserId
- IdP-verified originator identifier — the
subclaim or equivalent.
Enums§
- Audit
Decision - The decision recorded by a scope check.
- Audit
Deny Reason - The per-layer reason a deny occurred.
- Audit
Record Kind - Discriminates the two flavors of audit record this ticket lands.
Traits§
- Audit
Sink - What the framework calls to persist an
AuditRecord.