Skip to content

operator runbooks

Intended Documentation

Deploy and Rollback Policies

Promote a reviewed policy draft to an active version and roll back to a prior version — the real /policy/deploy/:draftId and /policy/rollback/:versionId lifecycle, plus the flat deploy-policy CLI. No fictional deploy command group.

Deploy and Rollback Policies#

This runbook covers the promotion end of the policy lifecycle: approving a reviewed draft, deploying it to an active version, and rolling back to a prior version when a change misbehaves. It picks up where Author a Policy and Simulate Impact leave off.

There is no `intended deploy …` command

Deployment and rollback run through the Policies API /policy/* lifecycle and the console. The CLI is flat: deploy-policy (alias policy-pack-install, which posts to /policy-packs/install) and policy-pack-inspect are the only deploy-adjacent verbs. There is no intended deploy status / approve / push / verify / rollback, no intended policy pin, and no per-deploy "decision token" — those do not exist. First-class deploy/rollback/pin CLI verbs are Roadmap.

Why deployment matters
A request flows through interpret, resolve, evaluate, issue, and enforce. The evaluate stage consults the active policy version and produces APPROVED (200), ESCALATED (202), or DENIED (403); a token is minted only on APPROVED. Deploying a draft swaps the version the evaluate stage reads.

Deploying a draft replaces the policy version the runtime's evaluate stage consults on every request. Roll back to restore the prior version instantly.

Prerequisites#

  • The authority:policy:write permission. Every lifecycle transition requires it, and each appends to the audit ledger.
  • A draft in the approved state. Deploy refuses to promote a draft that has not been approved.
  • Tenant scope aligned across credential, x-tenant-id, and body tenantId (else 403 TENANT_MISMATCH).

The lifecycle, end to end#

The governed promotion path is a fixed sequence. Each step is an explicit API call (or console action) — nothing auto-promotes.

StepCallResult
1. Submit to reviewPOST /policy/drafts/:id/reviewDraft enters review.
2. ApprovePOST /policy/drafts/:id/approveDraft becomes deployable.
3. DeployPOST /policy/deploy/:draftIdDraft becomes the active version.
4. Roll backPOST /policy/rollback/:versionIdA prior version becomes active again.

Reject instead of approve with POST /policy/drafts/:id/reject. Read state at any point with GET /policy/drafts/:id and GET /policy/packs/:pack/versions.

Step 1 — Approve the draft#

A reviewer who holds authority:policy:write approves. Separation of duties (author ≠ approver) is a process control you enforce in review; honor it.

bash
curl -X POST https://api.intended.so/policy/drafts/draft_123/approve \
  -H "Authorization: Bearer $INTENDED_API_KEY" \
  -H "x-tenant-id: tenant_acme_prod" \
  -H "Content-Type: application/json" \
  -d '{
    "tenantId": "tenant_acme_prod",
    "reviewerId": "user_security_lead",
    "comments": "Impact summary reviewed; changed-outcome rate 1.1%, recommendedMode review."
  }'

Tip

Read the draft impact summary one last time before approving — GET /policy/drafts/:id/impact-summary. Approving on a stale or lowData projection is the most common way a bad change reaches production.

Step 2 — Deploy#

Promote the approved draft to the active version.

Deploy the draft

bash
curl -X POST https://api.intended.so/policy/deploy/draft_123 \
  -H "Authorization: Bearer $INTENDED_API_KEY" \
  -H "x-tenant-id: tenant_acme_prod" \
  -H "Content-Type: application/json" \
  -d '{
    "tenantId": "tenant_acme_prod",
    "deployedBy": "user_admin",
    "comments": "Promote prod-release-controls v1."
  }'

The response is the newly active policy version. From this point, every /intent and /authority/evaluate for the tenant consults it.

Confirm what is active

Inspect the deployed versions for the pack:

bash
curl "https://api.intended.so/policy/packs/prod-release-controls/versions?tenantId=tenant_acme_prod" \
  -H "Authorization: Bearer $INTENDED_API_KEY" \
  -H "x-tenant-id: tenant_acme_prod"

The CLI offers a read-only inspection of installed policy packs:

$intended policy-pack-inspect

List the tenant's installed policy packs (read-only).

--tenantstring *
Tenant id (or configure tenantId / use --session).

Watch the runtime

After deploy, watch live decisions to confirm the change behaves as the impact summary projected:

$intended watch

Stream live authority decisions over SSE.

--tenantstring *
Tenant id.
--decisionstring
Filter: ALLOW | DENY | ESCALATE.
--min-riskstring
Only show decisions at or above this risk score.
bash
intended watch --tenant tenant_acme_prod --decision DENY

A sudden cluster of denials right after deploy is the signal to roll back.

Step 3 — Roll back#

If the deployed version misbehaves, restore a prior version. Roll back first, investigate second — do not fix-forward under pressure.

Danger

If you see unexpected denials or a spike in escalations after a deploy, roll back immediately. Rollback restores a known-good version atomically; debugging a live production policy under load is how a small regression becomes an outage.

bash
curl -X POST https://api.intended.so/policy/rollback/ver_prev \
  -H "Authorization: Bearer $INTENDED_API_KEY" \
  -H "x-tenant-id: tenant_acme_prod" \
  -H "Content-Type: application/json" \
  -d '{
    "tenantId": "tenant_acme_prod",
    "rolledBackBy": "user_admin",
    "comments": "Unexpected deny spike for svc-ci-bot after prod-release-controls v1."
  }'

:versionId is the prior version you want to restore — find it via GET /policy/packs/:pack/versions. The rollback appends to the audit ledger like every other transition.

Version pinning is Roadmap

There is no version-pin endpoint or intended policy pin command today. To freeze a policy, govern it through your change process and roll back any unwanted deploy. A first-class pin/hold control is Roadmap.

Failure modes#

StatusCodeCause
400validationBody failed schema (missing deployedBy / rolledBackBy, etc.).
400TENANT_MISMATCHBody tenant ≠ header/credential tenant.
401UNAUTHORIZEDNo valid credential.
403FORBIDDENMissing authority:policy:write.
409conflictDeploying a draft that is not in the approved state.
404not foundDraft or version id not found for this tenant.

Next steps#

Deploy and Rollback Policies | Intended