What this is about
The audit contains what everyone did across the whole platform, in every tenant. Whoever could read part of it could already tell from the entries which customers exist. That is why reading is strictly controlled.
How it is read
The audit has exactly one read function: the interface AuditQueryUseCase with the method page(page, size). Code running in the same program as CIAS calls it, for example an admin screen of the host. There is no write access. Entries come only from the listener, see One trail for everything. An audit that someone can write to from outside would be a place for an alibi.
-
CIASlogged inIs there a logged-in caller?↳ no refused:
cias.audit.access-denied -
CIASPlatform administratorDoes their token carry a role that counts as platform administrator?↳ no refused:
cias.audit.access-denied -
CIASPageIs
pageat least 0 andsizebetween 1 and 500?↳ no refused, before anything is read - One page of entries, newest first
A page
auditQuery.page(0, 3)AuditPage[
total = 1284, page = 0, size = 3,
entries = [
{ type: "AuthorizationEvent.Granted",
detail: "Granted[assignmentId=a41f…, userId=5c9e…, roleClient=cias-backend, roleKey=tenant-user, tenantKey=nordbau, validUntil=null, grantedBy=nordbau, occurredOn=2026-09-22T09:20:11Z]",
actorId: "e7d0…", actorTenant: "nordbau",
occurredOn: 2026-09-22T09:20:11Z, recordedOn: 2026-09-22T09:20:11.042Z },
{ type: "TenantEvent.Suspended",
detail: "Suspended[tenantId=4f2a…, tenantKey=suedlogistik, occurredOn=2026-09-22T09:14:03Z]",
actorId: "b21c…", actorTenant: null, … },
{ type: "AuthorizationEvent.Expired",
detail: "Expired[assignmentId=77c3…, …]",
actorId: null, actorTenant: null, … }
]
]| Part | Meaning |
|---|---|
entries | the entries of this page, newest first. At the same point in time the ID decides, so no row appears twice or goes missing while paging |
total | how many entries there are in total |
page, size | which page was read and how many rows a full page holds. Default 50, at most 500 |
actorId empty | the platform acted on its own or nobody was logged in, in the example a timer |
The field detail is text, not structured. It is the description of the event the way Java prints a record as text: name, then all fields with values in square brackets.
The variants
When: The token carries a role that counts as platform administrator.
Reads all entries of all tenants.
Result: one page of entries
When: Tenant administrator, ordinary person or no token.
They do not see their own tenant either. A filter by tenant would have to leave out entries without a tenant, such as those of a timer, and an audit that silently leaves out what it cannot classify is the worst audit.
Result: refused: cias.audit.access-denied
When: size above 500, below 1, or page negative.
CIAS refuses instead of silently returning fewer rows. Otherwise the caller would believe they had seen everything.
Result: refused, nothing read