Fix R11: pin cryptography; prod runbook for SIGIL_ANCHOR + SIGIL_SEAL_PASS #11
22
DESIGN.md
22
DESIGN.md
@ -229,7 +229,7 @@ sessions mintable from a bare agent name, no revocation operation at all, an
|
|||||||
unkeyed chain that a database-level attacker could rebuild, and SQLite without
|
unkeyed chain that a database-level attacker could rebuild, and SQLite without
|
||||||
a busy timeout.
|
a busy timeout.
|
||||||
|
|
||||||
Leora's contracted prod pass (Quarry 18a5d762) closed three remaining review blockers on this branch: rekey no longer un-revokes, dual-bootstrap enrol is exactly-one under race, and redeem rate limits are per-agent (anonymous fails isolated from success). Off-box checkpoint tip publish/verify ships when `anchor_path` / `SIGIL_ANCHOR` is set. SealedStore / `SIGIL_SEAL_PASS` seals the DB file with AES-256-GCM (incremental path short of SQLCipher). Independent review and platform glue remain.
|
Leora's contracted prod pass (Quarry 18a5d762) closed three remaining review blockers on this branch: rekey no longer un-revokes, dual-bootstrap enrol is exactly-one under race, and redeem rate limits are per-agent (anonymous fails isolated from success). Off-box checkpoint tip publish/verify ships when `anchor_path` / `SIGIL_ANCHOR` is set. SealedStore / `SIGIL_SEAL_PASS` seals the DB file with AES-256-GCM (incremental path short of SQLCipher). Independent review returned GO-WITH-FIXES; R1–R8/R11 fixes on this branch. Platform glue remains off.
|
||||||
|
|
||||||
**Still not production ready**, and the reason is not a to-do list:
|
**Still not production ready**, and the reason is not a to-do list:
|
||||||
|
|
||||||
@ -252,11 +252,27 @@ The tests show the logic is correct. They do not make it safe.
|
|||||||
|
|
||||||
## Next
|
## Next
|
||||||
|
|
||||||
1. Independent security review before this guards anything real. Two hardening
|
1. ~~Independent security review~~ — independent review returned GO-WITH-FIXES
|
||||||
passes made it reviewable; neither substituted for one.
|
(tip c0027bb); fix PRs for R1–R8/R11 landed on `sigil-initial`. Platform glue
|
||||||
|
remains off until integration review. See `docs/PROD_RUNBOOK.md`.
|
||||||
2. ~~Anchor the checkpoint head digest outside the database~~ — done via
|
2. ~~Anchor the checkpoint head digest outside the database~~ — done via
|
||||||
`Store(..., anchor_path=)` / `SIGIL_ANCHOR` (signed tip file + `.log`).
|
`Store(..., anchor_path=)` / `SIGIL_ANCHOR` (signed tip file + `.log`).
|
||||||
|
**Prod must set it** (see runbook).
|
||||||
3. Secret broker on top — scoped, short-lived leases bound to a key fingerprint.
|
3. Secret broker on top — scoped, short-lived leases bound to a key fingerprint.
|
||||||
Its issuance and redemption logs *are* the work-attestation substrate, so it
|
Its issuance and redemption logs *are* the work-attestation substrate, so it
|
||||||
is the natural second piece.
|
is the natural second piece.
|
||||||
4. Deprecate passcode login across the platform, then rotate live credentials.
|
4. Deprecate passcode login across the platform, then rotate live credentials.
|
||||||
|
|
||||||
|
### Info / follow-ups (no code change required yet)
|
||||||
|
|
||||||
|
- **R9 — `issue_agent_session`:** library helper mints `agent:act` from a name
|
||||||
|
after the caller claims to have verified. Keep internal; integration must
|
||||||
|
never mint from headers/names. Consider renaming to `_issue_agent_session`.
|
||||||
|
- **R10 — challenge domain separation:** signatures currently cover
|
||||||
|
`nonce.encode()` with no context prefix. Adding
|
||||||
|
`b"sigil-challenge-v1\0" + nonce` is not backward-compatible with in-flight
|
||||||
|
challenges; schedule with a protocol version bump (follow-up).
|
||||||
|
- **R12 — multi-process rate limits:** quotas are per-`Store` / per-process.
|
||||||
|
Single writer until a shared limiter exists (documented in README + runbook).
|
||||||
|
- **R13 — opt-in anchor:** without `SIGIL_ANCHOR`, deleting in-DB checkpoints
|
||||||
|
allows silent history rewrite. Runbook requires the anchor on separate storage.
|
||||||
|
|||||||
@ -159,3 +159,8 @@ The tests assert the logic is correct. They do not make it safe.
|
|||||||
|
|
||||||
`DESIGN.md` — the design page: rationale, flows, session stamps, the invariant
|
`DESIGN.md` — the design page: rationale, flows, session stamps, the invariant
|
||||||
and its reasoning, and what is deferred.
|
and its reasoning, and what is deferred.
|
||||||
|
|
||||||
|
`docs/PROD_RUNBOOK.md` — production checklist: require `SIGIL_SEAL_PASS` and
|
||||||
|
`SIGIL_ANCHOR` on separate storage, verify-chain alerts, integration sharp edges.
|
||||||
|
|
||||||
|
`requirements.txt` — pinned `cryptography>=43.0.0,<45`.
|
||||||
|
|||||||
33
docs/PROD_RUNBOOK.md
Normal file
33
docs/PROD_RUNBOOK.md
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
# 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.
|
||||||
|
|
||||||
|
## 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.
|
||||||
3
requirements.txt
Normal file
3
requirements.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# Runtime dependency for Ed25519 + AES-GCM (SealedStore / optional key files).
|
||||||
|
# Pin a known-good lower bound; upper bound avoids surprise major breaks in CI.
|
||||||
|
cryptography>=43.0.0,<45
|
||||||
Loading…
x
Reference in New Issue
Block a user