Events and chain
The Events and chain screen lets you search the audit trail of your tenant, verify that its hash chain is
intact and export a period to immutable (WORM) storage. Portal path: /audit/events (menu Audit > Events and
chain, page title Audit events). Auditors, security officers and tenant administrators use it to answer "who
did what, when, with which decision".
What the screen shows
| Area | Content |
|---|---|
| Hash chain section | Each event contains the hash of the previous one; verification recomputes the chain. Before a check: Not verified in this session. After a check: the badge Chain intact or Chain broken and the JSON of the result (valid, count, broken_at, reason, verified_at). |
| Filters | Actor (actor id), Action (exact name, or a prefix ending with * such as finops.*), Resource (type or type:id), Outcome (success, failure, denied), Trace id, From and To (ISO 8601 timestamps). |
| Events table | Columns: Sequence, Time, Actor, Action, Resource type, Resource id, Decision, Outcome. Newest first, 50 events per page. |
| Detail panel | A click on a row loads the full event (actor, resource, decision, evidence, hashes). |
| Export to WORM storage | Form: From (for example 2026-01-01T00:00:00Z), To, Retention (days) (default 365), with a Result panel. Exports are written to immutable (WORM) storage and recorded in the audit trail. |
| Empty state | No audit event: every mutation and policy decision writes an event. |
Every search and every verification is itself recorded as an access to the audit trail.
Actions
| Button or action | What it does | API call | Roles |
|---|---|---|---|
| Verify chain | Recomputes the hash chain of the tenant and shows the verdict. | GET /v1/audit/verify | auditor, security_officer, tenant_admin, platform_admin |
| Filter | Applies the filters filled in. | GET /v1/audit/events (actor, action, resource, outcome, trace_id, from, to, limit, cursor) | auditor, security_officer, tenant_admin, platform_admin |
| Refresh (round arrow icon) | Reloads the list. | GET /v1/audit/events | Same roles |
| Load more | Loads the next page of older events. | GET /v1/audit/events (cursor) | Same roles |
| Click on a row | Opens the detail panel. | GET /v1/audit/events/{event_id} | Same roles |
| Run (Export to WORM storage) | Writes the events of the period, signed, with a manifest, to the WORM storage (the audit_worm storage profile of the tenant, else the platform profile named by EAI_AUDIT_WORM_STORAGE_PROFILE), and returns the manifest. | POST /v1/audit/export | auditor, security_officer, tenant_admin, platform_admin |
Roles
| Role | Access |
|---|---|
auditor, security_officer, tenant_admin | Open the screen (portal/src/lib/nav-access.ts), search, verify and export (READERS of services/control-plane/src/eai/domains/observability/audit_api.py). |
platform_admin | Same rights; every route needs a tenant context (tenant_required otherwise). |
| Other roles | The entry is hidden; the page shows Your roles do not open this page. |
danger
A Chain broken verdict means that an event of the trail was changed or removed. Do not fix it by hand: keep the
result JSON (it names broken_at and the reason) and open a security incident.
Typical tasks
Check the integrity of the audit trail
- Verify the chain. The verification proves that no event was altered since it was written. Click Verify
chain.
Expected result: the badge Chain intact and a JSON with
valid: trueand thecountof events checked. If it fails: with Chain broken, keep the JSON and declare an incident in Incidents.
Find who changed a quota
- Filter on the action. Enter
finops.quota.*in Action so every quota event is listed (create, update, delete, and the reservations of the gateways), then click Filter. Expected result: the table lists the quota events with their Actor. If it fails: if No audit event appears, widen From and To or check the action prefix. - Open the event. Click the row to read the full event.
Expected result: the panel shows the actor, the resource, the decision and the evidence.
If it fails:
not_foundmeans the event id is not in your tenant.
Export a quarter for an external audit
- Fill the period. In Export to WORM storage, enter From and To as ISO 8601 timestamps and the
Retention (days) the storage must keep the export (1 to 3650).
Expected result: the fields are filled.
If it fails: if a role notice replaces the form, ask for the
auditorrole. - Export. Click Run.
Expected result: the Result panel shows the manifest: file,
count,sha256, signature and retention. If it fails:storage_profile_not_foundorstorage_capability_missingmeans the WORM storage profile is missing or not verified; see Storage profiles.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| Your roles do not open this page | Your roles are not among auditor, security_officer, tenant_admin, platform_admin. | Ask for the auditor role. |
Error forbidden (HTTP 403): "You do not have the required role for this operation." | The token has no reading role of the audit trail. | Sign in again with an auditor account. |
Error tenant_required (HTTP 403) | Platform administrator without a tenant. | Sign in to a tenant. |
Error storage_profile_not_found (HTTP 404): "Storage profile ... not found." | EAI_AUDIT_WORM_STORAGE_PROFILE names a platform profile that does not exist. | Create the profile or fix the setting. |
Error storage_capability_missing (HTTP 409) | The WORM profile lacks a verified object lock or retention capability. | Verify the profile in Storage profiles. |
Error validation_error (HTTP 422) | Retention (days) outside 1 to 3650, or a timestamp that is not ISO 8601. | Fix the field. |
| Chain broken | An event was changed or removed. | Keep the result and open an incident. |