rotate-cli docs

Reference

Incident mode

Pre-declared scopes for vendor breaches. Rotate everything flagged in one command instead of assembling ad-hoc selectors.

The shape of an incident file

An incident lives at .rotate/incidents/<slug>.yaml in your repo. It declares a scope: which providers, optionally filtered by tag or metadata.

# .rotate/incidents/vercel-apr-2026.yaml
version: 1
id: vercel-apr-2026
published: "2026-04-18"
reference: "https://vercel.com/blog/apr-2026-oauth-incident"
severity: high
scope:
  - provider: clerk
    filter: { tag: non-sensitive }
  - provider: resend
  - provider: openai
    filter: { tag: non-sensitive }
  - provider: anthropic
  - provider: supabase
  ...

Running an incident

$ rotate-cli incident .rotate/incidents/vercel-apr-2026.yaml \
    --yes \
    --reason "context.ai OAuth incident" \
    --max-rotations 100

Dry run

See the plan without rotating anything:

$ rotate-cli incident <file> --dry-run

Flags

FlagMeaning
--dry-runPrint the plan, don't rotate.
--max-rotations <n>Hard cap, required in agent mode.
--skip-unknownSkip secrets where ownership can't be determined.
--force-rotate-otherRotate even if ownership says "other" (dangerous).
--no-ownership-checkDisable the gate entirely.

Why declarative? When a vendor breach happens, you don't want to improvise the selector. The incident file is checked into the repo, reviewed in a PR, and runs unchanged in both dry-run and real mode. Post-mortem has a single artifact.