Harden Sigil: DESIGN.md
This commit is contained in:
parent
a3dbdb4812
commit
57c07758ce
46
DESIGN.md
46
DESIGN.md
@ -152,23 +152,49 @@ it needs a human identity model of its own, which is a separate piece of work.
|
||||
|
||||
## Audit trail
|
||||
|
||||
Append-only, and the raw material for signed work attestations: every
|
||||
Hash-chained, and the raw material for signed work attestations: every
|
||||
enrolment, challenge, verification, code issuance, redemption, refusal and
|
||||
revocation, with actor, subject and key fingerprint. Code hashes are stored,
|
||||
never codes; enrolment secrets are hashed and deleted on use, so a database
|
||||
leak yields neither.
|
||||
revocation, with actor, subject and key fingerprint.
|
||||
|
||||
Each row folds in the previous row's digest, so editing or deleting an event
|
||||
breaks every digest after it, and `verify_chain` reports the first bad id. That
|
||||
makes tampering *detectable*. It does not make it *impossible*: an attacker with
|
||||
write access to the database can recompute the chain, because the digests are
|
||||
unkeyed. To commit to a log you need the head digest anchored outside the
|
||||
database's reach, or signed. Worth doing when the attestations start mattering,
|
||||
not before.
|
||||
|
||||
Secrets are not in the log and not in the database in the clear. Codes and
|
||||
session tokens are stored as digests, enrolment secrets are hashed and spent
|
||||
once. So a stolen database yields no live credential — which is only true
|
||||
because the review looked for it.
|
||||
|
||||
## Status
|
||||
|
||||
Working reference implementation with 54 passing tests. **Not production ready,
|
||||
and not reviewed.** Specifically missing: independent cryptographic review,
|
||||
encryption at rest, rate limiting on challenge issuance, agent revocation
|
||||
expiry, and transport assumptions. The tests show the logic is correct; they do
|
||||
not make it safe.
|
||||
80 passing tests, and a hardening pass that closed real defects. The worst were
|
||||
concurrency: one-time codes were redeemable repeatedly (753 sessions from 200
|
||||
codes under load), and a bootstrap secret could enrol more than one key. Those
|
||||
are now atomic compare-and-set operations, each covered by a test that races
|
||||
twelve threads. Session tokens are stored hashed, keys can be encrypted,
|
||||
challenge issuance is rate limited, rekey revokes old sessions, and the log is
|
||||
hash-chained.
|
||||
|
||||
**Still not production ready**, and the reason is not a to-do list:
|
||||
|
||||
- **No independent review.** Everything above is self-review. Self-review finds
|
||||
the bugs you already suspected. This needs someone else.
|
||||
- **The chain is unkeyed** — detectable, not tamper-proof (see *Audit trail*).
|
||||
- **The service is unwritten.** TLS, CSRF, transport, secret storage, routes.
|
||||
- **Revocation has no expiry semantics**, and there is no key recovery.
|
||||
- **Humans remain unattributable** to themselves, which is accepted and is a
|
||||
cost, not an oversight.
|
||||
|
||||
The tests show the logic is correct. They do not make it safe.
|
||||
|
||||
## Next
|
||||
|
||||
1. Independent security review before this guards anything real.
|
||||
1. Independent security review before this guards anything real. The hardening
|
||||
pass made it reviewable; it did not substitute for one.
|
||||
2. 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
|
||||
is the natural second piece.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user