Prompt injection is the problem nobody's actually solved. An agent reads an email or a web page, and hidden inside that data is an
instruction that redirects it. The model can't tell the difference — to it, everything is just tokens.
The structural answer has existed for fifty years: information flow control. Data carries labels saying who may read it and who
vouches for it, and the system checks every flow against a policy. What nobody had done, as far as I could tell, was make it something
a developer could actually adopt for agents.
That's what I built with
kelvra
You write a policy file naming your sources, your sinks, and the few declared crossings between them — "this summary may now be seen
by the support team", "a human reviewed this, I vouch for it". In Python, values carry those labels. emit() checks the flow before
data leaves. model_call() treats the model as opaque, so the output inherits the strictest label of everything that went in. Coarse,
yes — but it never under-labels, and under-labeling is what leaks data.
The part that surprised me most: kelvra check analyzes the policy before anything runs. It reads the flow graph and tells you that
untrusted inbox data can reach a Slack channel with nothing in the way — the shape of an injection attack, found at authoring time. No
execution, no traffic.
Every run produces an audit record too: what was read, what crossed, who consented, what got refused. Hash-chained, journaled to disk
as it happens, signable with Ed25519. The refusals matter as much as the permits — for an auditor, proof a system said no is worth as
much as the trace of what it allowed.
Now, the honest part, because I think a security project that oversells is worthless:
• It can't see inside the model. If an authorized output contains something it shouldn't, Kelvra doesn't know. One attack in my own
eval corpus gets through for exactly this reason — it's written down in the threat model, not hidden.
• The in-process runtime is cooperative, not a sandbox. There is an MCP gateway that really does sit in the middle and refuse tool
calls before they reach the server, but it's stdio only, coarse-grained, and hasn't run against a real MCP application yet.
• If a source is mislabeled public , everything downstream works perfectly and protects nothing. That's a people problem, and no amount of code fixes it.
``CaMeL, FIDES, AgentArmor — better teams already solved enforcement. I'm not competing with them. What I was going for is the layer
above: a portable label vocabulary, a policy file a non-programmer can read, an audit artifact you could hand to a regulator. Whether
that gap is real is the open question, and I'd genuinely like to be proven wrong.
What I'm looking for: I'm one person and the core is done (1200+ tests, zero dependencies), but nothing is deployable until there's a
framework adapter — LangChain, LlamaIndex, whatever you use. If you build agents and want to wire this into something real, or you
want to break the spec, come argue with me. Issues and PRs welcome, hostile review especially.
Star it if the idea is interesting. Contribute if you think it's wrong.
Top comments (0)