Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

Python client and OpenAI function tools (1.1.0-rc.1 prerelease)

The 1.1.0-rc.1 prerelease provides an installable Python client and an optional OpenAI Agents SDK adapter. It is not published on PyPI and is not in v1.0.3. The client talks to the separately installed DeadBolt executable; the wheel does not bundle or start it. The base client uses only Python's standard library and its wheel runs on Python 3.9+. Building/installing from source requires Python 3.10+ for the patched build backend. The optional adapter uses the pinned, tested openai-agents==0.23.1; use Python 3.10+ for that SDK.

Install the release wheel or a reviewed checkout

Download the wheel and SHA256SUMS from the versioned prerelease, verify its hash, and install in your application's virtual environment:

python -m pip install /absolute/path/to/n11_deadbolt_client-1.1.0rc1-py3-none-any.whl
# Optional SDK integration uses Python 3.10+:
python -m pip install '/absolute/path/to/n11_deadbolt_client-1.1.0rc1-py3-none-any.whl[openai-agents]'

Alternatively, activate the environment, then install from an absolute path to the reviewed source or extracted candidate archive:

python -m pip install /absolute/path/to/deadbolt
# Optional SDK integration:
python -m pip install '/absolute/path/to/deadbolt[openai-agents]'

For a wheel, first install the build frontend with python -m pip install build==1.3.0, then run python -m build --outdir release-artifacts/python in the source checkout. Install the resulting .whl by its full path. Install with [openai-agents] to include the SDK, or omit it to keep the client dependency-free. Do not use pip install n11-deadbolt-client until a registry release exists.

The wheel installs deadbolt_client, deadbolt_openai_agents and the deadbolt-client command. Existing source imports of deadbolt_client keep working; there is one implementation, rather than a copied package client.

Operator setup, outside the agent

See operations for durable state, private paths and credentials. Use a new executor-assigned run ID and configure its policy before running it. On Unix the default local socket can be used. Windows requires a loopback TCP address. Keep DEADBOLT_TOKEN in the sidecar/operator environment. Leave DEADBOLT_ADMISSION_TOKEN absent during operator setup below. Set it only in the dispatcher environment after lease/policy setup and issuance; see credential issuance.

deadbolt serve
# In another terminal, with the same sidecar/state configuration:
deadbolt-client ensure --agent my-run-001
deadbolt policy --agent my-run-001 --tools write_file
# Then issue the admission credential and launch the dispatcher with it.

Check that ensure returns ok: true. Do not expose ensure, policy, approval, resume, spend or child-registration methods as model tools. Lease creation and explicit ensure calls belong to the trusted executor; this decorator never calls ensure. Ordinary admission retains DeadBolt's sliding TTL for already live leases. It cannot revive an expired or killed run.

Add the decorator to the actual body

from pathlib import Path
from agents import Agent
from deadbolt_openai_agents import protected_tool

@protected_tool(agent_id="my-run-001")
async def write_file(content: str) -> str:
    """Write the application-owned output file."""
    Path("output.txt").write_text(content)
    return "written"

agent = Agent(name="Writer", tools=[write_file])

Use protected_tool in place of function_tool on Python functions. The SDK still generates the schema, validates arguments, handles context and runs its own guardrails and approval flow. DeadBolt checks immediately before the validated function body runs, including after a paused SDK run is approved and resumed. Synchronous bodies run in a worker thread; asynchronous bodies are awaited. Return values are preserved. A denial raises DeadboltDenied; the SDK Runner wraps it in agents.exceptions.UserError, preserving it as the cause. It stops the run and does not invoke the body. Ordinary body errors also stop the run through that SDK wrapper. Handle denials without parsing error text:

from agents import Runner
from agents.exceptions import UserError
from deadbolt_openai_agents import denial_code

try:
    result = await Runner.run(agent, user_input)
except UserError as error:
    code = denial_code(error)
    if code is None:
        raise  # Ordinary tool/SDK failure, not an admission denial.
    print("Action blocked:", code)

Display a blocked action or request operator intervention. Do not blindly retry.

The decorator forwards SDK options such as name_override, needs_approval, tool_input_guardrails and timeout. For example:

@protected_tool(agent_id="my-run-001", name_override="send_email", needs_approval=True)
async def send_email(recipient: str, body: str) -> str:
    # Your trusted, validated mail implementation goes here.
    ...

The SDK's human approval and DeadBolt admission are separate decisions. This adapter does not automatically grant either one. If the operator configures send_email as irreversible in DeadBolt, it also needs a DeadBolt one-shot approval. That existing approval covers the agent/tool pair, not these exact arguments. Use the SDK's application-controlled per-call review or configure the candidate's exact-action grant with action_grant to bind the actual validated arguments. SDK error-as-output handlers are rejected; failure_error_function must be None, so a blocked action or failing body stops instead of encouraging retries.

