Skip to main content

Module audit

Module audit 

Source
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) or ForwardPolicyApplied (AUTHLANG-3 writes this kind).
  • AuditDecisionAllow or Deny { reason }.
  • AuditDenyReason — the layered-denial detail captured per AUTHZ-0.
  • AuditSink — async trait the framework awaits to persist a record.
  • TracingAuditSink — default sink, emits tracing::info! to the plexus::audit target. Free observability for every deployment.
  • ScopeCheck / ForwardPolicyApplied — empty marker types matching the AuditRecordKind variants (introduced per the ticket’s introduces: 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§

AuditRecord
One audit observation: a scope check or a forward-policy application.
ForwardPolicyApplied
Marker type for the ForwardPolicyApplied audit-record kind.
RoleName
IdP-issued role name within a realm/tenant.
ScopeCheck
Marker type for the ScopeCheck audit-record kind.
SensitiveField
Tags a parameter or field as containing sensitive material that audit payloads must redact.
SessionId
IdP-issued session identifier — the sid claim or equivalent.
TracingAuditSink
The default AuditSink: emit tracing::info! events under target = "plexus::audit".
UserId
IdP-verified originator identifier — the sub claim or equivalent.

Enums§

AuditDecision
The decision recorded by a scope check.
AuditDenyReason
The per-layer reason a deny occurred.
AuditRecordKind
Discriminates the two flavors of audit record this ticket lands.

Traits§

AuditSink
What the framework calls to persist an AuditRecord.