dcj · dotcomjack
Guardrails for desktop AI agents, in Swift. Secret redaction and SSRF policy for anything that reads your screen and follows links.
Add to Package.swift
.package(url: "https://github.com/dotcomjack/grux-kit.git", from: "0.5.0")
Your own manifest needs platforms: [.macOS(.v13)] too. Leaving it out is a build failure, not a warning.
See it work
The moment that text is interpolated into a prompt, it leaves your machine. Edit the left pane and watch what would reach the model.
What the agent read
What reaches the model
This demo is a JavaScript approximation, not the library. The real matcher is the Swift one: twenty four patterns plus a generic high entropy pass, table driven and pinned by tests. It is reproduced here loosely so the idea is visible in two seconds. A security tool whose demo quietly disagrees with its own library is exactly the failure this library exists to complain about, so it is worth saying plainly rather than in a footnote.
Two modules
Twenty four patterns plus a generic high entropy pass. Two properties are load bearing and both are pinned by tests.
Most specific wins. A Stripe live key is tagged [REDACTED:STRIPE_LIVE_SECRET], not the generic entropy tag. Precision is what makes the audit trail worth reading later.
It is idempotent. redact(redact(x)) == redact(x). Prompts get assembled from fragments that were each cleaned on the way in, so the function runs over its own output constantly.
PEM blocks are consumed whole, header through footer, including a truncated block with no footer. Redacting the header alone would tag the block and then hand the model every byte of the key.
What it does not do
It is a matcher, not a parser, so it cannot catch a secret that does not look like one. Single case hex strings are deliberately exempt, which keeps git SHAs and checksums intact but lets a 32 or 64 character lowercase hex API secret through untouched. That is a real gap, not just a feature, and you should know which side of it you are on.
The threat is server side request forgery with a language model as the confused deputy. Your agent runs on your laptop, inside your network, and it will follow a link that came from a web page, an email, or its own hallucination.
Default posture: http and https only, credential bearing URLs always denied with no override, and loopback, private ranges, link local, carrier grade NAT, .local and bare single label hostnames all denied.
Every denial carries a tag, and the tag list is complete on purpose. A test fails the build if the code can emit a tag the table does not name. Alert loudest on HOST_SMUGGLING, the only tag that implies intent.
What it does not do
It does not follow redirects, and that is the biggest gap. evaluate judges one string, and a perfectly public URL is free to answer 302 Location: http://127.0.0.1:8080/. You must re-evaluate every hop. It does not resolve DNS either, so rebinding is outside what it can see.
Every tag before 0.5.0 leaks credentials
Published tags stay resolvable so existing checkouts do not break. They are documented here and in the changelog so nobody adopts one by accident. Use 0.5.0.
| Tag | What it actually does |
|---|---|
| 0.1.0 | Passes private key bodies straight through to the model, and the injection fence is forgeable. |
| 0.2.x | Leaks the AWS secret access key. |
| 0.4.0 | Measured against a real build rather than inferred from its changelog: allows the loopback and NAT64 SSRF bypasses, and leaks indented PEM bodies, PGPASSWORD=, session cookies, Set-Cookie, bare Bearer headers and curl -u passwords. |
The one to check if you have ever pinned it.
In 0.4.0, a denylist entry written any way other than a bare host matches nothing at all. https://evil.com, evil.com:443 and *.evil.com are all silently inert against denylist: ["evil.com"]. Your own denylist fails open while looking configured.
Five tags published, all five later found to leak, several by audits of code that had already survived earlier ones. 0.5.0 is the most heavily audited state this library has been in, and that is a statement about effort, not a guarantee. Pre 1.0, so treat the minor version as breaking.
Roadmap
Each one lands with its tests rather than as a sketch. Nothing below is shipped.
Green, yellow and red action classes. What runs silently, what asks first, what is never automated.
Per call accounting and budget ceilings, because an agent in a retry loop is a billing incident.
Fan out to parallel workers with structured results.
Near silent audio makes Whisper emit confident garbage. The hard constraint is the false positive side: it must never reject ordinary dictated speech.