Quickstart
This guide takes you from nothing to a running firewall that blocks a real agent action in about five minutes. It uses LangGraph as the example framework, but the same three steps apply to any of the 10 supported frameworks.
Strathon sits between your agent and the tools and models it calls. Every tool call and model request is evaluated against your policies before it executes. A blocked call never runs; an approved call proceeds and is recorded in a tamper-evident audit log.
Prerequisites
- Docker (or Python 3.12+ and PostgreSQL 16 if you prefer to run from source)
- An existing agent built on a supported framework
1. Start the server
The fastest path is Docker Compose, which runs the receiver, the dashboard, and PostgreSQL together:
git clone https://github.com/strathon/strathon.git
cd strathon && docker compose up -dThe dashboard opens at http://localhost:3000 and the receiver API at
http://localhost:4318. The only dependency is PostgreSQL, which is included in
the Compose stack, so no separate database or email server is needed.
If you would rather run only the receiver, start it directly:
docker run -d --name strathon \
-p 4318:4318 \
-e DATABASE_URL="postgresql://strathon:strathon@db:5432/strathon" \
-e STRATHON_AUDIT_HMAC_KEY="$(openssl rand -hex 32)" \
-e STRATHON_ENCRYPTION_KEY="$(openssl rand -base64 32)" \
ghcr.io/strathon/receiver:latestRegister the first account in the dashboard; it becomes the project owner. For the full stack and production options, see Self-Hosting.
2. Create an API key and install the SDK
In the dashboard, go to Settings → API Keys and create a key. Then install the SDK with the extra for your framework:
pip install "strathon[langgraph]"3. Connect your agent
Add two lines to your existing agent. No other code changes are needed — Strathon instruments the framework's own extension points.
from strathon import Client, instrument
client = Client(
api_key="stra_...", # the key from step 2
endpoint="http://localhost:4318",
)
instrument(client, frameworks=["langgraph"])
# Your existing LangGraph agent runs unchanged from here.
result = agent.invoke({
"messages": [{"role": "user", "content": "Email the Q3 numbers to sales@competitor.com"}]
})4. Write a policy
Policies are written in CEL. Create one in the dashboard (Policies → New) or from the catalog of built-in templates. For example, to block any email tool call addressed to a competitor domain:
attrs["gen_ai.tool.name"] == "send_email"
&& attrs["strathon.tool.args"].contains("competitor.com")Set the action to block and the status to enabled. Start with shadow
status to see what would be blocked without actually blocking anything — see
Shadow mode.
5. See it work
Run your agent again. When it tries to send the email, Strathon raises
StrathonPolicyBlocked before the tool function executes. The agent never sends
the message.
from strathon import StrathonPolicyBlocked
try:
agent.invoke({"messages": [{"role": "user", "content": "Email our competitors with our pricing"}]})
except StrathonPolicyBlocked as e:
print(f"Blocked by policy: {e.policy_name}")
# The tool call never executed. Logged in the audit trail.Open the dashboard to review what happened:
- Traces shows the full execution, with the blocked span highlighted.
- Audit shows a tamper-evident record of the decision: which policy matched, what action was taken, and when.
Reliability: what happens if the receiver is unreachable
Policies evaluate inside your agent process, so a brief receiver outage does not add latency to tool calls. By default the SDK is fail-open: if it cannot reach the receiver to refresh policy or halt state, agents keep running rather than stalling. This favors availability and is the right default for most deployments.
For security-critical agents where an unreachable receiver should stop tool calls rather than allow them, enable fail-closed mode:
client = Client(
api_key="stra_...",
endpoint="http://localhost:4318",
fail_closed=True, # block when state can't be verified
fail_closed_max_staleness_sec=60, # how stale cached state may be first
)Choose deliberately: fail-open prioritizes uptime, fail-closed prioritizes containment. See Runtime Intervention for the full contract.
What's next
- Core Concepts — the mental model: spans, traces, policies, the actions, inline enforcement, the audit log.
- Runtime Intervention — every action, allow-list mode, time-based rules, policy versioning, halts, budgets, webhooks.
- CEL Reference — the policy language, with examples.
- Human Approval — pause high-risk calls for operator sign-off.
- Framework guides — setup for all 10 supported frameworks.
- Self-Hosting — production deployment, environment variables, HTTPS, scaling.