Skip to main content

Audit

Every financial mutation and every sensitive action in the platform writes an AuditEvent. Operators read the trail through GET /v1/ops/audit, filtered by customer and attributed across the full actor chain — including autonomous agents and internal rules.

The endpoint

The endpoint is operator-gated (require_role("operator")). It returns audit events newest-first, optional customer_id filter, capped at limit (maximum 200):
apps/api/src/neobank/api.py
See Operator console for the role and MFA requirements that gate this route.

The AuditEvent row

Each row is a single attributed action. The columns come from the AuditEvent model:
apps/api/src/neobank/models.py
The composite index ix_audit_customer_created (customer_id, created_at) backs the filtered, newest-first listing an operator runs during triage.

Attribution across the actor chain

The two actor_* columns are what make the trail usable for mandate investigation. A single mandate execution by an autonomous agent produces an event whose actor_id is the agent’s subject and whose actor_client_id is the authorized client that the customer approved on the mandate. Direct customer actions leave actor_client_id null. This lets an operator answer “which authorized client executed this mandated payment?” without inference. Cross-reference the request_id against the operation in /v1/ops/operations to tie the audit row to the resulting transfer and its outcome.
Actions taken by an internal_rule caller carry that rule’s identifier in actor_client_id, not a human subject. The trail distinguishes a human-initiated action from a rule-initiated one in the same column.
  • Operator console — the surface operators use alongside this trail.
  • Agent mandates — how authorized clients and rules come to hold execution authority, and what an actor_client_id value represents.