DeadBolt
Integrates with OpenAI Agents SDK function tools by providing a @protected_tool decorator and sidecar dispatch, allowing DeadBolt policy to gate each protected function before it executes.
DeadBolt
Contributing with an agent? Read AGENTS.md for setup, local checks and project boundaries.
A local execution gate for software agents. Put DeadBolt in the code that runs an action, then let policy and operator controls decide whether that action runs. Embed it in Rust, call its local sidecar from another language, or wrap a trusted stdio MCP server. Free under Apache-2.0.
Install · Try it · Integrate · Migration · Project site
Version 2.0.0
This source targets engine 2.0.0 and Python client 2.0.0, with scope frozen at the tested RC3 behavior. Versioned releases identify available downloads, exact source and checksums; installation tracks package-manager, bundle and editor availability separately. A source merge does not publish a package or update a directory listing.
Version 2 requires authenticated operator setup for Unix and TCP sidecars, creates private state, defaults fresh roots to supervisor renewal, and enforces ancestor policy and fixed run deadlines. Existing stored renewal modes remain unchanged. Read major-version migration and private state before replacing an older installation.
The artifact-pinned RC3 retest passed conflicting-destination denial, damaged-store Cursor Reload refusal, and actual model calls after a fixed deadline on macOS arm64. The underlying Auto model was unknown. Separate Linux headless checks cover their recorded scope. These are execution receipts, not certification; stable artifact and installed-consumer checks remain distinct from the RC3 results.
Related MCP server: mcp-policy-gateway
Try it before connecting an agent
No model account, API key, Harness, cloud service or database server is needed. Choose a checksum-verified native archive in the installation guide. From its extracted directory on macOS/Linux:
chmod 0755 deadbolt
./deadbolt --version
./deadbolt drill
python3 examples/evaluate.py --binary ./deadboltOn Windows, use .\deadbolt.exe --version, .\deadbolt.exe drill and
python examples/evaluate.py --binary .\deadbolt.exe.
Expected: your selected version, deadbolt drill ok, and JSON with "passed": true.
The evaluation starts a private sidecar, writes harmless temporary files, checks
that policy, approval, kill and outage block effects, and cleans up afterward.
Python 3.9+ is the additional runtime needed. Understand the report.
For a reviewed source checkout, Rust 1.85+ and a native C compiler/linker:
cargo install --path . --locked --bin deadbolt
deadbolt --version
deadbolt drillThe matching Python client 2.0.0 is published. The matching Rust package 2.0.0 is also published. Install the CLI from Cargo, or the Python client in your application environment:
cargo install n11-deadbolt --version 2.0.0 --locked --bin deadbolt
# In your application's virtual environment:
python -m pip install 'n11-deadbolt-client==2.0.0'For embedded Rust, use deadbolt = { package = "n11-deadbolt", version = "=2.0.0" }
and commit your application's own lockfile. The Python wheel contains the client,
not the engine. Node remains a bundled source module. Install and verify.
Pick your integration
Your executor | Smallest integration | Start here |
Rust application | Embedded store and a check at actual dispatch | |
Python application | Local sidecar and | |
OpenAI Agents SDK function tools | Sidecar and | |
FastMCP server you own | Sidecar and | |
Node or another language | Local sidecar; source Node client or HTTP protocol | |
Trusted stdio MCP server |
| |
Desktop MCP client | Verified local bundle and private operator configuration | |
Docker-launched MCP client | Source-built stdio container and trusted downstream |
Choose the exact bundle and matching configuration before installation. Blank configuration exposes two read-only setup tools and provides no active protection. Configured tools come from your trusted downstream server. Version 2 bundle runs require a fixed deadline, deliberate renewal mode and reviewed offline exceptions. The bundle uses broad one-shot tool approvals; it does not provision exact-action grants. Configuration · Editor guide.
Discover versioned bundles through Smithery and the official MCP Registry. Check each entry's version and checksum. Discovery is not hosted operator access, marketplace acceptance of another submission, or an endorsement.
Put the gate at the effect
Your trusted executor creates the run and configures policy first. With the matching Python client installed and its sidecar configured:
from pathlib import Path
from deadbolt_client import dispatch
outcome = dispatch(
"executor-run-001", "write_file",
lambda: Path("output.txt").write_text("allowed work"),
)
if not outcome["executed"]:
print("Action blocked:", outcome["decision"]["code"])A fresh admission happens before the callback; a denial leaves the body uncalled.
Complete setup covers provisioning, policy, credentials,
transport and errors. Wrap every protected route. Never cache an allow or split
one-shot admission from execution. ensure confirms record presence, not liveness.
Controls and limits
Tool and destination policies, reported-spend caps, pause, clips and operator kill.
Default 60-second idle TTL. A separate supervisor maintains fresh runs; explicit activity mode is available. Neither mode can move a fixed deadline or revive expired/killed state. Liveness · Deadlines.
Descendants obey ancestor restrictions. A child policy cannot widen its parent.
Broad one-shot tool approvals and exact-action grants for trusted integrations using the content-bound API.
Scoped admission credentials separate dispatch from operator controls.
/spendremains operator-only.SQLite evidence, JSONL mirrors and per-agent incident exports.
Store or transport failure denies protected dispatch; malformed or unsuccessful responses never authorize the body.
Ordinary trusted-executor admission treats unset policy lists as open; the MCP proxy requires explicit tool policy. Configure runs and children before dispatch. MCP discovery can advertise tools that the policy will deny. Destination parsing covers recognized fields, not arbitrary arguments or network traffic. Destination policy.
Know the boundary
DeadBolt protects connected execution routes. It does not sandbox arbitrary code, stop a provider, or make external effects transactional with admission. Kill blocks subsequent admissions; stopping in-flight work requires an executor cancellation pattern. The MCP child remains trusted and has OS access; startup and non-tool methods are outside the tool-call gate.
Keep state and operator authority outside untrusted agent processes. A process able to write the database or invoke the operator CLI has operator authority; socket credentials cannot contain it. Use separate OS/service ownership and OS egress controls where your application requires those boundaries. Evidence hashes identify content; operator-writable records are not tamper-proof certification. Trust · HTTP authentication · Pilot checklist.
Developer documentation
Need | Guide |
First working result | |
Binary, crate or Python installation | |
Embed, sidecar or MCP wiring | |
Least-authority dispatch and sensitive actions | |
API and upgrade behavior | |
Denial or setup problem | |
Deploy, backup and respond | |
Evaluate or contribute | |
Versions and packaging |
Source checks: cargo test --locked, cargo clippy --all-targets --locked -- -D warnings,
and python3 tests/client_contract.py after cargo build --locked --bin deadbolt
(Python and Node required). CI also checks Rust 1.85, installed Python/SDK behavior
and native packages. Passing these checks does not establish acceptance of your application.
Report ordinary bugs or use private security reporting. Copyright NextEleven LLC 2026. License · Notice. Harness is one consumer, not a prerequisite.
For trusted executors that need to stop already running local commands, the owned-process cancellation reference adds a POSIX supervisor pattern with disposable acceptance. It does not change the gate into a sandbox or add enforcement to older packages.
Available Tools
2 toolsdeadbolt_check_bundleARead-onlyIdempotent
Read the bundled engine and provenance metadata, calculate its SHA-256 and report compatibility and packaging integrity for this host. Reads only this installed bundle; does not execute the engine, inspect operator state or test security. Available only when operator configuration is blank.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| target | Yes | Native target for this host, or unsupported. |
| boundary | Yes | Protection scope and setup-mode limitation. |
| bundle_version | Yes | Installed launcher bundle version. |
| engine_version | Yes | Pinned preview engine version. |
| checksum_matches | Yes | Whether the bundled executable matches its packaged SHA-256 metadata. This is corruption detection, not independent signature verification. |
| active_protection | Yes | Always false in setup mode; no downstream server is configured. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive and closed-world, and the description reinforces this with a hard scope boundary: it touches only the installed bundle and performs no execution, operator-state inspection, or security testing. The credential-like caveat about blank operator configuration is additional context the annotations do not carry.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences: what is read and computed first, scope exclusions second, availability condition last. Every clause carries distinct information with no repetition of the title or annotations.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With zero parameters, a present output schema, and full annotation coverage, the description needs only to define operation and scope, which it does. Nothing an agent needs to decide to call this tool is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so per the rubric the baseline is 4; the description correctly implies no inputs are needed and nothing about input semantics is ambiguous. There is nothing for the description to add beyond what the empty schema already communicates.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a precise verb chain (read engine + provenance metadata, calculate SHA-256, report compatibility and packaging integrity) against a clearly named resource, the installed bundle. It does not explicitly contrast itself with the sibling deadbolt_get_integration_guide, but the two operations are so distinct that selection is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states a positive precondition ('Available only when operator configuration is blank') and negative scope ('does not execute the engine, inspect operator state or test security'), which tells the agent when this tool is appropriate and what it will not cover. It stops short of naming an alternative tool when the precondition fails.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
deadbolt_get_integration_guideARead-onlyIdempotent
Get local, read-only DeadBolt setup steps for a supported integration route. Returns operator responsibilities, a placeholder configuration and the enforcement boundary. Does not create files, run a server or grant permission. Available only when operator configuration is blank.
| Name | Required | Description | Default |
|---|---|---|---|
| route | Yes | Integration route: claude_desktop for this bundle, stdio_client for a terminal/editor MCP client, rust for embedding the crate, or http for the local sidecar. |
Output Schema
| Name | Required | Description |
|---|---|---|
| route | Yes | Requested integration route. |
| steps | Yes | Ordered steps for the trusted developer/operator. |
| boundary | Yes | Protection scope and setup-mode limitation. |
| documentation_url | Yes | Official integration documentation URL; this tool performs no network request. |
| operator_config_example | Yes | JSON template for the bundle; replace all placeholders deliberately. This tool does not save or apply it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint and destructiveHint=false, so the safety profile is covered. The description still adds real value beyond them: the gating condition (only when operator configuration is blank) and the explicit negative guarantees about not running a server or granting permission are not derivable from the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, front-loaded with the verb and resource, and the precondition is placed last where it is easy to scan. The sentence enumerating return contents is slightly redundant given a dedicated output schema exists, but it is not wasteful enough to penalize heavily.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter, read-only tool with a full output schema and rich annotations, the description supplies the pieces structured fields cannot express: the gating condition and the negative guarantees. Only the relationship to the sibling tool is unstated.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single 'route' parameter carries a full enum with per-value explanations, so the schema does all the work. The description only gestures at 'a supported integration route' without adding syntax or selection guidance, matching the baseline for fully documented parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Get') and a specific resource ('local, read-only DeadBolt setup steps for a supported integration route'), so the agent knows exactly what the tool produces. However, it never contrasts itself with its only sibling deadbolt_check_bundle, leaving the agent to infer the boundary between reading a guide and checking a bundle.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The closing clause 'Available only when operator configuration is blank' is a concrete precondition that tells the agent when this tool applies, which is more than most definitions offer. It stops short of naming an alternative for the non-blank case, so the routing decision is still partly left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
2 tool updates
v2.0.0- First observed
deadbolt_check_bundle - First observed
deadbolt_get_integration_guide
TDQS
Scored across 2 tools
The two tools have clearly distinct purposes: one returns human-readable setup guidance, the other computes bundle integrity/hash metadata. Their descriptions explicitly state what each does and does not do, leaving no realistic room for misselection.
Both names use the same server prefix plus a consistent verb_noun pattern (deadbolt_get_integration_guide, deadbolt_check_bundle), with no mixed casing or style drift.
Two tools is thin even for a narrow, read-only pre-configuration surface; an agent will likely need more than guidance plus a bundle check. The count is not wrong, but it is borderline minimal.
The surface covers the two advertised functions (setup guidance, bundle verification) but has notable gaps: no way to enumerate supported integration routes, validate a candidate placeholder config, or confirm host prerequisites beyond the bundle hash. Agents hitting those needs have no tool path.
Maintenance
Related MCP Connectors
MCP server for mandates, delegation, policy-gated execution, credential grants, and audit.
- gatewayOAuthai.sealgate
MCP gateway with runtime security policy, tool-call-level control, and audit of agent actions.
Guard wraps stdio MCP servers: risky calls wait for a person; no answer, no run. Remote: cooperative
MCP server for your apps' tools and custom tools, plus hosted AI agents and approval-gated workflows
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceA least-privilege enforcement proxy for MCP servers. It sits between MCP clients and upstream servers, enforcing tool policies, hiding denied tools, requiring human approval for risky actions, and providing a structured audit trail.MIT
- AlicenseNot gradedqualityCmaintenanceProxies MCP traffic between a client and a downstream server to enforce runtime policies on tool declarations, call arguments, and results, including allowlisting, sandboxing, secret and egress controls, and injection detection. It also includes a deterministic benchmark for measuring which security controls stop which attacks.MIT
- AlicenseNot gradedqualityBmaintenanceEnables developers to wrap existing MCP servers with a deterministic policy enforcement gate that intercepts tool discovery and tools/call requests over stdio, allowing only authorized calls to reach the downstream server. It supports dynamic tool exposure or hiding, allow/deny/approval-required decisions, configurable error disclosure modes, and Ed25519-signed retry credentials for approved workflows.Apache 2.0
- AlicenseNot gradedqualityCmaintenanceSits in front of any MCP server to enforce allow/ask/block policies on tool calls, paths, shell commands, and network domains, with local approval prompts and an audit log.MIT