Warrant canaries: how they work and how to verify one
The legal theory behind warrant canaries, why most published ones are worthless, and how to verify a canary — including monitoring it automatically.
What is a warrant canary and how do I check if it is real?
A gag order can compel a company to stay silent about a legal demand. The warrant canary is an attempt to route around that: instead of announcing that something happened, the provider continuously announces that it has not happened, and stops when it does.
The legal theory
The argument is that compelled silence and compelled speech are different. A court can plausibly order a company not to disclose the existence of a demand. Ordering that company to affirmatively publish a false statement — to sign a document saying "we have received no such demand" when it has — is a substantially harder proposition in jurisdictions with constitutional protections against compelled speech.
This theory is untested at appellate level anywhere. It is an argument, not a precedent. Prosecutors have generally chosen not to force the question, which means canaries have worked in practice while remaining legally unsettled.
There is a second, more reliable effect that gets less attention: a canary with a published reissue schedule creates an expectation. When it lapses, informed users notice. That signal exists independently of whether the compelled-speech argument would survive a court, and it is why the reissue schedule matters more than the legal theory.
The four tests a real canary passes
1. It is cryptographically signed
An unsigned canary is a web page. Anyone who can edit the site can update it — including someone who has compromised the site, and including a provider under duress who wants to keep publishing. The signature must be made with a key whose fingerprint is published elsewhere: a key server, a Git repository, a printed conference handout, a Twitter bio from years ago. A key that only lives on the same website it is verifying proves nothing.
2. It embeds a recent unpredictable value
Without this, a provider could sign twelve months of canaries in advance and have them published automatically, which defeats the entire mechanism. The standard solution is to include a recent Bitcoin block hash and height in the signed text. Because block hashes are unpredictable, the canary demonstrably could not have been signed before that block existed. Recent news headlines are sometimes used and are weaker but acceptable.
3. It has a stated reissue schedule
"We will reissue this by the 21st of each month" makes absence detectable. Without a schedule, a canary that has not been updated in five months is ambiguous — has something happened, or did somebody forget? Ambiguity is the failure mode, and a good canary states both the cadence and what a lapse should be taken to mean.
4. It is machine-readable
Humans do not reliably check a web page monthly. A canary published as JSON at a stable URL, with a signature you can verify programmatically, can be watched by a cron job. This is the difference between a canary that works and a canary that is theatre.
How to verify one
# 1. Fetch the provider's signing key from a source that is not their website
gpg --keyserver hkps://keys.openpgp.org --recv-keys 0x<keyid>
# 2. Check the fingerprint against a value you obtained independently
gpg --fingerprint 0x<keyid>
# 3. Fetch the canary and its detached signature, then verify
curl -sO https://example.org/canary.txt
curl -sO https://example.org/canary.txt.asc
gpg --verify canary.txt.asc canary.txt
# If the provider clearsigns instead of using a detached signature,
# there is no .asc to fetch and the command is:
# gpg --verify canary.txt
# 4. Confirm the embedded block height is recent and real
curl -s https://blockstream.info/api/block-height/<height>
Check which of the two signing schemes the provider actually uses before you conclude anything from a failure: running the detached form against a clearsigned file, or the reverse, produces "no valid OpenPGP data found" and tells you nothing about the canary.
Step 2 is the one people skip and it is the only one that matters. If you obtain the key from the same server that serves the canary, an attacker who controls the server controls both, and the signature verifies perfectly while proving nothing.
Monitoring it automatically
A canary you check when you happen to remember is a canary that will lapse unnoticed. The fix is a stable JSON endpoint. Ours is at /canary.json; it currently reports that no issue has been published, and once the first issue is signed it will carry the same shape as the example below:
{
"version": 2,
"published": true,
"issued": "<date>",
"next_due": "<date>",
"statements": {
"no_gag_orders_received": true,
"no_secret_warrants_received": true,
"no_national_security_letters": true,
"no_key_disclosure_demands": true,
"no_backdoor_requests": true,
"no_servers_seized_since_last": true
},
"btc_block": { "height": "<height>", "hash": "<hash>" },
"signature_url": "https://example.org/canary.txt.asc"
}
A monitor is then trivial — alert if next_due has passed, if any statement flipped to false, or if the endpoint stops responding:
#!/bin/sh
c=$(curl -sf https://vpsden.com/canary.json) || { echo "canary unreachable"; exit 1; }
due=$(echo "$c" | jq -r .next_due)
[ "$(date +%F)" \> "$due" ] && echo "CANARY OVERDUE (was due $due)"
echo "$c" | jq -e '.statements | to_entries[] | select(.value==false)' &&
echo "CANARY STATEMENT CHANGED"
What a canary cannot do
- It cannot tell you what happened. A lapse means "something, or nothing, or an administrative failure." It is a smoke alarm, not a report.
- It cannot survive a determined court. If a court squarely orders continued publication, the theory is tested and might lose. Nobody knows.
- It cannot protect data that is already readable. A canary is a notification mechanism. Encryption is the control. A provider with a beautiful canary and plaintext disks has given you a warning system attached to nothing.
- It cannot be verified retroactively if the key is lost. Keep your own copies of past canaries if you want a durable record; providers are not obliged to keep an archive and some do not.
Our canary is at vpsden.com/canary, signed monthly, with the JSON endpoint above and a published archive of every prior issue.