Skip to main content

OpenWarden

Composable guardrails for OpenAI-compatible clients and native PyTorch generation.

CI PyPI Python versions Typed MIT license

OpenWarden wraps clients and models you already use. It intercepts supported generation calls, evaluates their input and output, and either returns the original response object or raises an explicit guard exception.

pip install openwarden

Quick Start

from openai import OpenAI

from openwarden import GuardMode, GuardedOpenAI, WardenConfig
from openwarden.guards.regex import RegexSecretGuard

client = GuardedOpenAI(
    OpenAI(),
    guard=RegexSecretGuard(),
    config=WardenConfig(
        mode=GuardMode.BOTH,
        fail_open=False,
    ),
)

response = client.responses.create(
    model="your-generation-model",
    instructions="You are concise and helpful.",
    input="Explain Python decorators with a simple example.",
)

print(response.output_text)

Allowed calls return the original OpenAI SDK object. Blocked calls raise GuardViolation.

Supported Surfaces

  • Synchronous OpenAI and asynchronous AsyncOpenAI clients.
  • responses.create(...) and chat.completions.create(...).
  • Native PyTorch or Transformers model.generate(...).
  • Input-only, output-only, both, and disabled modes.
  • Block, redact, rewrite, annotate, and log-only enforcement actions.
  • Deterministic guards, guard pipelines, and prompted guard models.
  • Per-call overrides and context-managed overrides.
  • RAG retrieval, context injection, and grounding extension points.
  • Trace IDs, decisions, latencies, and optional GuardedResult metadata.
  • Fail-open and fail-closed operation.

Unsupported SDK resources pass through to the wrapped client unchanged.

Guard Models

ModelPromptGuard can call a dedicated policy model through any compatible OpenAI endpoint:

import os

from openai import OpenAI

from openwarden import GuardMode, GuardedOpenAI, WardenConfig
from openwarden.guards.base import ModelPromptGuard

raw_client = OpenAI()

guard = ModelPromptGuard(
    raw_client,
    model=os.environ["GUARD_MODEL"],
    api="chat_completions",
    require_json=True,
)

client = GuardedOpenAI(
    raw_client,
    guard=guard,
    config=WardenConfig(mode=GuardMode.BOTH, fail_open=False),
)

Provider-specific generation parameters can be passed through create_kwargs.

Direct PyTorch Generation

OpenWarden does not import or pin PyTorch or Transformers. It composes around compatible objects from the versions selected by your application:

from transformers import AutoModelForCausalLM, AutoTokenizer

from openwarden import GuardMode, GuardedPyTorch, WardenConfig
from openwarden.guards.regex import RegexSecretGuard

model_id = "your-org/your-generation-model"
tokenizer = AutoTokenizer.from_pretrained(model_id)
raw_model = AutoModelForCausalLM.from_pretrained(model_id, device_map="auto")

model = GuardedPyTorch(
    raw_model,
    tokenizer=tokenizer,
    guard=RegexSecretGuard(),
    config=WardenConfig(mode=GuardMode.BOTH, fail_open=False),
)

inputs = tokenizer("Explain decorators.", return_tensors="pt").to(raw_model.device)
output = model.generate(**inputs, max_new_tokens=200)

Allowed calls return the original tensor or Transformers generation object. PyTorchPromptGuard can run a separate policy model locally.

Guard Decisions

Custom guards subclass BaseGuard and return structured decisions:

from openwarden import BaseGuard, GuardDecision


class CompanyPolicyGuard(BaseGuard):
    def check_input(self, context):
        if "confidential" in context.request.text().lower():
            return GuardDecision.block(
                "Confidential content cannot leave this boundary",
                categories=("data_policy",),
            )
        return GuardDecision.allow()

Configuration

from openwarden import GuardAction, GuardMode, WardenConfig

config = WardenConfig(
    mode=GuardMode.BOTH,
    input_action=GuardAction.BLOCK,
    output_action=GuardAction.BLOCK,
    fail_open=False,
    timeout_seconds=10,
)

Streaming is conservative by default. When output guarding is enabled, stream=True raises UnsupportedStreamingModeError rather than exposing tokens before the complete response can be evaluated.

Documentation

Security

OpenWarden is an application-layer policy boundary. It does not replace authorization, provider safety systems, deterministic access controls, or secure secret storage. Keep retrieval authorization in the data layer and use fail_open=False where enforcement is required.

Please report vulnerabilities according to the security policy. Do not open public issues containing credentials, private prompts, customer data, or model output.

Development

python -m pip install -e ".[dev]"
ruff check openwarden tests examples scripts
python -m pytest -q
python -m build
python -m twine check dist/*

See the contribution guide before submitting changes.

License

OpenWarden is available under the MIT License.

Release files for openwarden 0.1.0

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

Source distribution (sdist)

Source distribution for openwarden 0.1.0
File Size Uploaded
openwarden-0.1.0.tar.gz 207.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for openwarden 0.1.0
File Interpreter ABI Platform
openwarden-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 239.3 kB

Release files / openwarden-0.1.0.tar.gz

Download URL openwarden-0.1.0.tar.gz
Size 207.2 kB
Tags Source
SHA-256 checksum
How to use checksums
0d79b6d42511778b7b93756ec90ad46bd1b931221a7f9b6bd77b23f0666f92bb
BLAKE2b-256 checksum
How to use checksums
4975306889f9b6a29ae642f2294ba3f9af06842647facbf8c42f83f1ff997823
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.5

Release files / openwarden-0.1.0-py3-none-any.whl

Download URL openwarden-0.1.0-py3-none-any.whl
Size 32.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d6279ed2c86551f4c07714866735570af27594bf6d00602de4a1b7e1c2214814
BLAKE2b-256 checksum
How to use checksums
05a534bdf1ab49ad3cb9165c3a997c1ff439d1bee94d45a948a00b003e9af12b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.5

Release history Release notifications | RSS feed

This release

0.1.0 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