Try it!
Source on GitHub Read the full write-up on Devpost
Submission
Python JavaScript Rust Docker NVIDIA Nemotron Nebius Token Factory
Built with Isabella Wu and Annie Liao; the full credits are on Devpost. Started October 2026.
About the Project
What it does: Every message into an agent and every reply out of it gets one verdict — pass or block — and the name of the rule that decided. Thirteen checks run in a fixed order against a JSON policy: canonicalisation (zero-width characters, homoglyphs, Unicode NFKC), container-breakout patterns (
docker.sock, /proc, cloud metadata endpoints), prompt injection and jailbreak phrasing, custom blocklists, length limits, harmful content, PII and credentials, data exfiltration, and system-prompt leakage. The first failure decides, so the console can say "blocked by container_breakout in 8 ms" instead of "something went wrong".Above the rules sits an optional second opinion: an NVIDIA Nemotron model on Nebius Token Factory reviews text the rules allowed — and its only power is to escalate to a block. It can never release anything, so if the model is offline or talked into misbehaving, you lose an opinion, not your security.
How it was built: Four rings, outside in. A build-free console page that holds no rules; an HTTP gateway with default-deny routing, per-endpoint permissions, sessions or scoped API keys, CSRF checks and rate limiting; a pure-logic rule engine with no network, clock or randomness; and the oversight monitor wrapping the engine. Security primitives are deliberately standard: PBKDF2-HMAC-SHA256 password hashing, RFC 6238 TOTP two-factor with hashed single-use backup codes, and a hash-chained audit ledger where deleting or reordering an entry breaks every hash after it. Zero runtime dependencies —
python3 guardrail_server.py starts the API, console and audit log.Challenges: The model layer was first wired backwards — in front of everything, costing an inference per request and opening a new attack surface. The integration with Nebius looked alive and wasn't: the client spoke the Ollama API shape instead of OpenAI's, no API key was ever sent, and the verdict parser matched the substring "safe", so a model answering "not safe" was scored as safe. Testing the API directly with curl (not the dashboard) also exposed a two-factor bypass: the gate checked a global "2FA configured" flag instead of the user's own record. One-line fix, now a regression test.
What I learned: A model that can be persuaded cannot be the guard. Defaults decide everything — default-deny only works when it's structural. And trust the API, not the dashboard: the green tick was a claim; the 403 was the truth.
Dev Notes
By the Numbers
13 deterministic checks, 11 test suites, zero runtime dependencies, MIT licensed.
Key Design Choice
The model only sees what the rules already allowed, and can only tighten a verdict. A blocked request never reaches it.
Hardest Bug
A "safe" substring match that scored "not safe" as safe — the exact failure the oversight layer exists to prevent.
What's Next
A hosted read-only demo, per-page policy packs, signed audit exports, and a decorator-style integration for agent frameworks.
← Back to Hackathons Back to top