Skip to main content

Whiteout AI Governance SDK

Wrap AI API calls with Whiteout policy enforcement. Three lines of code to add governance to any Python AI application.

Install

pip install whiteout-ai

Custom AI Apps: AppGuard (0.2+)

For your own LLM applications registered under Integrations → Custom AI Apps. Authenticates with the app key from the setup wizard, with no registration step, and checks both the prompt and the model's reply.

pip install "whiteout-ai>=0.2"
export WHITEOUT_APP_KEY=wo_app_prod_...
export WHITEOUT_BASE_URL=https://api.whiteout.groovysec.com   # the default
from openai import OpenAI
from whiteout_ai import AppGuard, WhiteoutBlockedError

guard = AppGuard()
client = guard.openai(OpenAI())            # or guard.anthropic(Anthropic())

try:
    reply = client.chat.completions.create(
        model="gpt-5", messages=messages,
        whiteout={"end_user": user.id},     # optional; never sent to OpenAI
    )
except WhiteoutBlockedError as e:
    print(e.stage, e.reason, e.violated_policies)   # stage: "input" or "output"

The wrapped client is the same object with chat.completions.create (or messages.create) governed. Everything else passes straight through.

What gets scanned. By default this is the latest user message. Pass scan=["user", "system", "context", "tool"] to the constructor, or per call via whiteout={"scan": [...]}, to also catch sensitive data in system prompts, retrieved documents (context=) and tool results.

Checking without a wrapper:

d = guard.check_input(messages, context=retrieved_docs, model="gpt-5", provider="openai")
reply = call_your_model(messages)
guard.check_output(d.evaluation_id, reply)    # raises WhiteoutBlockedError on block

Streaming. stream=True works for both providers.

stream_mode Behaviour
"buffered" (default) The whole response is held until the output check passes, so nothing flagged reaches the user.
"passthrough" Chunks are yielded as they arrive, with a check every check_every characters (default 2000) plus a final check. It stops at the first flagged checkpoint. Text already shown cannot be retracted, so use buffered mode where you enforce.

Fail behaviour. If Whiteout is unreachable, or the key is revoked (logged at ERROR), the SDK applies your policy group's fail behaviour from GET /v1/guard/config. That setting is cached for 5 minutes and revalidated with an ETag. Pass fail_open=True/False to override it. With no config yet, the SDK fails open.

Async. AsyncAppGuard has the same surface (await guard.check_input(...), guard.openai(AsyncOpenAI()), async for over streams). Use it as async with AsyncAppGuard() as guard: so pending background checks drain on exit.

LangChain.

from whiteout_ai.langchain import WhiteoutCallbackHandler   # pip install "whiteout-ai[langchain]"
llm = ChatOpenAI(callbacks=[WhiteoutCallbackHandler(AppGuard())])

A block raises out of the chain. Streaming chains are checked when the completion finishes.

Other options:

  • block_output=False makes output checks fire-and-forget (observe the reply without blocking it).
  • send_events([...]) reports calls after the fact (observe-only, batched).
  • timeout sets the request timeout in seconds (default 10).

No code changes: auto-instrumentation (0.3+)

pip install "whiteout-ai[auto]"
export WHITEOUT_APP_KEY=wo_app_prod_...
whiteout-ai run python app.py            # or: whiteout-ai run -- gunicorn app:server
whiteout-ai check                        # key set? which clients will be governed?

In a container where you can't change the start command, put the bootstrap on the path instead: PYTHONPATH="$(whiteout-ai bootstrap-path)". It runs any sitecustomize you already have.

What gets governed:

  • openai: chat completions and the Responses API, sync and async.
  • anthropic: messages.create, sync and async. messages.stream() is checked on input, and its final text is recorded.
  • boto3 bedrock-runtime: Converse and InvokeModel (input and output) and the streaming variants (input). This runs through botocore's event system.

A library is patched when your app imports it, so there's no startup cost for clients you don't use.

Environment variables:

Variable Values
WHITEOUT_MODE enforce (default) or observe. Observe checks and records but never raises.
WHITEOUT_STREAM_MODE Stream mode for governed calls
WHITEOUT_SCAN Which parts of the call to scan
WHITEOUT_INCLUDE / WHITEOUT_EXCLUDE openai, anthropic, bedrock
WHITEOUT_DISABLE=1 Turns it off completely