For destination policy, supply a fixed host or a trusted synchronous resolver:

@protected_tool(agent_id="my-run-001", destination=lambda args: args["host"])
async def fetch(host: str) -> str:
    # Validate/canonicalize host and enforce it in the actual HTTP implementation.
    ...

Resolvers see the SDK-validated Python arguments, including defaults and context when present. They must return a valid DeadBolt host token; a resolver failure or missing destination stops before admission and does not consume a one-shot. They must identify the host the body really uses. DeadBolt compares tokens; it does not constrain redirects, DNS, socket traffic or other destinations visited inside the body. A custom tool name is not automatically recognized as a network tool; always provide its actual destination when using destination policy.

Coverage and trust boundary

  • Decorate every protected function on every agent, including specialists reached through handoffs. This adapter does not scan an Agent or silently wrap all tools.
  • Existing FunctionTool objects, Agent.as_tool() wrappers, hosted tools, computer/shell/apply-patch tools and handoffs are not accepted by this decorator. Gate their actual local implementations separately. For local stdio MCP, use the MCP proxy.
  • SDK schema validators, approval callbacks, guardrails, destination resolvers, error handlers and hooks are trusted application code outside the protected function body. Do not put protected effects there.
  • The model must not control the run ID, tool identity, gate credentials, stored policy or operator approval. Use a fixed-agent admission credential for the dispatcher. DEADBOLT_TOKEN retains all operator route authority and must stay outside workload access. Setting DEADBOLT_ADMISSION_TOKEN puts all client calls in workload mode, including control calls, with no operator fallback.
  • Admission is not atomic with execution, does not revoke work already running, and does not create a filesystem/network/process sandbox. A cancelled sync body may continue in its worker thread; other already admitted tools in a parallel batch may finish when one tool is denied. Protect resources with separate OS and service controls when the process can execute untrusted code.
  • This adapter supports the pinned Python SDK contract. TypeScript, hosted MCP and other SDK versions need their own acceptance; they are not claimed here.

Try the disposable, one-command demonstration first:

python /absolute/path/to/deadbolt/examples/openai_agents_demo.py --binary /absolute/path/to/deadbolt-executable

It starts its own temporary sidecar, writes one allowed file, revokes the run, verifies the second write was blocked, and cleans up. It uses the real SDK with scripted tool calls, disables tracing and makes no provider requests.

Run the installed-wheel acceptance suite with the real sidecar:

python /absolute/path/to/deadbolt/tests/openai_agents_acceptance.py

Set DEADBOLT_BIN to your reviewed executable's absolute path when it is not at the source checkout's target/debug/deadbolt. Tests use the SDK's ScriptedModel and disable tracing. They perform local file effects and approval/resume flows without provider requests, API credentials or paid turns. Automated framework acceptance is not outside customer adoption.

Exact-action source candidate

The opt-in exact-action protocol binds reviewed arguments, run, tool, destination, nonce and deadline. Its new endpoint cannot fall back to legacy admission. Approval enables exact-only policy for that run/tool; nonces persist after use/revocation. Existing unconfigured integrations retain their behavior. This is available in 1.1.0-rc.1. Older binaries cannot enforce these new requirements; quiesce protected dispatch before any rollback.

Metadata

Release files for n11-deadbolt-client 1.1.0rc1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for n11-deadbolt-client 1.1.0rc1
File Size Uploaded
n11_deadbolt_client-1.1.0rc1.tar.gz 31.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for n11-deadbolt-client 1.1.0rc1
File Interpreter ABI Platform
n11_deadbolt_client-1.1.0rc1-py3-none-any.whl Python 3 none any Details

Total release size: 48.2 kB

Release files / n11_deadbolt_client-1.1.0rc1.tar.gz

Download URL n11_deadbolt_client-1.1.0rc1.tar.gz
Size 31.6 kB
Tags Source
SHA-256 checksum
How to use checksums
d83629e52b2cc620b550d54aa6b3e155e8cdfa8ac7734f8159e7edc0a466ade5
BLAKE2b-256 checksum
How to use checksums
9916879de3facb6c7e843b37340fe44c5b2b137c732c96d17d75403b341b498f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 11, 2026.

Transparency log

Release files / n11_deadbolt_client-1.1.0rc1-py3-none-any.whl

Download URL n11_deadbolt_client-1.1.0rc1-py3-none-any.whl
Size 16.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e8ac19f1f8aeb544e95504bafbf69f87e53e6fc85e1826802a57c98a1abc7153
BLAKE2b-256 checksum
How to use checksums
055b6253298c628d80db01acaba961776c5ccd5ef38c1a74693d1643631a187b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 11, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.1.0rc1 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page