Skip to main content

Break-glass and audit

This page covers the two mechanisms that keep provider access honest: break-glass, the only way platform staff can touch your project's contents, and the audit log, the append-only record your whole team can read.

Break-glass

Platform admins hold no authority over your project's contents — the security overview explains why. When one genuinely needs in (usually to fix something you asked them to fix), they take a break-glass grant: a self-granted, temporary membership with strings deliberately attached.

The mechanics

Every break-glass grant:

  • requires a written reason of at least 8 characters, shown to your project's members word for word. The API insists: a reason is required and is shown to the project's members verbatim - say what you are fixing and, if there is one, name the ticket;
  • expires on its own — 4 hours by default, 24 hours at most. Work that outlives the ceiling needs a fresh grant with a fresh reason: a break-glass grant may last at most 24h0m0s - take a fresh one, with a fresh reason, if the work outlives it;
  • is visible immediately on your IAM & members page, rendered louder than any normal row, with the reason, who took it, and when it expires;
  • is written to your audit log as project.break-glass — a record that outlives the grant;
  • requires a human credential — machine credentials are refused;
  • is only available to a platform admin holding no existing grant on the project. It is an escalation from nothing, never a quiet role upgrade: break-glass access is for platform admins repairing a project they are not a member of; you already hold a grant here, or you hold none to escalate from.

The grant itself comes back with a note that summarizes the deal:

this grant is visible to the project's members and recorded in its audit log. It expires on its own; remove it sooner with DELETE /v1/projects/<id>/members/<userId>

For the curious, the API call (platform admins only):

curl -s -X POST "$CAI_API/v1/projects/$PROJ/break-glass" \
-H "Authorization: Bearer $TOK" \
-d '{"reason":"debugging stuck builds, ticket OPS-142","minutes":120}'

You should see:

{"grant":{"break_glass":true,"expires_at":"...","reason":"debugging stuck builds, ticket OPS-142","granted_by":"..."},"note":"this grant is visible to the project's members and recorded in its audit log. It expires on its own; remove it sooner with DELETE /v1/projects/<id>/members/<userId>"}

After the grant

  • Expiry is automatic. The row stays on the IAM page marked expired — it becomes history, not clutter, so a grant can never be quietly forgotten.
  • Early removal is an ordinary member removal, recorded as project.member.remove in the audit log.
  • Break-glass admins never count toward the "last admin" guard — a temporary provider grant can never become the reason your project appears to have an admin it doesn't really have.

What to do when you see one

Nothing is required — visibility is the feature. But if a break-glass row appears with a reason you don't recognize, ask the person named in granted_by, and remember the reason string was written knowing you would read it.

The audit log

Every project has an append-only audit log: a per-project history of state changes that any member can read — not just admins. It is the other half of the break-glass bargain: provider access is only trustworthy if the record of it is yours.

What one entry looks like

FieldMeaning
tsWhen it happened
actorThe email of the user or service account that did it; empty means the platform system itself
actionA dotted name like agent.deploy (full list below)
targetWhat it happened to
detailExtra context — for example the role that was granted

Entries are returned newest first and paged with a cursor. Read it in the console on the Audit log page, or from the API:

curl -s "$CAI_API/v1/projects/$PROJ/audit?page_size=20" \
-H "Authorization: Bearer $TOK"

You should see:

{"entries":[{"ts":"...","actor":"sam@acme.com","action":"project.member.add","target":"dana@acme.com","detail":"..."}],"next_page_token":"..."}

What gets recorded

Every state change through the API. The complete set of actions:

FamilyActions
Agents and functionsagent.deploy, agent.redeploy, agent.delete, agent.config, agent.file.write, agent.file.delete, agent.set-traffic
Embed widgetagent.embed.update, agent.embed.rotate-key, agent.embed.delete
Membershipproject.member.add, project.member.role, project.member.remove, project.member.sa.role, project.member.sa.remove
Invitationsproject.invite, project.invite.revoke, invitation.accept
Break-glassproject.break-glass
Project lifecycleproject.create, project.rename, project.delete
Secretsproject.secret.write, project.secret.delete, project.secret.reveal, project.secret.issue-token, project.secret.apply, project.secret.bind, project.secret.unbind
Credentialsapikey.create, apikey.revoke, serviceaccount.create, serviceaccount.delete, serviceaccount.key.create, serviceaccount.key.revoke
MCP serversmcpserver.create, mcpserver.delete, mcpserver.tool.publish, mcpserver.tool.delete, mcpserver.version.rollback, mcpserver.version.yank, mcpserver.version.unyank
Crusoe Cloud integrationproject.crusoe-cloud.map, project.crusoe-cloud.unmap, project.crusoe-cloud.bucket.create, project.crusoe-cloud.repository.create
Platform administrationorg.create, org.delete, org.member.add, org.member.remove, org.member.role, user.create, user.delete, user.role, user.reset-password, valkey-acl.backfill

Note the quiet standouts: project.secret.reveal means reading a secret's value is itself an audited event, and functions appear under agent.deploy because they share the agent pipeline.

What the log guarantees — and what it doesn't

Guarantees:

  • Append-only. There is no API to edit or delete an entry.
  • Member-readable. Every member sees the same history, including provider actions.
  • Never blocks you. An audit write failure never fails the underlying request.

Honest alpha limits:

  • That last guarantee cuts both ways: because audit writes are best-effort, an entry could in principle be missing after an infrastructure failure. The log is a strong record, not yet a cryptographic one.
  • No export, no retention controls, no server-side date-range filter yet — you page backward from newest.
  • Reads (list/get calls) are not logged; the log records changes, plus the read-like exceptions called out above (project.secret.reveal, project.secret.issue-token).

Summary checklist

  • Platform staff access = break-glass only: reason (≥ 8 chars, shown verbatim), expiry (default 4 h, max 24 h), loud IAM row, audit entry.
  • Expired grants stay visible as history; early removal shows as project.member.remove.
  • Any member can read the full audit log; actor empty means the system did it.
  • Secret reveals are audited; audit writes never fail your request; no export/retention yet (alpha).

Next steps