Security model โ Omitly
What Omitly's cryptography and redaction assert, and what they do not, after the
2026-06 crypto audit. The full public threat model is in docs/THREAT-MODEL.md; the
audit report is at ../security/crypto-audit-2026-06/.
The machine-readable cryptographic inventory (CBOM) this document's language is
kept in sync with lives in crypto-bom.yaml; the software bill of materials
(SBOM, including vendored assets like fonts and models) is generated in CI
(../harness/innisfallen-ci/.github/workflows/deps.yml).
The tamper-evidence seal
Asserts: the delivered PDF โ visible content and the embedded audit report alike โ
has not been altered since it was sealed. The signature is Ed25519 over the entire
delivered file (a trailing %%OMITLY-SEAL appendix); verification recomputes the hash
over the bytes the holder presents and fails on any mismatch (verify_strict).
Does NOT assert โ important: the seal is integrity, not identity. The signing key is per-install, so a valid seal means "unchanged since sealed by the holder of this key", not "produced by Omitly". Anyone can generate a key and self-sign. The verifier surfaces the key fingerprint for out-of-band comparison rather than claiming origin. Do not market the seal as proof of Omitly origin. (Vendor-anchored notarization โ a pinned vendor key, co-signed online โ is a roadmap/Pro option; it would require a hash to leave the machine and is out of scope for the local-only seal.)
Limitation: a downstream PDF normaliser that rewrites the file drops the trailing appendix โ verification reports "no valid seal" (a fail, never a false pass). A PAdES ByteRange in-document signature is the future upgrade.
Redaction completeness
Asserts: text glyphs are removed from page content streams (not just covered), images intersecting a region are painted/dropped, metadata/XMP/markup annotations are scrubbed, and the output is independently re-verified (geometric re-walk + raw-byte survivor scan).
Default-deny boundary: content rendered from annotation/form-field appearance streams
(/AP), inline images, and exotic constructs (Type3, patterns) is NOT removed by the
page-content rewrite. When such a path intersects a region the result is forced to
all_passed = false with a warning โ Omitly refuses to claim success rather than leak
under a box. Flattening AcroForm appearance streams into page content is a tracked
follow-up (O-3 real fix).
FIPS / PQC posture
- Ed25519 (FIPS 186-5) and SHA-256 (FIPS 180-4) are FIPS-approved algorithms, but
ed25519-dalek/sha2/getrandomare not CMVP-validated modules. Claim "approved algorithms, non-validated implementation" โ not "FIPS compliant". - The seal protects long-lived document integrity, so it is a natural future home for a post-quantum signature. SLH-DSA (FIPS 205) โ conservative, hash-based โ is the recommended target (hybrid Ed25519 + SLH-DSA), once the algorithm-driven verify path is generalised. (Moot until trust-anchor semantics are settled, see above.)
Tracked follow-ups
O-4/O-7 key at rest in the OS keystore + zeroize; W-1 WASM provenance/checksum; W-2 pin the published npm entrypoints; W-3 CSP + analytics off the leak-checker page. See audit ยง8.