Limits: raw HTTP calls to a model API aren't seen. If a declared model host is called without Guard events, the AI Footprint still flags it.

Prompt injection: quarantine (0.3+)

When your org has Prompt Injection Defense on, a tool result or system prompt carrying instructions can be quarantined. Wrapped clients, and auto-instrumentation, replace that turn with a short notice before the model sees it. Tool calls stay paired, and your own objects are never changed.

Context documents you send as context= can't be rewritten inside your prompt, so drop them yourself:

d = guard.check_input(messages, context=docs, scan=["user", "context"])
docs = d.clean_context(docs)             # the documents Whiteout didn't quarantine

Replies are checked for injected instructions too. If your org blocks such content, check_output blocks.

The employee's own policies (0.3+)

If the app is set to the employee's own policies in the admin console, pass the signed-in employee's OIDC id_token. Whiteout then applies their group's policies, just as it does in ChatGPT:

guard.check_input(messages, user_token=session["id_token"])
client.chat.completions.create(model=..., messages=..., whiteout={"user_token": session["id_token"]})

Infrastructure workloads: WhiteoutGuard

WhiteoutGuard is unchanged. It uses an enrollment token and the /infra-agent routes, and suits workloads enrolled as infrastructure resources.

Quick Start

from whiteout_ai import WhiteoutGuard

guard = WhiteoutGuard(
    token="whiteout_enroll_...",
    backend_url="https://your-org.api.whiteout.groovysec.com",
)

# Option 1: Evaluate a prompt directly
result = guard.evaluate(
    prompt="Summarize this patient record...",
    ai_provider="openai",
    model="gpt-4o",
)
# result = {"decision": "block", "reason": "Contains PHI", ...}

# Option 2: Wrap an OpenAI call
import openai
response = guard.wrap(
    openai.chat.completions.create,
    model="gpt-4o",
    messages=[{"role": "user", "content": "Hello world"}],
)

# Option 3: Catch blocked prompts
from whiteout_ai import WhiteoutBlockedError
try:
    guard.evaluate(prompt="SSN 123-45-6789")
except WhiteoutBlockedError as e:
    print(f"Blocked: {e.reason}")
    print(f"Policies: {e.violated_policies}")

Configuration

Parameter Required Default Description
token Yes - Enrollment token from Whiteout admin
backend_url Yes - Your org's Whiteout API URL
fail_open No True Allow calls when backend unreachable
timeout No 10.0 Backend call timeout (seconds)
mode No sdk Deployment mode identifier

Features

  • Automatic provider detection (OpenAI, Anthropic, Google, Mistral)
  • Fast checks cached locally (provider block, model allowlist)
  • Remote compliance evaluation for content policies
  • Output governance (response scanning in background)
  • Fail-open by default (never breaks your app)
  • Thread-safe

Metadata

Release files for whiteout-ai 0.3.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 whiteout-ai 0.3.0
File Size Uploaded Provenance Actions
whiteout_ai-0.3.0.tar.gz 8.6 MB With provenance Details for whiteout_ai-0.3.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for whiteout-ai 0.3.0
File Interpreter ABI Platform Actions
whiteout_ai-0.3.0-py3-none-any.whl Python 3 none any Details for whiteout_ai-0.3.0-py3-none-any.whl

Total release size: 8.7 MB

Release files / whiteout_ai-0.3.0.tar.gz

Download URL whiteout_ai-0.3.0.tar.gz
Size 8.6 MB
Tags Source
SHA-256 checksum
How to use checksums
e2641d07eefeba8074358e2812587d43561f152c4edaa646171336bc20a87380
BLAKE2b-256 checksum
How to use checksums
552c8137b30544c45c12ab8e373572b7e24fc75c9096c66db6fa0b3c4b1beb5f
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 Sep 28, 2026.

Transparency log

Release files / whiteout_ai-0.3.0-py3-none-any.whl

Download URL whiteout_ai-0.3.0-py3-none-any.whl
Size 38.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
fd3cf43ea6880b5c75cc5d4db29917c7a27d12ab41da21533e4ee9c2acafb700
BLAKE2b-256 checksum
How to use checksums
0fe8ff74601d2fb385fad2e760652afddd63c9946e8b0d1df3c15dc80e0a38dd
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 Sep 28, 2026.

Transparency log

Security for whiteout-ai 0.3.0

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.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for whiteout_ai-0.3.0.tar.gz

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 Sep 28, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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