You don't have to trust us. That's the whole point.
Every camera company promises privacy. SecuraCV is built so the promise is math you can check yourself — with the same math the device uses, right here in your browser. Nothing leaves this page. New word? The glossary defines each one in a sentence.
Three ideas do all the work
Start with the kernelA normal camera records everything. This one is built to refuse.
At the center of SecuraCV is the witness kernel — the software you install at home, and the gatekeeper every detection passes through before anything is stored or sent. It isn't a camera app that tries to be private; the invasive features are left out, not switched off.
In plain terms: think of the kernel as a one-way mail slot bolted onto a locked room. The camera and its raw video live inside the room. The kernel is the only slot out — and it's shaped so only a short, hand-written sentence can fit through it (“someone is at the front door”), never the picture itself. There's no bigger slot, because a bigger slot was never built.
The path a moment takes through the kernel
watch itThe raw frame is marked private — it physically stays in the room. Only a signed, coarse claim is allowed to leave.
Why that's different — and useful to you: on an ordinary camera, “don't record faces” is a setting, and settings can be flipped — by an update, an admin, a breach, or a subpoena. Here, the face-recognition code was never written, and sealed video leaves only when a quorum of trustees approves. There is no switch to flip.
Privacy by absence, not by setting
What the kernel emits
- Motion & object events — "Package detected at front door" (the default build detects motion only; object classes come from Frigate or the opt-in ONNX backend)
What has no code at all
- Face, plate & gait recognition — No code for this exists
- Cross-camera tracking — No code for this exists
- Solo video export — Requires multiple trustees to approve
Three intentional constraints
Events only, not video
The output is a log of what happened. There's no API to stream or export continuous video.
Rules apply forward only
A new detection rule can't be run over past records — no retroactive surveillance.
Multi-party video access
Raw footage requires approval from multiple trustees; one approval alone doesn't release it.
The one sentence that leaves is signed. Try to fake it.
When a Canary lets a claim out, it stamps it with a digital signature. Below is a real one, made in your browser this second with the same method (Ed25519) the device uses. Watch it verify, then rewrite the record and watch the stamp catch you.
In plain terms: a signature is a wax seal that only one secret ring can press, but that anyone can recognize. The device keeps the ring (its private key) on its own chip and never shares it. It hands out only a picture of the seal (its public key), so anyone can check its stamps and no one else can press one. Not even us.
A live claim, signed on this page
real Ed25519This device's public key fingerprint — the thing you'd check a stamp against:
- public key
- generating…
- signature
- —
The claim the witness is making. Drag to rewrite what it says — as an attacker would:
These are the real bytes generated on this page — not a picture of bytes. Forge the record above and the signature can't follow it.
// build the same message the device signs, then sign + verify it
function canonical(c, hash) {
return "securacv-canary-sig|v1|presence|" + id +
"|occupants=" + c.occupants +
"|range_m=" + c.range_m + "|" + hash;
}
sig = await crypto.subtle.sign("Ed25519", privKey, msg);
ok = await crypto.subtle.verify("Ed25519", pubKey, sig, msg);
// firmware/projects/canary-display/src/trust.cpp
// rebuild the locked canonical, then verify the stamp
snprintf(canonical, sizeof(canonical),
"%s|v%d|chain|%s|%lu|%s",
SIG_PREFIX, SCHEMA_V, device_id, length, latest_hash_hex);
const bool ok = Ed25519::verify(sig, pubkey,
(const uint8_t*)canonical, n);
Same handshake, both sides. The browser and the chip build the
byte-for-byte identical message
(securacv-canary-sig|v1|…) before they
sign or check it — so anyone can re-check a real Canary's claim without us.
For makers: what “Ed25519” actually is — and the one-character avalanche
Ed25519 is a specific, well-tested recipe for that seal. Four facts make it trustworthy.
- 1It's a one-way street. Going from the secret private key to the public key is easy; going back is, as far as anyone knows, out of reach. That gap is the entire foundation.
- 2A signature is welded to the exact message. It's not a sticker — it's a number computed from the secret and every byte of the claim. Flip one character and the only valid signature changes completely. (That's what you just did to break it.)
- 3Checking needs only the public half. Anyone with the public key can confirm a signature could only have come from the matching private key, over that exact message — without ever learning the secret. Anyone can check it; producing one takes the private key.
- 4Why this recipe. Small keys and signatures, quick on a cheap chip, and deterministic — it never gambles on fresh randomness when it signs, a mistake that has leaked real keys elsewhere. It's the same standard behind SSH logins and Signal.
The one-character avalanche — why there's no “almost right”
Before it's signed, every claim is boiled down to a 32-byte fingerprint (a SHA-256 hash). Edit the record below by a single character and watch its fingerprint — a real hash, recomputed as you type. The blue tiles are the bytes that changed.
Why that's different — and useful to you: the secret that makes the stamp never leaves the device. We can't sign a fake “nobody was home” in your camera's name, and neither can a hacker who breaks into a server we don't have. You can trust the record without trusting us.
Every record remembers the one before it. Break one, break the rest.
One signed claim is good; a history you can't secretly edit is better. The kernel writes each event into a hash chain: every new record carries a fingerprint of the one before it. Change any past record, even by one character, and every record after it stops adding up. Try it.
In plain terms: imagine a ledger where each new page begins by copying a summary of the previous page. Tear out or edit page 3, and pages 4, 5 and 6 no longer match the summaries they promised to carry. You can't quietly fix the past — the math tattles.
A real hash chain — edit any record
real SHA-256Each fingerprint below is a genuine SHA-256, computed in your browser as you type. Change a payload and watch the breakage cascade downstream.
/// Hashes a log entry with the previous chain hash.
pub fn hash_entry(prev_hash: &[u8; 32], payload: &[u8]) -> [u8; 32] {
let mut hasher = Sha256::new();
hasher.update(prev_hash); // ← the fold: last hash…
hasher.update(payload); // …mixed with this record
hasher.finalize().into()
}
let prev_hash = store.last_event_hash_or_checkpoint_head()?;
let entry_hash = hash_entry(&prev_hash, payload_json.as_bytes());
let signature = sign_entry(keys, &entry_hash, DOMAIN_SEALED_LOG_ENTRY)?;
// the new record is now both chained AND signed — three lines.
That's the whole trick. Each hash folds in the one before it, so the newest fingerprint
vouches for the entire history. The demo runs the same
SHA-256(previous + record) the kernel does.
Why that's different — and useful to you: quietly deleting the event where they walked past your door, or backdating one that never happened, breaks the chain — for an intruder, for us, even for you. Anyone can re-run the check and see the chain is whole. That's what “tamper-evident” actually means.
We emulate a lot. Here's exactly what's real.
The Test bench, the Lab and the Scenes run in a browser — and the cryptography in them is completely real. The radar, the chip's secret key and the sealed storage can't exist in a web page, so those are simulated; the signature checks in them are not.
Real, byte-for-byte
- The Ed25519 signing & verifying you did above
- The SHA-256 hash chain you just broke
- The exact
securacv-canary-sig|v1|…message format - The actual device firmware — compiled to run in the browser (WebAssembly)
Simulated (can't exist in a browser)
- The 60 GHz radar and camera sensors
- The device's real private key, stored on its chip
- Power, the network, and other Canaries nearby
- The encrypted vault where sealed footage would rest
The emulator's own README says it plainly: it “talks to the firmware only through the same boundaries silicon would.” Where your browser can do the real math, it does — so a “verified ✓” in a demo is a real signature check, not decoration.
Three ways to check, from “click a button” to “audit the source.”
Trust should be optional. Pick how deep you want to dig.
Play with it here
You already did: you tried to forge a signature and broke a hash chain, with real cryptography.
Read the actual code
Every snippet on this page is quoted from the open-source repo. Read the real thing — the device signer, the kernel's chain, the browser demos.
Run the verifier yourself
Point the open-source verifier at a real device's log. If a single event was edited or reordered, it fails — loudly. No trust in us required.
Not “trust our privacy policy.” Trust the math.
A promise can change the day after you buy the camera. A signed, chained record can't change without showing it — and you can check it whenever you like.