Audit trail
Every action on record. Refusals included.
Cycloid writes every state-changing action to an append-only log in your own database. One identifier follows the chain from the click to the terraform apply.
Denials
The refused action is the one you need
Most audit logs record what happened. The question that arrives with an auditor is what somebody tried and couldn’t. Cycloid logs every attempt, allowed or denied, so probing the edges of your access leaves a trail either way. Event types come from one closed catalogue, so nothing new arrives without a place in the record. Guardrails only count if you can prove they held.
Operations
Every create, change and delete on Resources, Blueprints, Environments, Teams and Providers, plus deployments and approvals. Action names match your permission model, so blueprint:publish is one string in both.
Identity
Logins that worked and ones that didn’t, invitations, suspensions, lockouts. Permission changes carry before and after state, so a role change reads as a diff.
Administration
Tenant and security changes, the plugin lifecycle and every impersonation session. An attempt to reach another tenant’s data gets its own event type.
Cycloid for your team
What one record changes for each reader
The timeline is already assembled
The problem
The post-mortem starts with an hour of working out who did what, across three systems with three clocks and one of them in the wrong timezone.
With Cycloid
One append-only log and one identifier per action, joined to run records and traces. Refused attempts sit alongside the ones that ran.
The outcome
You walk into the review with the sequence, not with a theory about it.
A denial that tells you what to fix
The problem
You get “permission denied” with no idea which of four things is wrong, so you ask in a channel and wait for whoever knows to come online.
With Cycloid
The denial names the layer that blocked it and the condition that failed, on your screen and in the record, from the same decomposition.
The outcome
You fix it, or you ask for exactly the right thing, without a triage round trip.
Evidence, rather than recollection
The problem
The auditor wants proof the control ran, and what you’ve got is people’s memory plus a CI log that was rotated out last month.
With Cycloid
Attempted operations are recorded with their result and denying layer. Permission changes carry before and after state, and an expired break-glass grant is marked expired, not deleted.
The outcome
The evidence for a control is a query somebody can run in front of you.
How it works
From one request to one readable record
01 · A request gets its ID
Every action gets a request ID at the start, from a form, the API, the CLI, an assistant or a webhook. The log, the runs and the notifications all carry it.
02 · It survives the wait
An action waiting days for approval keeps its ID, and the approver’s click carries the same one.
03 · It reaches your tooling
The ID is injected into the Terraform or Ansible process, so a collector can find it in any trace. Nothing else travels with it.
04 · A denial explains itself
A refusal records which layer stopped it and the exact condition that failed.
05 · The event keeps a diff, not your secrets
Mutations store old and new values. Sensitive fields store only that they changed.
It all lives in PostgreSQL, append-only and scoped to the tenant, and you can query it from the API or the admin UI. System logs stay separate, because one stream doing both jobs is too noisy to audit and too selective to debug. The event catalogue, retention settings and export formats are in the audit trail docs. Export runs through plugins.
The short version
What the record holds
1
request ID, from click to terraform apply
4
places it shows up: audit, runs, logs, traces
1 yr
kept by default. You set the floor
0
secrets in the record of what changed
What did an assistant do for me yesterday?

Filtered on actor type and the person acted for. Four tool calls, one session, four request IDs.
Audit · actor_type: assistant
On behalf of you
Session
1 conversation, 4 actions
Each carries
Its own request ID
Working with your assistant
The assistant is in the log under your name, not its own
Does the assistant get its own permissions?
No. There’s no service account and no elevated assistant role. If you can’t deploy to production, neither can the assistant you’re talking to, in Cycloid’s own assistant or any compliant MCP host.
Ask your assistant what changed on a resource this week and it queries the log as you, with your read permission. There’s no service account behind it, so it can’t pull out anything you couldn’t read yourself.
Its own actions land in the same log, marked as assistant, with the person it acted for and a session ID. So everything an assistant did last quarter, and who asked for it, is a query rather than a project.
Frequently asked questions
Yes, with more detail than the successes. A denial records which of the four authorisation layers blocked it and why. The caller sees the same reason, so the person who hit the wall and the auditor read one explanation.
A year by default, set per tenant, above a floor your instance admin controls. For multi-year retention, export a copy to your SIEM or object storage and let that system hold it.
Yes. Syslog in CEF or LEEF covers Splunk, Sentinel and QRadar, JSON goes to object storage, and a real-time POST reaches any webhook. Anything unusual is a plugin you write against the same capability.
A dedicated permission, delegable read-only, so a compliance reviewer never needs admin rights. Self-hosted, it’s your database. Even an instance admin reaches tenant data only through impersonation, which is itself logged.
Bring the incident you never fully explained
Twenty minutes, one action of your choosing, and the record it leaves: the event, the actor, the request ID, and that same ID on the run and on the trace. Then ask us for something the log can’t tell you, and we’ll say so.



