@fortress_os/provenance-sdk
v1.0.0
Published
EU-sovereign, offline invisible watermarking + bit-exact tamper-evidence across image/video/audio/text/code/data. 11 per-use-case facades. Self-verifying resilient survival; signed-hash fragile integrity. $0 API.
Maintainers
Readme
@fortress/provenance-sdk
EU-sovereign, offline invisible watermarking + content provenance. One package for:
- Resilient marks → forensic leak-tracing / anti-piracy (survive the distribution pipeline).
- Fragile marks → authenticity / tamper-evidence (break on any edit).
- Text/code copy detection → robust provenance fingerprinting (no hidden bits to strip).
No cloud, no API, no GPU. Every number below is reproduced by npm test. Boundaries are stated, not hidden (Rule 9 / Documentation/SSOT/BENCHMARK_TRUTH.md).
Eleven per-use-case facades (pick the right one — never mix)
const {
// RESILIENT — survive distribution → attribution / leak-tracing
ContentProvenance, // AI-content image attribution (EU AI Act Art.50)
AntiPiracy, // studio leak-tracing, crop-hardened stills
VideoProvenance, // per-frame video + temporal majority (H.264)
AudioProvenance, // audio through MP3 128/64 kbps
TextProvenance, // text/code copy + paraphrase (fingerprint, no hidden bits)
DataProvenance, // JSON/CSV rows (float jitter + row-permutation codec)
// FRAGILE — shatter on edit → authenticity / tamper-evidence
LivenessAuthenticity,// KYC injection/replay
ScienceIntegrity, // scientific-image integrity
CaptureAttestation, // creator "captured live & unaltered" badge — LIVE-CAPTURE ONLY, NOT "not AI"
TamperSeal, // bit-exact signed-hash tamper-evidence — ANY modality, ANY 1-bit change
// TOOLING
LeakScanner, // crawled suspect media → recipient (correct DC-QIM, not LL-STDM)
} = require('@fortress/provenance-sdk/markets');Each facade hardcodes its validated profile so you cannot pick the wrong engine for a use case.
Decision table + params: Documentation/SSOT/USE_CASE_TO_SDK_MAP.md. Crawler wiring: CRAWLER_INTEGRATION.md.
The "is it AI?" badge — honest scope (Rule 9)
CaptureAttestation proves "this exact file is unaltered since we sealed it" — NOT "not AI-generated".
Software cannot prove sensor origin; true camera-origin needs hardware (L3 Play Integrity / L4 on-sensor).
The SDK refuses to assert it (attestation.assertsCameraOrigin === false). See Documentation/STRATEGY/Creator_Platform_Shipping_Kit.md §3.
Install & use
const { FortressProvenance } = require('@fortress/provenance-sdk');
const fp = new FortressProvenance({ merchant: 'did:ohm:acme-media' });
// 1) Per-recipient leak-tracing (image; grayscale 1024x1024 Uint8/Float array)
const { pixels, keyHex } = fp.embedImage(gray, 'subscriber-0042'); // profile: 'stealth' (default)
const hit = fp.extractImage(suspectGray); // → { found, keyHex } (look keyHex up in your registry)
// crop-hardened profile (survives crop up to ~50%, slightly more visible)
const c = fp.embedImage(gray, 'subscriber-0042', { profile: 'crop-hardened' });
const hit2 = fp.extractImage(croppedSuspect, { profile: 'crop-hardened' }); // → { found, keyHex, via:'crop' }
// 2) Authenticity / tamper-evidence (fragile)
const a = fp.embedAuthenticity(gray, 'asset-001');
fp.verifyAuthenticity(suspect, a.keyHex); // → { authentic, tamperDetected }
// 3) Text / code copy detection (paragraph-length text; any code)
const sig = fp.fingerprintCode(originalCode);
fp.matchProvenance(sig, fp.fingerprintCode(suspectCode)); // → { similarity, isCopy }
// 4) Evidence package (DSR / provenance report)
fp.generateEvidence({ recipientId, assetId, keyHex, suspectUrl });Validated capability scorecard (reproduced)
| Capability | Result | Profile | |---|---|---| | Image vs JPEG/recolor/noise/≤75% resize | 100% | stealth (~32 dB, margin 250) | | Image crop 10–50% (centered + off-center, ±H.264) | 100% (crop+H.264 80–100%) | crop-hardened (24 dB) | | Video — real H.264 CRF 18–35 | BER 0% | (backend video engine) | | Audio — real MP3 128/64 kbps | recovered, conf 0.97 | (backend audio engine) | | Fragile: reads original / detects screenshot+AI-edit | 100% / 100% (40 dB) | fragile | | Code copy: reformat + rename + comments | 100% | fingerprint | | Text copy: whitespace/case 100%, sentence-reorder 75%, light-reword 40% | — | fingerprint |
Profiles
- stealth — most invisible (~28–30 dB); full distribution-pipeline survival; no crop recovery.
- crop-hardened — full-key 4×4 tiling (24 dB); adds centered/off-center crop ≤50% + crop-after-H.264.
- fragile — ~40 dB; reads the untouched original, breaks on any manipulation (tamper-evidence / liveness).
Honest boundaries (do NOT claim past these)
- Generative AI redraw destroys the resilient mark (information-theoretic) — that destruction is the basis of the fragile product, not a defect.
- Crops >50%, blind crop+rotation combined, full 6-DoF affine — open R&D (precisely bounded in
BENCHMARK_TRUTH.md). - Text/code: full semantic rewrite / refactor escapes the fingerprint (info-theoretic). Text needs paragraph-length input (≥~30 words) for a reliable fingerprint. Heavy paraphrase is weak (≈1%); pair with a semantic-embedding layer for that.
- keyHex → recipient mapping is the integrator's responsibility (keep a registry;
LeakScannerdoes this for you). Image API expects a 1024×1024 grayscale array. Video and audio use the same validated DC-QIM engine as images (NOT the LL-STDM stream engine — that one is JPEG-fragile and is for live-stream screenshots only).
Video, audio & CLI
// VIDEO — per grayscale frame (validated through real H.264 CRF28, 31 dB)
const v = fp.embedVideoFrame(grayFrame, 'subscriber-0042');
const hits = frames.map(f => fp.extractVideoFrame(f));
fp.extractVideoMajority(hits); // → { found, keyHex, votes } (temporal majority vote)
// AUDIO — mono PCM Float32 [-1,1] (validated through real MP3 128 kbps)
const a = fp.embedAudio(pcm, 'subscriber-0042'); // a.pcm (SNR ~20 dB — tune _audioEngine margin for your loudness target)
fp.extractAudio(suspectPcm); // → { found, keyHex } (half-block sliding window handles codec delay)# CLI (image I/O via ffmpeg)
fortress mark cover.png subscriber-0042 --profile crop-hardened --out cover.marked.png
fortress trace suspect.png --profile crop-hardened # → recovered key → look up recipient
fortress match original.js suspect.js # → code/text copy similarity
fortress key subscriber-0042Media validated: npm run test:media (real ffmpeg H.264 + MP3) → 4/4 PASS.
Caveat: pure black/white synthetic patterns (e.g. color-bar test charts) clip at 0/255 and weaken the mark — real photographic/video content is unaffected. Audio SNR ~20 dB is a pilot default; lower the margin for inaudibility (trades codec-robustness).
Reproduce
npm test # smoke 7/7 + market 22/22 + signer 4/4 (10 facades incl. badge + leak-scanner + data)
npm run test:media # media-test.cjs → 4/4 PASS (real H.264 + MP3 via ffmpeg)
npm run demo # 7 demos exit 0 (incl. demos/data.cjs + demos/creator-platform.cjs)Engines are faithful re-expressions of fortress-dwt-v3.engine.ts, cross-validated bit-for-bit (Δ 0.00 dB). Full truth registry: Documentation/SSOT/BENCHMARK_TRUTH.md; engine map: ENGINE_REGISTRY.md.
