Composable guardrails for OpenAI-compatible clients and native PyTorch generation.
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 openwardenfrom 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.
- Synchronous
OpenAIand asynchronousAsyncOpenAIclients. responses.create(...)andchat.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
GuardedResultmetadata. - Fail-open and fail-closed operation.
Unsupported SDK resources pass through to the wrapped client unchanged.
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.
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.
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()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.
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.
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.
OpenWarden is available under the MIT License.