paypal.com — not paypa1-secure.app. A brand-new
domain pretending to be a household name is the single strongest tell.
01 phishing & scam reporting, filtered
Karst is a self-hostable platform for phishing- and scam-reporting intelligence. Ordinary people forward a suspect message; Karst redacts the personal data on-device, parses authentication signals, classifies the threat in plain language, clusters related reports, and publishes signed intelligence to downstream CERTs, SIEMs, and on-device blocklists.
Karst takes its name from limestone landscapes that filter water naturally — a precise reference to filtering signal from noise across a sensor network of human reporters. Citizens forward suspicious emails to a deployment they trust; Karst redacts personal data, parses authentication signals, classifies the threat in plain language, clusters related reports into campaigns, and publishes signed intelligence to downstream CERTs, SIEMs, and on-device blocklists.
02 canonical data flow
A report enters through one of six clients, is sanitised on-device, then traverses the pipeline as messages on NATS JetStream, isolated by per-service subject ACLs. Hover any stage for the subject name it publishes on.
03 education as a feature
Karst doesn't just classify — it teaches. Each report comes back with a headline, a plain-language expansion, and an actionable tip. The reporter learns what to look for next time; the operator gets a paper trail of why the model said what it said.
DMARC failed. This message claims to be from PayPal but wasn't signed by them.
The sender wrote From: service@paypal.com, but the message was actually
sent from account-update.paypa1-secure.app and carries no valid DKIM
signature for paypal.com. The reply-to address differs from the
return-path, and the domain was registered 4 days ago.
paypal.com — not paypa1-secure.app. A brand-new
domain pretending to be a household name is the single strongest tell.
04 trust boundary
Each report crosses five concentric zones. The raw RFC822 body is encrypted on the ingest edge, lifted into the evidence vault, and referenced by hash from every downstream stage — it is never serialised back onto NATS.
Client
Web Extension · Thunderbird add-on · web app · iOS · Android · admin console. Recipient identities are stripped here, before the report leaves the device.
Ingest edge
HTTPS termination, rate limit, sender verification. Body is AES-256-GCM encrypted and the ciphertext is sent to the vault. Metadata continues on the bus.
Pipeline
NATS JetStream. Parser, privacy filter, classifier, clustering, dispatcher each consume and publish on ACL-isolated subjects. Bodies referenced by hash only.
Evidence vault
Encrypted RFC822 bodies in Garage object storage. Read only by an explicit operator action, audit-logged. Never serialised back onto NATS.
Published feeds
Signed outputs leave the deployment: MISP, STIX/TAXII, webhooks, Ed25519-signed on-device blocklists. The only material that ever crosses the deployment boundary.
05 federation, not multi-tenancy
Each CERT, company, or regional authority runs its own isolated Karst instance. Deployments share output, not databases — there is no multi-tenant code path, no row-level security, no cross-tenant trust boundary to defend.
Indicators & incidents — never the encrypted body, never the reporter.
Every published feed and every on-device blocklist, with a per-deployment Ed25519 key.
National CERTs, small companies, individual sysadmins — same code, same shape.
06 what makes karst different
Recipient identities are stripped on the client. An 11-layer Unicode-aware redaction pipeline runs server-side. Raw RFC822 bodies are encrypted at the ingest edge and never traverse the message bus — they live in the evidence vault and are referenced by hash.
Every classification ships with a three-layer explanation: headline → plain-language expansion → how-to-spot-this-next-time tip. Karst gets less useful the more people learn to spot phishing without it — and that's the point.
Each operator — CERT, company, regional authority, sysadmin on a 4-vCPU box — runs their own isolated instance. Federation happens via signed published feeds, not shared backends. No multi-tenant code paths, no RLS, no cross-tenant trust boundary to defend.
Headline
One sentence in plain language. No jargon. Tells the reporter, in human terms, what went wrong.
Expansion
The specific evidence — the actual sender domain, the headers that failed, the age of the domain. Auditable; nothing hidden.
Tip
A concrete pattern the reporter can apply themselves next time. The feature, not a footnote — Karst gets less useful the more people learn to spot phishing without it.