sigil/docs/PROD_RUNBOOK.md
leora a609088bdc Fix N2: agent_keys history keeps checkpoints verifiable after revoke
Permanent revoke and rekey retired the live pubkey without retaining it,
so historical checkpoints and off-box anchors became permanently
unverifiable. Add append-only agent_keys (public material only); retire
on revoke/rekey; verify against the fingerprint-named historical key.
Document a dedicated checkpoint-signer identity in the runbook.
2026-10-06 06:28:01 +08:00

2.5 KiB

Sigil production runbook

Short checklist before Sigil guards anything real. Library-only today — do not enable platform glue until an integration review covers session minting.

Required environment

Variable Purpose Notes
SIGIL_DB Path to the store file Prefer a dedicated volume; backups are sensitive (roster + audit).
SIGIL_SEAL_PASS AES-256-GCM seal passphrase Required in prod. ≥12 chars. Without it the DB file is cleartext on disk. Seal-on still uses a plaintext 0600 working copy while the process is open — not SQLCipher.
SIGIL_ANCHOR Off-box signed tip path Required in prod. Must be on storage separate from SIGIL_DB (different volume/host). Every checkpoint publishes here; verify_external_anchors / verify-chain must alert on failure.

Optional: agent private keys stay off the platform host whenever possible; checkpoint signer key preferably offline.

Dedicated checkpoint-signer identity

Enrol a separate agent id used only for checkpoint / publish_anchor (for example sigil-checkpoint). Do not use a working agent as the tip signer: compromising and permanently revoking that agent would otherwise retire its key (history still verifies, but ops alerting on "key retired" gets noisy). Never store the checkpoint signer's private key in the Sigil DB — public history only.

Ops loop

  1. Open with seal + anchor configured (CLI respects the env vars above).
  2. Periodically run chain verify and external-anchor verify; page on failure.
  3. After permanent revoke (compromise): bootstrap + enrol_rekey, then reinstate. Reinstate alone does not restore a wiped key.
  4. Single writer process until a shared rate-limit store exists (in-process quotas multiply across processes).

Integration sharp edges (do not ignore)

  • Never mint issue_agent_session from a client-supplied name or header. Only after a verified challenge-response. Prefer keeping that helper internal to verified paths.
  • Human view codes are ~40 bits; keep TTL short; never log raw codes (already hashed in audit).
  • Challenge signatures today sign the raw nonce (no domain separation). Changing the signed payload needs a coordinated version bump — tracked as a follow-up, not a silent break.

Deferred

  • SQLCipher / page-level encryption for multi-tenant co-resident hosts.
  • Domain-separated challenge payloads (sigil-challenge-v1 prefix) — backward-incompatible without a protocol version.
  • Shared cross-process rate limiter.