Inspiration

Hospitals are putting AI agents on care teams, but most of their “security” is a polite line in a prompt. One leaked token or over-broad tool list, and patient data is exposed. We wanted real walls: identity that expires on its own, tools locked to a role, and a human who can pull the plug mid-task.

What it does

BadgeWard is a live control room for hospital AI agents.

A clinician asks in plain language: “P003 has a sinus infection. Recommend an antibiotic and draft the order.” An orchestrator agent plans the work but can’t see a single patient record. Every step goes through one gateway that:

Authenticates every agent with a short-lived badge tied to a private key only that agent holds. A leaked badge is useless. Enforces the plan like a contract: single-use leases, steps run in order, prerequisites required. No order gets drafted before allergies and interactions are checked. Encrypts every consult so that only the one agent instance it’s addressed to can read it. Passes only typed fields, never free text, so a prompt injection hidden in a patient record is stopped at the gateway. Revokes instantly: kill an agent mid-task and the rest of its plan is cancelled.

Operators also get approvals for risky actions, security escalations, a live handshake visualizer, a tamper-evident audit log, and one-click attacks (stolen badge, tampered code, rogue agent) that visibly fail.

Bring your own agent: Cursor and Claude Code connect over MCP with their own identities and get exactly one tool, ask_ward. Reaching for anything else gets them revoked.

How we built it

TL;DR: Policy in YAML. An LLM plans. A deterministic gateway enforces every step with layered cryptographic identity.

11 specialist agents and 21 typed tools (pharmacy, labs, insurance, vitals, imaging, scheduling, discharge, and more). Specialists are deterministic functions with no LLM inside, so they can’t be prompt-injected. A fresh instance is created for each request. The identity stack: Code attestation, then a workload secret. An encrypted, signed badge (AES-256-GCM) bound to the agent’s own Ed25519 key. It expires after 60 seconds and rotates every 45 with a new key. A signed proof on every call, with replay protection. A per-instance delegation, then an encrypted consult and a signed handshake. A typed output check, and a hash-chained audit log. Orchestrator: Groq (gpt-oss-120b) or a local Qwen model through Ollama. The model plans; the gateway decides. Stack: Python, FastAPI, SQLite, cryptography and PyJWT, MCP over stdio and HTTP, plus a live web console. Challenges we ran into Small models plan badly. They submitted empty plans, invented tools and made up placeholder values. Worked examples and policy-based plan repair fixed that, and the gateway still checks everything. Rotation vs. revocation. A rotation lets an in-flight call finish. A revocation throws its result away. MCP clients want every tool. We cut the outside door down to one tool, ask_ward. A revoke that’s actually hard: cancel later steps, keep partial answers, and never quietly respawn a killed agent. Knowing when to stop. We kept the security layers a judge can watch fail live. Accomplishments that we’re proud of 0 security failures across 17 live attack and workflow scenarios on both a cloud and a local model, backed by 238 automated tests. Stolen badges really fail: replayed requests, foreign keys, bare badges, even a badge plus key stolen before the last rotation. One tool in, a full care workflow out. Revoke Cursor and it’s cut off on its next call. Human approval and escalation built into the plan itself. A live handshake visualizer that shows the exact hop where an attack stops. What we learned

LLMs are great planners and terrible security boundaries. Put the fence in the gateway (badges, leases, schemas, humans) and the model can stay creative inside it.

What’s next for BadgeWard Hardware-backed attestation (TEE or SPIFFE/SPIRE). Policy packs for multiple hospitals. A production lifecycle for MCP credentials. More care workflows behind the same badge, lease and handshake model.

Built With

Share this project:

Updates

Submission history