Audit log endpoints
Querying the row every admin mutation writes, and what that row holds.
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/admin/audit-logs | List audit log entries, newest first. Filters (AND-combined, exact match): ?action=, ?resource_type=, ?resource_id=, ?principal=; time range: ?start_time= (inclusive) and ?end_time= (exclusive), RFC 3339; paging: ?offset=, ?limit= (clamped to 1–1000, default 50). An unknown parameter returns 400 |
What a row records. Every admin mutation writes one, including
POST /workflows/{id}/test, which runs the workflow’s tasks against live connectors and so is a side-effecting operation, not a dry run.
-
principal— the actor.key-<16 hex>for an authenticated caller, oranonymouswhenadmin_auth.enabled = false. The id is derived asSHA-256("orion:audit:key-id:v1" ‖ SHA-256(key)), truncated to 8 bytes: it is stable for a given key (the same value whether the key is configured in plaintext orsha256:form), distinct for keys that share a prefix, and cannot be reversed to the key. Hold the config and you can recompute it to map a row back to a key you issued; nobody else can go in either direction. -
details— a JSON object with the request context:request_id(the same value as thex-request-idheader anderror.request_id),client_ip,user_agent, andchange_contextwhen the request carried anX-Orion-Change-Contextheader — free-form, truncated at 256 bytes; promotion tooling stampspackage=<name>@<version>on every call of an apply so the trail groups the whole operation. Both attacker-controlled inputs are truncated before storage (256 bytes foruser_agent, 200 for a suppliedx-request-id). Fields that are unavailable are omitted rather than recorded empty.client_ipfollows therate_limit.trusted_proxiespolicy, which applies whether or notrate_limit.enabledis set, so a forgedX-Forwarded-Forcannot dictate it. The flip side is that with the default empty list, forwarded headers are ignored entirely and the recorded address is the direct peer. Behind an ingress or load balancer, that is the proxy’s address on every row. List your proxies inrate_limit.trusted_proxiesto record the real client.
Rows are written asynchronously, so admin responses never wait on the INSERT. The queue is bounded (audit.max_pending) and drained at shutdown (audit.drain_timeout_secs), so a mutation accepted moments before SIGTERM is still recorded. Anything that does not make it is counted in orion_audit_events_dropped_total.
Related
- Admin API: every admin resource, and the contracts they share.
- Audit logs: every action and resource type a row can carry.
- Audit log settings: retention, cleanup and the write queue.
- Export and promotion: the header that groups a promotion’s rows.
Last verified 14 September 2026