Skip to content

llm.audit — Audit Chain Events

Auto-documented module: spanforge.namespaces.audit

The RFC-canonical llm.audit.* namespace currently includes one registered first-party event type:

  • llm.audit.key.rotated

The spanforge.namespaces.audit module also ships helper payload dataclasses for chain-verification outcomes. Those payloads are useful, but their corresponding event types are not part of the canonical RFC Appendix B registry. If you use them, emit them under a reverse-domain custom event type (e.g. x.mycompany.audit.chain.verified) rather than llm.*.

Payload classes

ClassCanonical event typeNotes
AuditKeyRotatedPayloadllm.audit.key.rotatedRFC Appendix B canonical event type
AuditChainVerifiedPayloadUse with a custom reverse-domain event type
AuditChainTamperedPayloadUse with a custom reverse-domain event type

AuditKeyRotatedPayload

Records that an HMAC signing key was replaced. effective_from_event_id is the ULID of the first event signed with the new key, enabling exact replay of any chain segment.

FieldTypeRequiredDescription
key_idstrIdentifier of the new key
previous_key_idstrIdentifier of the superseded key
rotated_atstrISO 8601 timestamp (6 decimal places)
rotated_bystrIdentity of the operator or service that rotated the key
rotation_reasonstr | NoneOne of "scheduled", "suspected_compromise", "policy_update", "key_expiry", "manual"
key_algorithmstrDefaults to "HMAC-SHA256"
effective_from_event_idstr | NoneULID of first event signed with the new key

Canonical example

from spanforge import Event, EventType
from spanforge.namespaces.audit import AuditKeyRotatedPayload

payload = AuditKeyRotatedPayload(
    key_id="key_01HX_v2",
    previous_key_id="key_01HX_v1",
    rotated_at="2026-03-04T12:00:00.000000Z",
    rotated_by="ops-bot@spanforge.io",
    rotation_reason="scheduled",
)

event = Event(
    event_type=EventType.AUDIT_KEY_ROTATED,
    source="key-manager@1.0.0",
    org_id="org_01HX",
    payload=payload.to_dict(),
)

AuditChainVerifiedPayload

Represents a successful audit-chain verification result.

FieldTypeRequiredDescription
verified_from_event_idstrULID of the first event in the verified range
verified_to_event_idstrULID of the last event in the verified range
event_countintNumber of events verified
verified_atstrISO 8601 timestamp of the verification run
verified_bystrIdentity of the verifier (service or operator)

Custom event-type example

from spanforge import Event
from spanforge.namespaces.audit import AuditChainVerifiedPayload

payload = AuditChainVerifiedPayload(
    verified_from_event_id="01HXABC0000000000000000000",
    verified_to_event_id="01HXABCZZZZZZZZZZZZZZZZZZZ",
    event_count=1024,
    verified_at="2026-03-04T14:00:00.000000Z",
    verified_by="audit-worker@1.0.0",
)

event = Event(
    event_type="x.mycompany.audit.chain.verified",
    source="audit-worker@1.0.0",
    org_id="org_01HX",
    payload=payload.to_dict(),
)

AuditChainTamperedPayload

Represents a failed chain-verification result (tampering or sequence gaps).

FieldTypeRequiredDescription
first_tampered_event_idstrULID of the first event with a broken HMAC
tampered_countintNumber of events with invalid signatures
detected_atstrISO 8601 timestamp of detection
detected_bystrIdentity of the detector
gap_countint | NoneNumber of missing sequence IDs
gap_prev_idslist[str]ULIDs immediately before each detected gap
severitystr | None"low", "medium", "high", or "critical"

Custom event-type example

from spanforge import Event
from spanforge.namespaces.audit import AuditChainTamperedPayload

payload = AuditChainTamperedPayload(
    first_tampered_event_id="01HXDEF0000000000000000000",
    tampered_count=3,
    detected_at="2026-03-04T15:30:00.000000Z",
    detected_by="audit-worker@1.0.0",
    severity="high",
    gap_count=1,
    gap_prev_ids=["01HXDEE0000000000000000000"],
)

event = Event(
    event_type="x.mycompany.audit.chain.tampered",
    source="audit-worker@1.0.0",
    org_id="org_01HX",
    payload=payload.to_dict(),
)