⚠️ Experimental — This is a test environment for reasoning about agentic security, not production software.
Janus is an experimental interpretation of the Agents Rule of Two designed to explore how cryptographic identity and network-layer enforcement can mitigate prompt injection attacks in AI agents.
Prompt injection is a fundamental, unsolved weakness in all LLMs. When an attacker-controlled string enters an agent's context window, it can hijack the agent's behavior—ignoring developer instructions, exfiltrating private data, or taking unauthorized actions.
The risk becomes critical when an agent simultaneously has:
| Capability | Example |
|---|---|
| [A] Untrusted Input | Processing emails from unknown senders |
| [B] Sensitive Data | Access to private calendar, documents |
| [C] External Mutation | Sending emails, making API calls |
With all three, a single malicious email can instruct the agent to exfiltrate your calendar to attacker@evil.com. No amount of prompt engineering reliably prevents this—the attack surface is the context window itself.
The Rule of Two (inspired by Chromium's security policy and Simon Willison's "dual LLM" pattern) states: an agent must satisfy no more than two of [A], [B], [C] within a session.
Janus explores enforcing this by splitting capabilities into mutually exclusive modes:
| Mode | Capabilities | What Agent Can Do |
|---|---|---|
| AB | Input + Data | Read inbox and calendar (no egress) |
| BC | Data + Comms | Send emails, read calendar (no untrusted input) |
| AC | Input + Comms | Research internet (no sensitive data) |
To transition, the agent petitions for a lifecycle event: it is killed, memory wiped, and restarted with a new cryptographic identity (SPIFFE SVID). Only a sanitized state payload survives—breaking the [A] → [B] → [C] exploit chain.
Phase 1 (Mode AB): Agent reads the malicious email and calendar. It detects the attack, refuses to comply, and writes a safe response plan. It then petitions for Mode BC.
Phase 2 (Mode BC): Agent restarts with fresh memory. It can only read the sanitized plan from the handover state—not the original attack. It sends the safe response.
The attack fails because the agent never has simultaneous access to attacker-controlled input and egress.
# Prerequisites: Docker, Docker Compose, Linux (for eBPF)
# Set your OpenAI API key for the Codex agent
export OPENAI_API_KEY="your_key_here"
# Run the end-to-end test
./tests/janus_full_test.sh| Component | Role |
|---|---|
janusd |
Supervisor—handles petitions, brokers to IAM, updates SPIRE, restarts containers |
janus-net |
Network guardian—egress proxy (:3128) and mTLS ingress (:8443) |
janus-run |
Agent entrypoint—state hydration, proxy configuration |
janus-cli |
CLI for agents to petition for mode transitions |
janus-kernel |
eBPF LSM enforcer—prevents network bypass (Linux only) |
janus-proto |
Shared types and constants |
iam-mock |
Mock authorization service for testing |
See docs/design.md for the architecture and threat model.
This codebase is for educational and experimental purposes only. It demonstrates concepts for reasoning about agentic security but is not hardened for production use. The mock IAM, simplified protocol parsing, and test-oriented design choices are intentional tradeoffs for clarity over robustness.

