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.

Audit log

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.

From one request to one readable record

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?

Cycloid

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.