Sovereign AI Shield · sensor · resolver · gateway · passport
Your country’s data stays in your country unless a named human authorizes it to leave.
It establishes where your machines are actually talking, holds anything unauthorized, keeps identity from leaving in the first place, and makes every determination something you can prove afterwards. At the highest classification, nothing leaves at all.
No account · no tracking · nothing on this page is sent anywhere
Deny by default
Nothing communicates unless it is listed with an owner and a reason.
Every destination your machines reach lands in one of three states. There is no fourth state for “probably fine”.
On the list, with a name against it
A destination someone signed for. The allow entry carries the reason it exists and the person who owns that reason, so the list can be read a year later by someone who was not in the room.
Domestic, but nobody has signed for it
Inside the border and not obviously wrong — but unowned. This is the state most real traffic starts in, and working through it is the actual work.
Foreign and unlisted — or unestablished
Undisclosed counts as unauthorized on purpose. A destination whose jurisdiction will not resolve is what an exfiltration path looks like. The usual remedy is a new line in the jurisdiction table, not a block.
Every finding carries its basis — which address range, or which reverse-DNS suffix, produced the answer. Nothing is estimated to fill a gap, and a jurisdiction is never guessed to make a report look complete.
Four parts, four positions
Each one sits somewhere different, because each one can only see from where it stands.
Every machine
Sensor
Watches this machine’s real outbound connections and attributes each one to the process that opened it. One-shot, or continuously.
python3 watch.py
Router, or a small always-on box
Resolver
Covers everything that will never run an agent — televisions, doorbells, phones, cars — by the names they look up, with the device that asked.
sudo python3 resolver.py --port 53
Between your apps and the model
Gateway
Replaces names, record numbers and addresses with tokens on the way out and puts them back on the way in. High classification fails closed.
python3 proxy.py --classification high
Wherever models are approved
Passport
Signs a model’s papers, so a determination cannot be quietly edited afterwards. Change one character and the signature stops verifying.
python3 sign.py sign model.json
Python 3, standard library only. It runs by unzipping.
One ledger, two viewpoints
A name the resolver saw and an address the sensor saw are often one event.
The sensor knows which process opened a connection. The resolver knows which device asked for the name. Neither knows the other half. Pairing them by answer address and time turns two half-rows into the row you actually wanted:
BEFORE — two files that overwrote each other
living room TV → metrics.vendor.example
studio-mac — Safari → 203.0.113.9
AFTER — one row, both viewpoints
studio-mac — Safari → github.com (140.82.114.4) both viewpoints
paired with a lookup — github.com answered 140.82.114.4 five seconds before this connection
Paired
Exactly one name answered that address inside the window, and the same device asked. The row carries the gap in seconds it was matched on.
Ambiguous, and it says so
Several names answered the same address — a shared CDN is the ordinary cause. The candidates are listed and the row stays an address. Nothing is merged on a guess.
No lookup at all
Something connected straight to an address. That is not a gap in the report; it is a finding, and it is one of the two things the resolver cannot see on its own.
Where the two viewpoints disagree about a determination, the disagreement is printed and the more restrictive one is applied. It is never averaged away.
The passport is a gate, not a certificate
An application does not start against a model that cannot produce papers.
Three lines in any app closes the hole where a model gets loaded directly, around the gateway, by a script nobody remembered:
from require import require_passport
require_passport("claude-opus-5",
passport="passports/claude-opus-5.signed.json")
Missing, expired, altered, or determined worse than you accept
The application refuses to start. A refusal at load is recoverable. An unnoticed disclosure is not. That trade is the whole design.
There is an override, and it must name a person
A tool with no override gets switched off wholesale the first time it is wrong at 2am, and then it protects nothing. So: a first and last name, a reason, and every use appended to a ledger with the model, the host and the time. The point is not to stop anyone. It is that nobody can later say the model ran unchecked and nobody knew.
Stated plainly
What it cannot see, printed next to what it did.
A report that lists only findings reads as an inventory. This one is a sample, and it says so on its own face.
A device using DNS-over-HTTPS bypasses the resolver entirely
It asks a hardcoded resolver of its own and never consults yours. Many televisions do exactly this. Pair the resolver with the firewall drafts for those.
Anything connecting straight to an address makes no lookup to see
The sensor catches it on the machines it runs on. Off those machines, it is invisible to the watchpoint — and the collated ledger now counts them rather than passing over them.
A capture window is a sample, not an inventory
Run several, at different hours. A destination seen for three weeks keeps its original first-seen date — a fresh capture never makes an old visitor look new.
No payload is read, anywhere
Connection metadata and DNS names only. There is no inspection step to turn on later, because there is no inspection step.
What this system will not do
A determination stops being a claim and becomes evidence the moment it is signed.
Every release is hashed, the hashes are signed, and the archive is built reproducibly — so you can rebuild it yourself and compare, rather than taking our word for it.