Audit
Every financial mutation and every sensitive action in the platform writes anAuditEvent. 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
require_role("operator")). It returns audit events
newest-first, optional customer_id filter, capped at limit (maximum 200):
apps/api/src/neobank/api.py
The AuditEvent row
Each row is a single attributed action. The columns come from theAuditEvent 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 twoactor_* 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.Related
- 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_idvalue represents.