Files
member-console/design/audit/interfaces.md
Christian Galo 195cd348a9 Update design to use schemas per module and revert to using industry
aligned terminology for discounts and coupons and promo codes.
2026-04-01 03:08:35 -05:00

6.3 KiB

Audit Module -- Interfaces

This document describes the cross-module interface surface of the audit module. The audit module is architecturally distinctive in its one-directional relationship to the rest of the system: it consumes references from other modules but provides no interfaces that other modules depend upon.


Provided Interfaces

None.

The audit module is a one-directional observation system. No table outside the audit module has a foreign key reference into any audit table. No business logic in any other module depends on audit data being present, queryable, or consistent. This is by design (Decision 96) and constitutes a fundamental architectural property: the audit module can be disabled, dropped, or replaced without affecting any other module's schema or runtime behavior.

This is unusual among the six modules -- most modules both provide and consume interfaces. The audit module's absence of provided interfaces reflects its role as a terminal consumer in the dependency graph: information flows into audit but never flows out via structural references. External consumers (SIEM, analytics) receive audit data via the audit_outbox relay, but this is an application-level delivery mechanism, not a structural interface.


Consumed Interfaces

From identity

Entity FK Column(s) Usage
identity.persons audit_logs.actor_person_id Identifies the person who performed the audited action. Nullable -- NULL when the actor is a service account or system.
identity.persons audit_legal_holds.scope_actor_person_id Scopes a legal hold to events performed by a specific person. Nullable -- NULL for broader holds.
identity.persons audit_legal_holds.hold_placed_by Records who placed the legal hold. Required (NOT NULL).
identity.persons audit_legal_holds.hold_released_by Records who released the legal hold. Nullable -- NULL while the hold is active.

From organization

Entity FK Column(s) Usage
organization.service_accounts audit_logs.actor_service_account_id Identifies the service account that performed the audited action. Nullable -- NULL when the actor is a person or system.
organization.organizations audit_logs.org_id Scopes the audit event to an organizational context for filtering. Nullable -- NULL for platform-level events.
organization.organizations audit_legal_holds.scope_org_id Scopes a legal hold to events within a specific organization. Nullable -- NULL for platform-wide holds.

Polymorphic Observation Contract

Beyond the structural FK references listed above, the audit module observes entities across all modules via bare polymorphic associations. These are intentional exceptions to the model's preference for exclusive arcs (Decision 23) and do not constitute consumed interfaces in the structural sense -- they are metadata annotations on append-only records.

Entity Observation (entity_type + entity_id)

The audit_logs table records the target of each audited action using entity_type (VARCHAR) and entity_id (UUID). The entity type can name any of the 53 tables in the system. There is no FK constraint -- the referenced entity may have been deleted, anonymized, or merged by the time the audit record is read. This is an observational annotation, not a navigable relational reference.

Observed modules: All six modules. Any table may appear as an entity_type value.

Actor Observation (actor_type + actor_credential_type + actor_credential_id)

The actor_type column identifies the actor's identity class (person, service_account, system). The actor_credential_type and actor_credential_id columns identify the authentication credential used. Only two of five credential types (pat from identity module, api_key from organization module) have table-backed targets. Sessions, OIDC client credentials, and system credentials are not backed by dedicated tables.

Observed modules: identity (persons, personal_access_tokens), organization (service_accounts, service_account_keys).


Interface Contracts

Stability Expectations from Consumed Modules

The audit module depends on the following stability guarantees from modules it consumes:

  1. persons.person_id remains stable through anonymization. The identity module guarantees that person anonymization mutates the row (scrubbing PII fields) but does not delete or re-key it (Decision 31). Audit records referencing an anonymized person retain their actor_person_id as a valid, though now de-identified, correlation key.

  2. service_accounts.service_account_id remains stable through deactivation. Service accounts may be deactivated but are not deleted (ON DELETE RESTRICT, Decision 33). Audit records referencing a deactivated service account retain a valid FK reference.

  3. organizations.org_id remains stable through all lifecycle states. Organizations may be suspended or deactivated but the primary key is preserved. Audit records and legal holds scoped to an organization retain valid FK references regardless of the organization's current state.

These stability guarantees are structural consequences of the model's universal ON DELETE RESTRICT policy (Decision 33) and the anonymization-over-deletion approach to GDPR compliance (Decision 31). They are not audit-specific contracts -- they benefit all modules that hold FK references to these entities. The audit module's reliance on them is documented here for completeness.


Dependency Direction Summary

All dependencies flow into the audit module. No module depends on audit. audit_logs receives actor references from the identity module (identity.persons) and the organization module (organization.service_accounts, organization.organizations), and observational entity annotations from all modules via the polymorphic entity_type column. audit_outbox is written in the same transaction as each audit event. audit_retention_policies is referenced by the materialization pipeline for tier configuration. audit_legal_holds receives scope references from identity (identity.persons) and organization (organization.organizations). audit_archive_manifest is fully self-contained with no external references.

This one-directional dependency structure is the defining architectural characteristic of the audit module.