gentrail
Governance SDK for AI agents. It captures compliance-evidence-grade telemetry from an agent run and, when enabled, enforces policy inline before a tool call executes.
A Go SDK with the same span shape lives in ../go/ (go get github.com/aigentrail/sdk/go).
Quickstart
pip install "gentrail[strands]"
export GENTRAIL_API_KEY="sk-..."
import gentrail
from strands import Agent
g = gentrail.init()
agent = Agent(model=model, tools=tools, hooks=[g.hook()])
agent("Reconcile the Q3 invoices")
That is the whole integration. init() reads the environment, builds the
governance tracer and the policy enforcer, and hook() returns a Strands
HookProvider that captures prompts, chain-of-thought, and tool calls, ships
them over OTLP, registers the agent on its first invocation, and enforces
verdicts before a tool runs. Use one hook() per agent. Whatever is not
configured stays off: with no API key the agent still runs, capture-only.
OpenAI Agents SDK
pip install "gentrail[openai-agents]"
from agents import function_tool
from gentrail.openai_agents import enforcement_guardrail
@function_tool(tool_input_guardrails=[enforcement_guardrail()])
def run_sql(database: str, sql: str) -> str: ...
A tool input guardrail that asks the decide endpoint before the tool runs. BLOCK rejects the call with the policy message; GATE holds it until a human approves in the Gentrail dashboard.
LangChain / LangGraph
pip install "gentrail[langchain]"
from langchain.agents import create_agent
from gentrail.langchain import enforcement_middleware
agent = create_agent(
model=model,
tools=tools,
middleware=[enforcement_middleware(agent_id="reporter")],
)
Agent middleware wrapping every tool call, sync and async. Same verdicts: a
blocked or unapproved call becomes an error ToolMessage and the tool never
executes.
Bring your own telemetry
Frameworks that emit OpenTelemetry GenAI telemetry natively (Strands with
strands-agents[otel], Google ADK, Pydantic AI, LangChain with
LANGSMITH_OTEL_ENABLED, the Vercel AI SDK) do not need the SDK to build
spans: the Gentrail backend ingests gen_ai.*, ai.*, and OpenInference
telemetry directly. This is the recommended integration for those frameworks.
What the SDK still adds is client-side PII redaction and export to Gentrail:
import gentrail
gentrail.instrument()
instrument() attaches a GentrailSpanProcessor to your application's
TracerProvider (pass yours with instrument(provider=...); a fresh one is
installed only when none exists). The processor redacts PII from gen_ai.*,
ai.*, and OpenInference input/output attributes before any value leaves the
process, stamps aigentrail.redaction.applied on spans it changed, and ships
them to the Gentrail collector over OTLP. Other exporters on the provider keep
the raw spans. Without GENTRAIL_API_KEY it returns None and the app runs
unchanged.
Inline enforcement stays separate: add the enforcement adapter for your framework (above) to get BLOCK and GATE verdicts before a tool runs.
Configuration
All through environment variables:
GENTRAIL_API_KEY: enables OTLP export of governance spans.OTEL_EXPORTER_OTLP_ENDPOINT: collector base URL, defaulthttps://otel.gentrail.ai.OTEL_EXPORTER_OTLP_HEADERS: standard OTel header list; when set it replaces the SDK's defaultAuthorization: Bearer <GENTRAIL_API_KEY>header.GENTRAIL_DECIDE_ENDPOINT: enables inline enforcement (see below).GENTRAIL_REDACT_PII: set tofalseto disable client-side PII redaction.GENTRAIL_GATE_TIMEOUT_SECONDS: how long a gated tool call waits for human approval, default 120.
If your application already configures an OpenTelemetry TracerProvider, the
SDK attaches its exporter to it as an extra span processor instead of replacing
it; a fresh provider is installed only when none exists.
PII redaction
The SDK redacts high-confidence PII (emails, SSNs, credit cards, AWS keys)
from span input and output values before they leave the process, replacing each
with a typed placeholder like [EMAIL], so the raw value never reaches the
collector while the data class stays visible for governance. This applies to
spans the SDK builds and, via GentrailSpanProcessor, to gen_ai.*, ai.*,
and OpenInference attributes on spans your framework emits itself. On by
default; opt out with GENTRAIL_REDACT_PII=false or instrument(redact=False).
Inline enforcement (opt-in)
The async backend evaluator only sees a trace after a tool has already run, so it can detect but never prevent. Enforcement happens here, in the before-tool-call hook: the SDK asks the backend for a verdict on the proposed tool call and stops it before it executes.
It is opt-in and fails open. Set both environment variables to turn it on:
export GENTRAIL_DECIDE_ENDPOINT="https://your-dashboard.example"
export GENTRAIL_API_KEY="sk-..."
With these set, a BLOCK verdict cancels the tool call (the agent receives an
error tool result and the tool never runs). A GATE verdict also stops the call
pending human approval. A backend error never breaks the agent: the call is
allowed and enforcement is skipped for that step.
Advanced: raw capture surfaces
init() and hook() compose lower-level pieces that remain importable for
consumers that need them directly:
evidence_ledger.py: a local append-only audit log with integrity hashes; the hook seals oneDecisionJournalper invocation.otel_exporter.py:create_governance_tracer()/get_governance_tracer()build the OTLP pipeline without the rest of the SDK.enforcement.py:PolicyEnforcerand its asyncio twinAsyncPolicyEnforcerare the raw decide/gate clients.
Develop
uv sync --extra strands
ruff check .
python3 tests/test_enforcement.py
python3 tests/test_init.py
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file gentrail-0.5.0.tar.gz.
File metadata
- Download URL: gentrail-0.5.0.tar.gz
- Upload date:
- Size: 189.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
29c9d0f88a971d4d953d7f73ded06bf7522f33544862a023e63f259f640df538
|
|
| MD5 |
bf61946f433c1f3a8ca8432e57189396
|
|
| BLAKE2b-256 |
95259537a92afea470f00bca8c5117fbf7beb4a23ff0f24decb545c85755f252
|
Provenance
The following attestation bundles were made for gentrail-0.5.0.tar.gz:
Publisher:
publish.yml on aigentrail/sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gentrail-0.5.0.tar.gz -
Subject digest:
29c9d0f88a971d4d953d7f73ded06bf7522f33544862a023e63f259f640df538 - Sigstore transparency entry: 2591437295
- Sigstore integration time:
-
Permalink:
aigentrail/sdk@3d764dcd9c858ad493b8f516ef913f1879a2dfe1 -
Branch / Tag:
refs/tags/v0.5.0 - Owner: https://github.com/aigentrail
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@3d764dcd9c858ad493b8f516ef913f1879a2dfe1 -
Trigger Event:
push
-
Statement type:
File details
Details for the file gentrail-0.5.0-py3-none-any.whl.
File metadata
- Download URL: gentrail-0.5.0-py3-none-any.whl
- Upload date:
- Size: 27.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9ba6f50c353103c234cbfa0f72fb7bd5727aa0ce994aa83979748640d5f57edd
|
|
| MD5 |
5e22b8a90a04ded08078ef40f381e184
|
|
| BLAKE2b-256 |
847f9017a6d0de8aff609cff4865af1d6f6d9341d89a6f8a95b8407020bbb9b2
|
Provenance
The following attestation bundles were made for gentrail-0.5.0-py3-none-any.whl:
Publisher:
publish.yml on aigentrail/sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gentrail-0.5.0-py3-none-any.whl -
Subject digest:
9ba6f50c353103c234cbfa0f72fb7bd5727aa0ce994aa83979748640d5f57edd - Sigstore transparency entry: 2591438276
- Sigstore integration time:
-
Permalink:
aigentrail/sdk@3d764dcd9c858ad493b8f516ef913f1879a2dfe1 -
Branch / Tag:
refs/tags/v0.5.0 - Owner: https://github.com/aigentrail
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@3d764dcd9c858ad493b8f516ef913f1879a2dfe1 -
Trigger Event:
push
-
Statement type: