Oversight Protocol

An open protocol for cryptographic data provenance, recipient attribution, and leak detection. Seal documents to named recipients with layered watermarks, post-quantum encryption, and tamper-evident transparency logs.

14,500+
Lines of Code
100+
Tests
2
Languages
11
Rust Crates

Key Capabilities

Recipient-Bound Encryption

Each sealed document is encrypted to a specific recipient using X25519 key agreement and XChaCha20-Poly1305 authenticated encryption. The recipient's identity is bound into the ciphertext, so a valid seal can only be opened by the intended party. No shared secrets leave the sender's machine.

Multi-Layer Watermarking

Three independent watermark layers provide defense in depth against removal. Layer 1 inserts zero-width Unicode characters that survive copy-paste. Layer 2 manipulates trailing whitespace patterns per line. Layer 3 performs semantic synonym substitution guided by a controlled vocabulary, producing marks that persist even through manual retyping.

Post-Quantum Hybrid Mode

An optional hybrid suite combines ML-KEM-768 (FIPS 203) with X25519 for key agreement, and ML-DSA-65 (FIPS 204) with Ed25519 for signatures. If a future quantum adversary breaks elliptic-curve assumptions, the lattice component keeps the document sealed. If lattice assumptions weaken first, X25519 still holds.

RFC 3161 Qualified Timestamps

Every seal carries an RFC 3161 timestamp from a third-party TSA (FreeTSA primary, DigiCert fallback). The timestamp proves the document existed in a specific form at a specific time, independent of the sender's clock. Tokens are embedded in the seal and verifiable by anyone with the TSA's root certificate.

Passive Beacons

Sealed documents can carry passive beacons that fire on open: DNS lookups against a controlled nameserver, HTTP tracking pixels, or OCSP callbacks. No code executes on the reader's machine. The beacon encodes the recipient fingerprint, so a network-layer signal reaches the issuer when a seal is opened.

RFC 6962 Transparency Logging

Every seal event goes into an append-only Merkle tree following the RFC 6962 Certificate Transparency spec. Entries get a signed tree head and an inclusion proof, so any auditor can verify that a seal was logged without trusting the log operator. Consistency proofs make silent deletion or rewriting detectable.

Policy Enforcement

Each seal can carry access constraints: time windows (the document expires after a deadline), maximum open counts (TOCTOU-safe via flock and atomic rename), and jurisdiction restrictions by IP geolocation. The client checks policy before decryption and logs violations to the transparency tree.

Format Adapters

The seal pipeline works on plaintext, images (LSB embedding in the Y channel), PDF (annotation-layer injection), and DOCX (Open XML field codes). Each format has a dedicated adapter that normalizes content for watermarking and reconstructs the output after decryption. More formats are straightforward to add.

Architecture Overview

Plaintext Watermark Encrypt Timestamp Log Seal

A source document enters the pipeline and gets watermarked with all three layers, with each recipient's copy receiving a unique mark derived from their public key. The watermarked content is then encrypted via X25519 (or hybrid ML-KEM-768 + X25519) key agreement and XChaCha20-Poly1305, then signed with the issuer's Ed25519 key.

Before delivery, the content hash goes to an RFC 3161 timestamp authority and gets appended to the Merkle tree. The final .sealed file bundles the ciphertext, signature, timestamp token, inclusion proof, beacons, and policy. On the other end, the open operation verifies the proof, checks the timestamp, enforces policy, decrypts, and hands back the readable document with the watermark metadata intact for forensic recovery if the content leaks later.

Current Status

Current stable v0.4.11 is the current tagged release. It closes the OSGT-HW-P256-v1 hardware-suite path across the Python core, Rust workspace, and public browser inspector. Since the tag, main has also gained live registry deployment docs, shared operator-token enforcement, Python-to-Rust SQLite migration tooling, stricter Rust registry burn-in validation, fail-closed local tlog recovery, Rust PDF/image format parity, and mobile CI privacy guards. Release notes: v0.4.11 on GitHub. Latest development note: A Week of Boring Hardening.

Shipped Mobile verifier (v0.1.11) is on TestFlight as of 2026-04-26. The oversight-protocol/oversight-mobile repo is a Flutter UI on top of the same Rust crates that power the desktop CLI, embedded via flutter_rust_bridge. Verification is bit-identical with the desktop. The whole iOS pipeline runs on GitHub-hosted macOS runners (macos-26, Xcode 26, iOS 26 SDK) so the project does not require Apple hardware to ship. Reproducible mobile builds are next on the roadmap. Status page: Mobile Verifier. Writeup: Mobile beta is live — and the Apple-side gotcha that nearly hid it.

Shipped The browser-based Sealed File Inspector is live. Drop a .sealed file to parse the container, verify the issuer's Ed25519 signature via WebCrypto, and read the manifest, watermarks, beacons, and policy directly in the browser. Optional registry lookup against the URL the manifest declares. Nothing leaves the device unless the inspector is asked to hit the registry. This closes the non-technical-recipient gap that has been blocking the broad public launch.

Shipped v0.4.11 closes the OSGT-HW-P256-v1 surface across every reference implementation. The Python core, the Rust workspace, and the public browser inspector now all decrypt hardware-suite sealed files. The /viewer/ page accepts a hardware tutorial identity via a new "Load hardware P-256 tutorial identity" button; the underlying ECDH runs against a vendored, pinned copy of @noble/curves NIST P-256, with imports rewritten to relative file paths so the inspector remains fully offline-capable. Every layer of the protocol now ships every suite (classic, hybrid, hardware P-256); the only piece deferred to a follow-up is the PivKeyProvider against PKCS#11 and the matching --recipient-hw CLI flag. Release notes: v0.4.11 on GitHub.

Shipped v0.4.10 lands the hardware-keys foundation in Rust. oversight-crypto now exposes a KeyProvider trait that abstracts the recipient-side ECDH so a hardware-backed token (YubiKey / Nitrokey / OnlyKey via PIV) can plug into the open path without changing call sites. FileKeyProvider is the X25519 default. The hardware-track suite OSGT-HW-P256-v1 is fully implemented in software: wrap_dek_for_recipient_p256, WrappedDekP256, and SoftwareP256KeyProvider (NIST P-256 ECDH via RustCrypto's p256). oversight-container recognizes the new suite id (3) so sealed files for hardware recipients ride the existing 1-byte header dispatch without a layout change. The PivKeyProvider (PKCS#11) implementation is the next bounded follow-up; the trait and software reference let it ship without touching seal-side or container code. Public API is purely additive; v0.4.9 callers are unchanged. Setup guide: docs/HARDWARE_KEYS.md. Release notes: v0.4.10 on GitHub.

Shipped v0.4.9: the browser inspector now decrypts hybrid (post-quantum) sealed files end-to-end, alongside the classic suite that already worked. ML-KEM-768 lands via a vendored copy of @noble/post-quantum; X25519 and HKDF-SHA256 stay on WebCrypto; XChaCha20-Poly1305 stays on the vendored @noble/ciphers. The KEK binds both shared secrets and both ephemeral inputs X-wing-style so an attacker has to break X25519 and ML-KEM-768 to recover content. The Rust registry under oversight-rust/oversight-registry now passes the v1 conformance harness (33/33), with a strict CORS surface on GET/OPTIONS for the public inspector origins. Try the hybrid path with the "Load hybrid tutorial identity" button at /viewer/. Writeup: Development Log: Rust Registry v1, Hybrid Viewer Samples, and Watermark Round Trips.

Shipped Outlook add-in scaffold landed 2026-05-07 as the first ecosystem integration. Office 1.1 MailApp manifest, task pane HTML/JS, and icons are hosted at /integrations/outlook/. The task pane imports the public viewer's parseSealed, verifyManifestSignature, and decryptSealed directly from the same origin, so there is no second crypto stack to audit. Both classic and hybrid (post-quantum) suites decrypt inside the task pane; the manifest requests ReadItem only and is ready for sideload against a Microsoft 365 dev tenant. Architecture decision record: docs/OUTLOOK.md. Visual design pass and a real tenant load-test are the remaining work; the protocol-side surface is complete.

Shipped v0.4.7 hardened registry federation. docs/spec/registry-v1.md is now pinned against the reference implementation with the canonicalization algorithm, the uniform error envelope, the full endpoint list including normative beacon paths, and the evidence bundle fields fixed. A 32-check conformance harness at tests/test_registry_conformance.py runs either against the reference registry in-process or against a live operator URL, so an independent deployment can claim v1 compatibility with evidence. Run it with OVERSIGHT_REGISTRY_URL=https://registry.example.org python3 tests/test_registry_conformance.py. Writeup: v0.4.7: Registry Federation Conformance Is a Test, Not a Document.

Shipped v0.4.6 brought SIEM export. Registry beacon events now ship in three SIEM-native formats so security teams get Oversight telemetry into the incident pipeline they already run. oversight_core.siem provides pure formatters for Splunk HEC, Elastic Common Schema 8.x, and Microsoft Sentinel Log Analytics, plus a Sentinel HMAC signing helper and minimal file, stdout, and HTTP sinks. The oversight siem export CLI streams events as JSON lines, reading the registry database in read-only mode so it is safe to run against a live service. The operator guide lives at docs/SIEM.md. Writeup: v0.4.6: SIEM Export for Splunk, Sentinel, and Elastic.

Shipped v0.4.5 made L3 semantic watermarking a safety-first feature. L3 defaults off for wording-sensitive document classes (legal, regulatory, technical specifications, source code, SQL, logs, structured data), requires an explicit acknowledgement when enabled because the recipient copy is textually non-identical to the canonical source, and supports a boilerplate-only mode for contracts and filings. The manifest records canonical_content_hash and l3_policy so disputes can reach ground truth. v0.4.5 also shipped an oversight gui Tkinter starter, raised PyPI dependency floors after a Dependabot follow-up, and published the public threat model at research/threat-model.html. Writeup: v0.4.5: L3 Semantic Watermark Safety and GUI Starter.

Shipped v0.4.4 closed a security hardening pass that resolved nine findings across the policy engine, Rekor verification, registry input validation, and the container format. Failed decryption attempts no longer consume open counts. REGISTRY and HYBRID policy modes fail closed instead of silently falling back to local state. The registry rejects unsigned beacon and watermark sidecars that differ from the signed manifest. DNS event callbacks to the registry require a shared OVERSIGHT_DNS_EVENT_SECRET for non-loopback callers. Multi-recipient sealing is disabled until the manifest format can honestly bind every recipient. Writeup: v0.4.4: Nine Security Findings and the Discipline of Failing Closed.

Live The attribution registry and beacon infrastructure are deployed at registry.oversightprotocol.dev. HTTP, OCSP, DNS, and license beacons are operational. Install with pip install . from the repository, run oversight keygen, and seal your first file. For a desktop entry point, run oversight gui to launch the Tkinter starter. To wire beacons into an existing SIEM, oversight siem export --format splunk|ecs|sentinel emits registry events in the native schema of each.

Shipped v0.5 integrated Sigstore Rekor v2 for public transparency attestations. Seal registrations are now recorded in the Sigstore public log via DSSE envelopes, verifiable by any auditor using standard Sigstore tooling without Oversight-specific code.

Shipped v0.6 format adapters ported to Rust: text (fully functional L1/L2/L3), PDF (annotation layer + JS/Launch rejection), DOCX (Open XML + field code sanitization), and image (Y-channel LSB, imperceptible). The Rust CLI auto-detects input format.

In Progress v1.0 registry port to Rust Axum + SQLx is scaffolded with all registry v1 endpoints implemented under #![forbid(unsafe_code)]. The Axum server now matches Python operator-token auth and DNS bridge auth, and oversight-registry --migrate-from can copy Python registry SQLite rows into the Rust schema. The burn-in validator now checks attribution relationships, signed manifests, event sidecar JSON, tlog index uniqueness, tlog index ranges, tlog leaf payload consistency, and local tlog recovery integrity. Pending: longer-running deployment tests and a wire format stability declaration. Registry federation is a v1.0 prerequisite and is tracked in docs/spec/registry-v1.md.