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.
42 lines
2.5 KiB
Markdown
42 lines
2.5 KiB
Markdown
# 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.
|