Human approval for the actions your AI agent takes, enforced outside the agent.
Why · Demos · 5-minute demo · Requirements · Limits · Repository map · Security · License
Warning
Research prototype. Not for production. All security reviews were performed by AI agents; no independent human audit has been done. See LIMITATIONS.md and DISCLAIMER.md.
Recorded results of one local Demo A run on 2026-10-30 (simulated provider; the agent and the approver are scripted), replayed by assets/readme/demo.tape; source: tests/demoa, examples/agent-support.
An AI agent or an app proposes consequential actions such as payments, refunds, or messages. An action executes only after a human approves exactly that action, or when it fits a bounded mandate the human set earlier. A separate broker holds the provider credentials; the app never does.
Compromise of computation must not imply compromise of authority.
Nodkey separates an application's ability to compute from its authority to cause consequential effects. An AI agent or an app (the workload) can only propose actions such as a refund or an outbound message. A separate broker, which alone holds the provider credentials, executes an action only if it carries a single-use grant signed by a separate authority, and the authority signs only what a human approved, exactly as it was shown to them, or what fits a bounded mandate that human delegated earlier.
Prompt injection or remote code execution in the workload gives an attacker everything the workload can do. If the workload holds API keys or database credentials, the attacker holds them too. In Nodkey the workload holds no credential and has no network route to the protected resource, so taking it over yields proposals, not authority. Nodkey limits the consequences of compromise; it does not prevent compromise or prompt injection (VISION.md, THREAT_MODEL.md).
Propose, confirm, execute: the workload proposes, a person approves, and the broker executes once with a single-use grant. PNG versions: light, dark.
Simplified. The real flow has more checks, for example a payments adapter that verifies grants again before contacting the provider. See ARCHITECTURE.md and effect-protocol-v2.
Each demo runs locally in Docker. The apps are intentionally vulnerable (a remote-code-execution
endpoint models a compromised workload). They bind to 127.0.0.1 only and must never be exposed to a
network. Results are copied from STATUS.md (last local runs, 2026-10-25 to 2026-10-28).
| Demo | Directory | Shows | Last result |
|---|---|---|---|
| 1. Containment | examples/php-ledger |
Arbitrary PHP in the app cannot reach the database or its credential; the same attack succeeds against an unprotected baseline | 65 PASS / 2 NOT APPLICABLE / 0 FAIL; baseline: 24 expected FAILs |
| 2. Confirmed transfer | examples/confirmed-transfer |
A compromised app can propose a transfer but cannot alter, forge, or replay the approved one | 29/29 PASS |
| P. Confirmed refund | examples/confirmed-refund |
Refunds through a simulated payment provider; the app never holds the provider key; no double refund | 92 PASS / 0 FAIL / 17 NOT TESTED |
| A. AI support agent | examples/agent-support |
A prompt-injected agent's tool calls run only when approved or within a mandate | 75 PASS / 0 FAIL / 14 NOT TESTED |
Demo A needs no model, API key, or account: a deterministic stand-in plays a fully prompt-injected agent.
tests/demoa/run.shThe script builds the images, runs the scenario twice on fresh stacks, prints a results table, and stops the stack. It exits with status 2 because 14 rows are NOT TESTED. The first run downloads base images and compiles the Rust components; this build can take longer than five minutes (it has not been timed). Step-by-step instructions, the meaning of each result value, cleanup, and troubleshooting are in QUICKSTART.md.
- Linux, or a Linux VM such as Colima on macOS. The development runs used Colima 0.10.3 (Ubuntu 24.04, AppArmor, Docker default seccomp).
- Docker with Compose v2.
bash,python3,opensslon the host (used by the run scripts).- Network access for the first image build (base images, Rust crates).
- Rust (1.99 used) only to build and test the crates outside Docker. The demos compile inside Docker.
phpon the host only for the Demo 1 containment suite (tests/containment/run.sh).
Nodkey does not prevent code execution or prompt injection, does not make permitted actions safe, and does not protect against a compromised host, kernel, container runtime, broker, gateway, or authority. Confirmed intent (SI-20) is PARTIALLY MET: approval is session-based with a test login, without passkeys. All providers are simulators. Many rows are NOT TESTED. Details: LIMITATIONS.md.
| Path | Contents |
|---|---|
broker/ |
Broker (Rust): verifies grants, owns effect state, executes declared operations |
crates/ |
Authority, gateway, grant verifier, payments adapter, MCP front (Rust) |
tools/ |
Simulated payment provider (simpay), mail sink, deterministic demo agent |
examples/ |
The four demo stacks |
tests/ |
Demo runners and harnesses, integration tests, test vectors |
docs/ |
Vision, invariants, threat model, architecture, specs, ADRs, research, reviews |
| STATUS.md / ROADMAP.md | What is verified; what is planned |
Report vulnerabilities as described in SECURITY.md. Contributions: see CONTRIBUTING.md and the Code of Conduct.
Apache License 2.0. See LICENSE and NOTICE. Third-party material is listed in THIRD_PARTY_NOTICES.md; see also DISCLAIMER.md.
