Omitly ยท Security

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/getrandom are 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.