security / threat model
Assume the model is compromised. Prove it doesn't matter.
The LLM, its context window, and everything it reads are classified untrusted, and the adversary is assumed to steer them at will. MCPIP's guarantee is architectural: compromised reasoning is not enough to produce a protected state change. This is the full adversary model — public here, not a gated PDF.
01 / the adversary
Grant the attacker the whole model. It still cannot cross.
what the adversary controls
- every prompt, and the full context window
- every document, page, and tool output the agent reads
- the exact wording, structure, and timing of each request
- full knowledge of the protocol — it has read the source
what it never obtains
- a verified identity it did not earn
- the real name or address of any protected system
- an approval that outlives its exact payload
- an execution path that skips the gate
- an explanation for any denial it can mine
02 / the guarantees
Seven guarantees. Non-negotiable.
Each holds on every request — or the request does not run. They are enforced by the architecture, not asked of the operator.
1
Timing-safe by construction
Every comparison of a token, PIN, signature, or secret is timing-safe. There is no fast path for an attacker to measure, so a valid secret can never be teased out one probe at a time.
timing-safe
2
Bound to the exact request
High-risk actions are cryptographically bound to the exact parameters they were approved for. Change a single value between approval and execution — a recipient, an amount, a path — and the action is denied. Approval for one request can never be replayed against another.
bound to the payload
3
Strict by default
Every input is strictly validated before it can reach your systems. Malformed, oversized, or smuggled payloads — unexpected fields, hidden control characters, structures built to exhaust a parser — are rejected at the door rather than interpreted.
strict by default
4
Verified identity only
Who an agent is comes only from a cryptographically verified token — never from anything the agent can set for itself. Identity smuggled into a request payload is a hard denial, not a value that is quietly trusted or silently stripped.
verified identity only
5
Capabilities, never roles
Privileged actions gate on explicit, granted capabilities and hard isolation boundaries — not on a role label. The word “admin” in a token authorizes nothing on its own, and an agent cannot even see the actions belonging to a compartment it was never granted.
capabilities, not roles
6
Fail closed, stay opaque
Any failure — a bad parse, a failed check, a missing record, a lost race — denies immediately. The caller sees only a generic denial and a correlation_id, while the real reason is sealed privately into a tamper-evident record before the action would ever run. The gate never leaks why, so it can never be turned into an oracle.
MCPIPDenied + correlation_id
7
Scales without shared trust
Authorization keeps no shared state inside any single node. Gates can be added, removed, or restarted independently, so the system scales horizontally under load without weakening a single guarantee or trusting one node’s memory.
no shared auth state
✓ all passing
Verify it yourself
A suite that exercises the real pipeline with no mock layer standing in for the gate, a self-verifying adversarial proof, and an independently re-checkable audit export. Every guarantee here is falsifiable on your own machine in minutes — not asserted in a datasheet.
./scripts/quickstart.sh # a live gateway + governed calls
python main.py # 29 checks: 7 allow-paths, 22 attacksmain.py resets its own sandbox database before it runs.
03 / the attack catalog
Every known move against an agent — and where it dies.
The outcome column is the shape of the denial recorded internally; the caller only ever sees a generic MCPIPDenied and a correlation id.
| Attack | What the gate does | Outcome |
|---|---|---|
| Prompt injection | The ask changes; the authorization does not. | DENY · sealed |
| Poisoned document / tool description | Steers what the agent requests, never what the gate allows. | DENY · sealed |
| Target enumeration | Real systems are never named; unknown aliases deny opaquely. | unknown alias |
| Approval replay | Step-up approvals are consume-once; a second use finds nothing. | not found |
| Payload tampering after approval | Approval binds to the exact payload; one byte of drift kills it. | payload mismatch |
| Forged or expired token | Identity comes only from cryptographic verification. | invalid token |
| Identity smuggled in arguments | Identity-shaped input is a hard deny, never a value to trust. | hard deny |
| Role-claim escalation | Role labels authorize nothing; capabilities are granted, not claimed. | no capability |
| Cross-tenant / cross-compartment reach | Hard isolation — the agent cannot even see across the boundary. | hard deny |
| Error-oracle probing | Denials are uniform and opaque; there is no signal to mine. | opaque deny |
| Audit tampering | Records are signed and hash-linked; delete one and verify names the epoch it was in. | chain break |
Settle the last row yourself
./scripts/audit_tamper_demo.sh
Every row above is a claim. This one you can check: the script deletes a sealed record straight out of Redis, bypassing the gateway entirely, then asks the gateway to re-verify its own chain — which comes back {"intact":false,"first_bad_epoch":N}. The root is recomputed from the surviving records and compared against the root Ed25519-signed when the epoch closed; the signing key is not in Redis, so nobody can re-sign a root matching what they left behind.
04 / the two hard guarantees, drawn
Payload-bound approval. Evidence before execution.
the step-up ceremony — approval binds to the exact payload and is consumed once; drift of a single byte denies.
write-before-execute — the sealed, hash-linked record exists before the side effect runs, in guaranteed order.
05 / non-goals
The guarantee is strong because the scope is honest.
MCPIP limits the blast radius of a compromised agent to exactly its granted envelope, and records everything inside it. What it deliberately does not attempt:
Making the model harder to fool
Prompt hardening is worthwhile, but the guarantee here does not depend on it. MCPIP assumes the model is already fooled.
Judging content
What the model says is out of scope. What it does is the whole scope — governed action, not filtered speech.
Anomaly detection
The gate is deterministic, not probabilistic. Pair it with your monitoring and SIEM; it does not replace them.
Replacing IAM or your vault
MCPIP consumes verified identities and composes in front of your secrets manager — it mints no identity and holds no LLM key. Where a downstream credential must be held, the optional encrypted vault does so explicitly, and host identity with no stored secret is the recommended posture.