audit
The audit trail as an admin reads it.
Every row is one privileged or automated action on an account or its data, written once and never changed. The read is the only way the trail leaves the database: there is no request model here because nothing writes to the trail through the API.
AuditReaderName = Literal['organisation', 'project', 'subject']
module-attribute
¶
Who reads an event besides the platform's administrators.
REDACTED_DETAIL_KEYS = frozenset({'email_hash'})
module-attribute
¶
Keys an audit event's detail never carries on the wire.
The one-way email hash a deleted account leaves behind exists so a support lookup by address can find the row; the lookup is a server-side filter, and the hash itself is never handed out.
AuditActionInfo
pydantic-model
¶
Bases: BaseModel
One audit action as the server records it.
The vocabulary is served so that a client renders it instead of keeping a copy: an audit view offers as filters exactly the actions its reader can receive, named as the server names them.
Fields:
action
pydantic-field
¶
The action, as its events carry it.
item_keys
pydantic-field
¶
The detail keys of this action that hold item ids, alone or in a list: the ids an audit view's item filter matches.
name
pydantic-field
¶
How the action reads.
readers
pydantic-field
¶
Who can ever read an event of this action, besides the platform's administrators: organisation (its owner and admins), project (the project's owner) and subject (the person it is about).
removal
pydantic-field
¶
Whether the action records something removed for good: a deletion or a purge.
AuditEventListResponse
pydantic-model
¶
Bases: PaginatedResponse
A page of audit events, newest first.
Fields:
-
total(NonNegativeInt) -
offset(NonNegativeInt) -
limit(PositiveInt) -
events(list[AuditEventOut]) -
export_limit(int)
export_limit
pydantic-field
¶
The most events one CSV export of this view holds. An export of more is refused: narrow the filters until total fits.
AuditEventOut
pydantic-model
¶
Bases: BaseModel
One audit event, as recorded.
Config:
from_attributes:True
Fields:
-
id(UUID) -
occurred_at(datetime) -
actor(str) -
action(str) -
org_id(UUID | None) -
user_id(UUID | None) -
detail(dict[str, Any])
Validators:
-
_redact→detail
action
pydantic-field
¶
What happened. A plain string, so a newly recorded kind of action needs no client update; the server serves its vocabulary at GET /status/audit-actions.
actor
pydantic-field
¶
Who acted: admin:<user id> for an administrator, user:<user id> for an account owner, system:<name> for a scheduled task.
detail
pydantic-field
¶
Non-personal context of the action — counts, bytes, dates, the names of fields that changed. Keys vary by action.
id
pydantic-field
¶
Identifier of the event; time-ordered.
occurred_at
pydantic-field
¶
When the action happened.
org_id = None
pydantic-field
¶
The affected organization, when the action concerns one. A bare identifier: the organization may no longer exist.
user_id = None
pydantic-field
¶
The affected account, when the action concerns one. A bare identifier: the account may no longer exist.
AuditFilters
pydantic-model
¶
Bases: BaseModel
What narrows an audit view: the same filters on every view.
Config:
extra:forbid
Fields:
-
actions(list[str] | None) -
since(datetime | None) -
until(datetime | None) -
user_id(UUID | None) -
resource_id(UUID | None)
actions = None
pydantic-field
¶
Only events recording one of these actions.
resource_id = None
pydantic-field
¶
Only events naming this item: a project, study, recording, analysis, export, invitation or API key.
since = None
pydantic-field
¶
Only events at or after this time.
until = None
pydantic-field
¶
Only events before this time.
user_id = None
pydantic-field
¶
Only events concerning this account.