ActionBoxBlog

SecuritySREPlatform

Secret rotation approval workflow: stage, approve, and swap safely

A copy-paste secret rotation approval workflow that stages a new credential, requires approval before production swap, and records audit evidence.

Secret rotation is the most skipped security control in production. The rotation script exists, but "nobody approved the swap" becomes "let's do it next quarter" — until the credential lands in a leak and the auditor asks why the rotation policy was ignored.

The fix isn't more automation. It's automation that stages the new credential, asks a human to approve the production swap, and records the approval — so rotation happens on schedule with evidence, not instead of it.

Secret rotation approval workflow: stage, ask, swap, record

bash
# 1. Rotate the credential in the vault (safe, no prod impact)
vault kv put secret/db/DATABASE_URL password=$(openssl rand -hex 32)

# 2. Ask for production sign-off, with context
actionbox ask "Swap DATABASE_URL to the rotated credential in production?" \
  --option swap="Swap now" \
  --option defer="Defer 24h" \
  --context-json '[{"type":"key_value","items":{"secret":"DATABASE_URL","rotation_policy":"90d","staging_tested":"true","incident_ticket":"none","expiry":"managed-by-vault"}}]' \
  --callback-url https://sec.acme.com/actionbox/swap-callback

The vault already has the new value; the human decides when the production swap happens. The callback performs the swap and writes the audit record.

Step 1: never let the gate block the safe part

Rotate in the vault first, gate the swap second. If nobody approves, the new credential just sits there — safe, unexpired, ready. Nothing broke, and the audit trail shows "rotation staged, swap deferred".

bash
# The callback must first verify X-Actionbox-Timestamp and
# X-Actionbox-Signature over "timestamp.raw_body" with the webhook secret.
case "$(jq -r '.data.response.value // .data.decision // empty' "$PAYLOAD")" in
  swap)
    ./scripts/swap-secret.sh DATABASE_URL
    ./scripts/record-rotation.sh DATABASE_URL "approved by on-call"
    ;;
  defer)
    ./scripts/record-rotation.sh DATABASE_URL "deferred 24h by on-call"
    ;;
esac

Step 2: compliance evidence without a spreadsheet

Auditors want three things: rotation happened on schedule, it was authorized, and the evidence wasn't altered. Every decision in Actionbox gives you all three:

  • Who approved (and that the approver is a named human, not the pipeline)
  • When (timestamped decision, not a Slack "done")
  • What ran (the decision payload, signed webhook, and audit trail)
bash
# Weekly audit summary: use the Actionbox History/API view filtered to the
# Source and resolved status. The CLI `get` command requires one Action ID.

This feeds SOC 2 CC8.1 / PCI-DSS 6.4.2 evidence collection directly — no manual compilation.

Step 3: emergency rotation still needs a gate

Compromised-credential rotations are urgent — but "urgent" doesn't mean "unapproved". Give the emergency path its own decision with a shorter SLA:

bash
actionbox ask "CRITICAL: rotate leaked API key for checkout service NOW?" \
  --option rotate="Rotate immediately" \
  --option verify="Verify leak first" \
  --context-json '[{"type":"key_value","items":{"secret":"checkout_api_key","leak_source":"public repo scan","revoked_elsewhere":"false"}}]' \
  --callback-url https://sec.acme.com/actionbox/emergency-rotate

Fail-closed on timeout: --on-expire-json '{"type":"return_expired"}' means no swap happens silently — the incident page fires instead.

The anti-pattern to avoid

Don't put the decision after the swap, or in a separate approval system nobody checks. The most common rotation failure is the "approve in the ticket system" flow: the ticket sits for two weeks, the rotation policy lapses, and the audit trail is a ticket status. Keep the decision in the rotation pipeline where the action actually happens.

Try it

  1. Create a Source → ACTIONBOX_TOKEN (rotate your Source token on a schedule too — it's an Actionbox Action)
  2. Stage a rotation in your vault, then run the ask command above
  3. Watch the dashboard countdown and the audit trail record the swap

Create a free Source · Webhook + callback reference · Cron jobs that ask before acting

Try this workflow in minutes

Create a free Source, then run the exact commands from this post against the live API — no approval infrastructure to build.

S
Suson Sapkota

Founder, Actionbox