Skip to main content
Agents do their best work when the blast radius of a mistake is bounded and recovery is one call away. Cactal gives you six controls for that: scope the key, keep work on drafts, check before publish, put a human at the publish gate, watch the audit log, and roll back when needed. The built-in Cactal agent follows this model automatically: it edits drafts, validates with the framework check, and pauses for an in-conversation approval before publishing or any other live change, with its actions attributed in the activity feed. The controls below apply the same discipline to agents you bring yourself.

Scope the key

Give each agent its own API key, scoped to exactly the websites and capabilities its job requires. Separate keys keep the audit log attributable and let you revoke one agent without breaking another. A content_editor key cannot edit source code, publish the website, or change settings — the MCP server does not even show it those tools. The owner role is not grantable to keys. Rescope a key at any time by sending access to PATCH /v1/apiKeys/{apiKeyId}; the change applies immediately. See Access control and Manage API keys.

Draft-first editing

All source edits land on the website’s head — the draft version. Mutations require an edit lease from POST /v1/websiteSourceCode/lease/acquire, and nothing an agent writes reaches the live website until an explicit POST /v1/websiteSourceCode/head/publish. Review the draft at any time on its preview host:
Preview hosts are served with X-Robots-Tag: noindex, nofollow, so drafts stay out of search engines. CMS items have their own draft state: an agent can prepare items and leave publishing to you. See Preview drafts and versions.

Check before publish

POST /v1/websiteSourceCode/head/check runs the framework quality gate against the draft without publishing anything. Make a passing check a hard precondition in your agent’s instructions. The check answers “does it render,” not only “does it compile.” It server-renders every page using placeholder content synthesized from the CMS schema, and returns each page that threw in renderFailures with its pageId, route, and error. Treat that array as the repair list. See What the head check covers. Publishing runs a build in an isolated sandbox and creates a deployment that moves through building, then ready or failed. Only a deployment that reaches ready serves traffic — but a failed publish still costs time, so check first.
An agent that publishes without checking can ship a broken draft build attempt and stall its own workflow. Treat head/check as mandatory, not advisory.

Put a human at the publish gate

The strongest pattern separates preparation from publication.
1

Agent prepares the draft

The agent edits source, content, and assets on head, running POST /v1/websiteSourceCode/head/check after each batch of changes.
2

Agent reports the preview URL

When the check passes, the agent posts https://draft--<label>.cactal.app and a summary of what changed.
3

Human reviews the draft

Open the preview URL, list files changed from the live version with GET /v1/websiteSourceCode/changes, and inspect selected files with GET /v1/websiteSourceCode/files/diff.
4

Publish after approval

Either you publish from the dashboard, or you tell the agent to call websiteSourceCode_head_publish.
You can enforce this two ways:
  • Hard enforcement — give the agent a content_editor key. It cannot publish at all; a human (or a separate, human-triggered process) owns the publish step.
  • Policy enforcement — give a full_editor key plus a standing instruction. Useful when the same agent must build and ship:
cactal-publish-policy.md

Watch the audit log

Lifecycle and access-control operations write organization audit events with actor attribution: website create/rename/delete/restore/transfer, editor grants and invitations, API keys, domains, organization membership, and billing. Agent actions carry actorKind: "api_key", so reviewing that activity is one filtered request:
Each event records the event type, the resource, a human-readable summary, and which API key acted. Narrow further with eventType, resourceType, actorPrincipalId, or websiteId (which matches the website itself and resources belonging to it), and page with cursor — see Pagination. Reading the audit log requires an admin-role key or the dashboard.
Source file edits, publishes, CMS content, and asset changes are not audit-logged. Review an agent’s content work where it actually lives: GET /v1/websiteSourceCode/changes for the pending file list, GET /v1/websiteSourceCode/files/diff for selected source changes, and the draft-- preview for the rendered result.
Review the audit log after an agent’s first unattended runs, and periodically afterwards. Attribution is only useful if someone reads it.

Recover

Every layer of agent work has an undo path. None of these require the agent that caused the problem. Unpublish needs no edit lease and takes every site hostname offline. Cached pages may take a few minutes to disappear. Rollback changes what serves immediately and moves head to a new copy of the selected historical version. See Roll back and recover for the full procedures, including failed-build recovery.

If a key is compromised

Act on the key first, then investigate.
  1. Rotate with POST /v1/apiKeys/{apiKeyId}/rotate — the old secret stops working immediately and you receive a new one once.
  2. Revoke with POST /v1/apiKeys/{apiKeyId}/revoke if the agent should lose access entirely. Revocation is permanent.
  3. Audit what the key did: filter the audit log by actorKind=api_key and the key’s principal, then roll back anything unwanted.
A safe agent setup looks like this: one key per agent, website-scoped, least role; all work on head; check before publish; a human approval step; periodic audit review; and a tested rollback path.