Skip to content

Open source · Apache-2.0 · Python 3.9+

Stop a bad tool call
before your AI agent makes it.

interlock checks every tool call your agent makes, inside the agent's own process, and allows, blocks, or rewrites it before anything happens. No proxy, no account, no network calls, and no dependencies.

pip install "git+https://github.com/SourceShift/InterLock.git"

import interlock
from interlock import Blocked, guard
from interlock.detectors import network_egress_guard, pii_redaction_guard


@guard()
def http_post(url: str, body: str) -> str:
    return f"posted to {url}: {body}"


interlock.install(rules=[
    network_egress_guard(allowed_hosts=["api.acme.com"]),  # only hosts you trust
    pii_redaction_guard(),                                 # mask secrets and PII
])

allow posted to https://api.acme.com/notes: routine sync

rewrite posted to https://api.acme.com/notes: Card on file: [REDACTED CREDIT_CARD]

block Blocked: blocked action 'http_post': egress to 'evil.example' is not on the destination allowlist

Real output. The first two calls run — the second with the card number masked. The third never leaves the process. Run it yourself.

Why interlock

Agents make mistakes, and some get tricked. Sooner or later one runs rm -rf, sends data to a host you have never heard of, or follows an instruction it found on a web page. Most guardrails watch what the model says. interlock watches what it does: at the last moment you can still say no, with the real arguments in hand.

  • Three verdicts, not two


    A call can be allowed, blocked, or rewritten — mask a card number, cap a row limit, force a dry run. Safety does not always have to cost you the task.

  • It checks what tools send back


    Injected instructions arrive in tool output: a web page, an email, a document. interlock screens results before your agent ever reads them.

  • One policy, every framework


    The same rules guard decorated functions, MCP sessions, LangChain tools, your own model loop, and Node.js agents.

  • 105 detectors, ready-made


    Prompt injection, SQL and shell injection, secret and PII redaction, SSRF, egress allowlists, MCP server trust, budgets, and runaway loops.

  • Built for real deployments


    Per-tenant policy scopes with safe delegation to sub-agents, a tamper-evident audit log, and an OS sandbox for the subprocesses your agent launches.

  • Nothing to sign up for


    Pure Python, no runtime dependencies, no API keys, no telemetry. It runs offline, and it works the same in CI as it does on your laptop.

Where interlock fits

There are three places you can put a guard on an agent, and they each see something different:

Where Sees Misses
Prompt / output filter what the model is told, and what it says what the model decides to do
Network proxy or gateway outbound HTTP, usually encrypted file writes, shell commands, local tools, and the real arguments
interlock, in-process every guarded call with its real arguments, right before it runs code that runs outside the guarded functions, such as a subprocess

interlock sits at the last moment you can still refuse, and it is the only position holding the exact arguments. For the part it cannot see — a subprocess the agent launches — interlock ships BRACE, an OS sandbox built from the same policy.

How interlock works covers the mechanics: events, rules, verdicts, ordering, and what happens when something goes wrong.

Know the limits

These are the honest ones. A guardrail you over-trust is worse than one you understand.

  • It does not understand intent. The detectors match specific patterns, tuned so ordinary values do not trip them. That keeps false alarms low, and it means a reworded attack can get through: tool_result_injection_guard catches "ignore previous instructions", but not "ignore all previous instructions". Treat detectors as layers, and pair them with allowlists, which do not depend on wording.
  • It only sees the calls you wrap. A tool without @guard, a session you did not wrap, or a call that never goes through enforce_tool_call is invisible to interlock.
  • It does not undo actions. A result is checked after the tool has already run. Blocking the result hides the output from your agent; the side effects stand.
  • It cannot stop malicious code in its own process. interlock runs inside your agent. Code sitting next to it could call the unguarded function directly, or install an empty engine. Run code you do not trust — model-written scripts, third-party plugins — in the sandbox, not just behind a guard.
  • There is no "ask a human" verdict yet. A call is allowed, blocked, or rewritten. A fourth verdict that pauses for human approval is on the roadmap.

The security model is the full version, including the settings that quietly weaken protection and the gaps we have not closed.

Read the docs

  • Start here


    Getting started — about fifteen minutes. Guard a tool, block a dangerous call, rewrite a risky one, catch an injected instruction, and try a rule without enforcing it. Every snippet was run, and the output is what it printed.

  • Understand it


    How interlock works — events, rules, verdicts, how they combine, and what happens when a rule crashes.

    Security model — what it protects against, what it assumes, and where it stops.

  • Pick your defence


    Using detectors — choose from 105 built-in rules, and make sure they see your tools.

    Writing rules — from one-liners to result-phase rules and tests.

  • Deploy it


    Production checklist — monitor mode, logging, and rollout.

    Scopes and audit log — per-tenant policy and a tamper-evident record of every decision.

  • Connect it


    Integrations — @guard, MCP, LangChain, a model SDK loop, or a Node.js agent.

    MCP — guard a session and decide which servers and tools to trust.

  • Look it up


    Python API — every public class and function, with signatures.

    Detector catalog — all 105 detectors: what each catches, and which calls it sees.

Get started