Boundwr Documentation
Everything you need to add governance, policy enforcement, and audit trails to your AI agents. Get compliant in minutes, not months.
#What is Boundwr?
Boundwr is a lightweight governance SDK for AI agents. It gives every agent in your fleet a verifiable identity, enforces policies as code before actions are taken, and creates an immutable audit trail — so your team can ship fast and stay compliant.
The SDK is local-first with zero external dependencies. Store governance data as JSON files during development, or connect to the Boundwr cloud platform for production dashboards, team access, and auditor-ready exports.
#Installation
Install the Boundwr Python SDK with pip:
pip install boundwrRequirements: Python 3.9+. No external dependencies — the SDK uses only the Python standard library.
Or download the archive directly from the SDK page.
#Quick Start
Register an agent, log an action, check a policy, and export a compliance report — all in under 20 lines:
from boundwr import Boundwr
# 1. Initialize the client
client = Boundwr(project="my-app", api_key="bwr_your_key_here")
# 2. Register an agent
agent = client.register_agent(
name="support-bot",
description="Handles tier-1 customer inquiries",
permissions=["read_kb", "send_message"],
owner="alice@company.com"
)
# 3. Log an action
client.log_action(
agent_id=agent["id"],
action="send_message",
details={"recipient": "user@example.com", "channel": "chat"},
status="success"
)
# 4. Define and check a policy
client.define_policy(
name="No External Email",
rules=[{"action": "send_email", "deny": True, "message": "Email not allowed"}]
)
result = client.check_policy(agent_id=agent["id"], action="send_email")
print(result)
# {"allowed": False, "violations": [{"policy": "No External Email", ...}]}
# 5. Export a compliance report
report = client.export_compliance_report(format="json")
print(f"Agents: {report['summary']['total_agents']}")
print(f"Audit entries: {report['summary']['total_audit_entries']}")#Boundwr()
Initialize the Boundwr client. This is the entry point for all SDK operations.
| Parameter | Type | Description |
|---|---|---|
| project* | str | Project name used to label reports and entries. |
| api_key | str | None | Optional API key for cloud connectivity. Must start with "bwr_". |
| storage_dir | str | Directory for local JSON storage. Defaults to ".boundwr". |
Returns: A Boundwr client instance.
from boundwr import Boundwr
# Minimal — local storage only
client = Boundwr(project="my-app")
# With API key for cloud sync
client = Boundwr(project="my-app", api_key="bwr_your_key_here")
# Custom storage directory
client = Boundwr(project="my-app", storage_dir="/tmp/boundwr-data")Keep your API key secret
Never commit API keys to version control. Use environment variables or a secrets manager.
#register_agent()
Register a new AI agent with a verifiable identity. Creates a persistent record in the agent registry.
| Parameter | Type | Description |
|---|---|---|
| name* | str | Unique name for the agent. |
| description* | str | Human-readable description of what the agent does. |
| permissions* | list[str] | List of permissions granted to this agent (e.g. ["read_kb", "send_message"]). |
| owner* | str | Email or identifier of the person responsible for the agent. |
Returns: dict — the created Agent record with auto-generated id, project, created_at, and updated_at fields.
agent = client.register_agent(
name="doc-summarizer",
description="Summarizes legal documents for review",
permissions=["read_documents", "write_summaries"],
owner="legal-team@company.com"
)
print(agent["id"]) # "a1b2c3d4-..."
print(agent["created_at"]) # "2026-03-23T10:30:00Z"#log_action()
Log a single agent action. All entries are append-only and immutable — creating a tamper-evident audit trail.
| Parameter | Type | Description |
|---|---|---|
| agent_id* | str | ID of the agent performing the action. |
| action* | str | The action being performed (e.g. "send_message", "query_db"). |
| details | dict | None | Optional dictionary of action metadata and context. |
| status | str | Outcome of the action. Defaults to "success". |
Returns: dict — the AuditEntry with id and timestamp.
entry = client.log_action(
agent_id="a1b2c3d4-...",
action="query_database",
details={"table": "customers", "query": "SELECT count(*) ..."},
status="success"
)
# Log a failed action
client.log_action(
agent_id="a1b2c3d4-...",
action="send_email",
details={"error": "Policy violation"},
status="blocked"
)#log_delegation()
Record when one agent delegates work to another. Tracks the chain of responsibility across your agent fleet.
| Parameter | Type | Description |
|---|---|---|
| from_agent* | str | ID of the agent delegating the task. |
| to_agent* | str | ID of the agent receiving the task. |
| reason* | str | Why the delegation is happening. |
| permissions_granted* | list[str] | Permissions the receiving agent is granted for this delegation. |
Returns: dict — the Delegation record with id and timestamp.
delegation = client.log_delegation(
from_agent="orchestrator-agent",
to_agent="research-agent",
reason="User requested deep research on topic",
permissions_granted=["read_web", "write_notes"]
)
print(delegation["id"]) # "d5e6f7g8-..."
print(delegation["timestamp"]) # "2026-03-23T10:31:00Z"#check_policy()
Check whether an action is allowed under the current policy set. Call this before an agent acts to enforce governance in real time.
| Parameter | Type | Description |
|---|---|---|
| agent_id* | str | ID of the agent attempting the action. |
| action* | str | The action to check against all defined policies. |
Returns: dict with allowed (bool) and violations (list of policy violations).
result = client.check_policy(
agent_id="support-bot",
action="send_email"
)
if not result["allowed"]:
for v in result["violations"]:
print(f"Blocked by: {v['policy']} — {v['message']}")
else:
print("Action permitted — proceed")#define_policy()
Define a governance policy with one or more rules. Policies are evaluated by check_policy() before agents act.
| Parameter | Type | Description |
|---|---|---|
| name* | str | Human-readable name for the policy. |
| rules* | list[dict] | List of rule objects. Each must have "action" (str) and "deny" (bool). Optional "message" for violation text. |
Returns: dict — the Policy record with id and created_at.
# Single rule policy
client.define_policy(
name="No PII Access",
rules=[{
"action": "access_pii",
"deny": True,
"message": "PII access requires human approval"
}]
)
# Multi-rule policy
client.define_policy(
name="Production Safety",
rules=[
{"action": "delete_data", "deny": True, "message": "Deletion not allowed"},
{"action": "modify_schema", "deny": True, "message": "Schema changes blocked"},
{"action": "read_data", "deny": False}
]
)#get_audit_trail()
Retrieve the audit trail with optional filters. Returns all logged actions in chronological order.
| Parameter | Type | Description |
|---|---|---|
| agent_id | str | None | Filter entries by a specific agent. |
| since | str | None | ISO 8601 timestamp — only return entries after this time. |
Returns: list[dict] — list of AuditEntry records.
# All entries
trail = client.get_audit_trail()
# Entries for a specific agent
trail = client.get_audit_trail(agent_id="support-bot")
# Entries since a specific time
trail = client.get_audit_trail(since="2026-03-01T00:00:00Z")
# Combined filters
trail = client.get_audit_trail(
agent_id="support-bot",
since="2026-03-01T00:00:00Z"
)
print(f"{len(trail)} entries found")#export_compliance_report()
Generate a full compliance report covering agents, audit logs, policies, and delegations. Designed for auditors and compliance teams.
| Parameter | Type | Description |
|---|---|---|
| format | str | "json" or "csv". Defaults to "json". |
Returns: dict — report data including summary statistics and full data export.
# JSON report (default)
report = client.export_compliance_report()
print(report["summary"])
# {
# "project": "my-app",
# "total_agents": 5,
# "total_audit_entries": 1842,
# "total_policies": 3,
# "total_delegations": 12,
# "status_breakdown": {"success": 1790, "blocked": 52}
# }
# CSV report for spreadsheet tools
csv_report = client.export_compliance_report(format="csv")
print(csv_report["csv_data"]) # CSV string ready to saveReport contents
- Project name and generation timestamp
- Complete agent inventory with registration dates
- All audit log entries with timestamps and statuses
- Policy definitions and rule sets
- Delegation records between agents
- Summary statistics and status breakdown
#list_agents()
Return all registered agents in the current project. No parameters required.
Returns: list[dict] — list of Agent records.
agents = client.list_agents()
for agent in agents:
print(f"{agent['name']} — {agent['description']}")
print(f" Owner: {agent['owner']}")
print(f" Permissions: {', '.join(agent['permissions'])}")
print()#Secure Your First AI Agent in 5 Minutes
This tutorial walks you through installing Boundwr, registering an AI agent, logging an action, and exporting a basic compliance report. By the end, you'll have a fully auditable agent in under 5 minutes.
Install the SDK
pip install boundwrSuccessfully installed boundwr-0.3.1Initialize the client
from boundwr import Boundwr
client = Boundwr(api_key="your_key_here")Replace your_key_here with the API key from your dashboard.
Register an agent
agent = client.register_agent(
name="support-bot",
description="Handles tier-1 customer support inquiries",
permissions=["read_kb", "send_message", "read_user_profile"],
owner="alice@company.com"
)
print(agent){
"id": "agt_8xKp2mVbQ3",
"name": "support-bot",
"description": "Handles tier-1 customer support inquiries",
"permissions": ["read_kb", "send_message", "read_user_profile"],
"owner": "alice@company.com",
"created_at": "2026-03-24T10:15:00Z",
"status": "active"
}Log an action
entry = client.log_action(
agent_id=agent["id"],
action="send_message",
details={
"recipient": "user@example.com",
"channel": "chat",
"message_preview": "Your refund has been processed."
},
status="success"
)
print(entry){
"id": "log_Qm9nRtW1xZ",
"agent_id": "agt_8xKp2mVbQ3",
"action": "send_message",
"status": "success",
"timestamp": "2026-03-24T10:15:05Z",
"details": {
"recipient": "user@example.com",
"channel": "chat",
"message_preview": "Your refund has been processed."
}
}Export a compliance report
report = client.export_compliance_report(format="json")
print(f"Agents: {report['summary']['total_agents']}")
print(f"Actions logged: {report['summary']['total_audit_entries']}")
print(f"Policy violations: {report['summary']['total_violations']}")Agents: 1
Actions logged: 1
Policy violations: 0Add error handling
In production, wrap calls to handle network or auth errors:
from boundwr import Boundwr, BoundwrError
client = Boundwr(api_key="your_key_here")
try:
agent = client.register_agent(
name="support-bot",
description="Handles tier-1 customer support inquiries",
permissions=["read_kb", "send_message"],
owner="alice@company.com"
)
print(f"Agent registered: {agent['id']}")
except BoundwrError as e:
print(f"Boundwr error: {e.message} (code: {e.code})")
except Exception as e:
print(f"Unexpected error: {e}")#Add Policy Rules to Control Agent Behavior
Policies let you define what agents can and cannot do — and enforce those rules before actions happen. This tutorial shows you how to create a policy, check actions against it, and view violations in the audit log.
Initialize and register an agent
from boundwr import Boundwr
client = Boundwr(api_key="your_key_here")
agent = client.register_agent(
name="data-pipeline-bot",
description="ETL agent for analytics warehouse",
permissions=["read_db", "write_db", "run_query"],
owner="bob@company.com"
)
print(f"Agent ready: {agent['id']}")Agent ready: agt_Lw3pNx7TmRCreate a policy rule
Block the agent from accessing the production database. Only staging and analytics databases are allowed.
policy = client.define_policy(
name="No Production DB Access",
rules=[
{
"action": "write_db",
"resource": "production",
"deny": True,
"message": "Agents cannot write to the production database"
},
{
"action": "read_db",
"resource": "production",
"deny": True,
"message": "Agents cannot read from the production database"
}
]
)
print(policy){
"id": "pol_Vk8mDxR2nQ",
"name": "No Production DB Access",
"rules": [
{
"action": "write_db",
"resource": "production",
"deny": true,
"message": "Agents cannot write to the production database"
},
{
"action": "read_db",
"resource": "production",
"deny": true,
"message": "Agents cannot read from the production database"
}
],
"created_at": "2026-03-24T10:20:00Z",
"status": "active"
}Check an allowed action
Reading from the staging database is not blocked by the policy, so it passes:
allowed = client.check_policy(
agent_id=agent["id"],
action="read_db",
resource="staging"
)
print(allowed){
"allowed": true,
"violations": [],
"checked_policies": ["No Production DB Access"]
}Check a denied action
Attempting to write to production triggers the policy violation:
denied = client.check_policy(
agent_id=agent["id"],
action="write_db",
resource="production"
)
print(denied){
"allowed": false,
"violations": [
{
"policy": "No Production DB Access",
"rule": "write_db on production",
"message": "Agents cannot write to the production database"
}
],
"checked_policies": ["No Production DB Access"]
}Enforce before acting
Use the policy check in your agent logic to block actions before they happen:
def execute_agent_action(agent_id, action, resource, details):
"""Run a policy check before executing any agent action."""
check = client.check_policy(
agent_id=agent_id,
action=action,
resource=resource
)
if not check["allowed"]:
for v in check["violations"]:
print(f"BLOCKED: {v['message']}")
return None
# Action is allowed — execute and log it
result = client.log_action(
agent_id=agent_id,
action=action,
details={"resource": resource, **details},
status="success"
)
return result
# This succeeds
execute_agent_action(
agent["id"], "read_db", "staging",
{"query": "SELECT count(*) FROM events"}
)
# This is blocked
execute_agent_action(
agent["id"], "write_db", "production",
{"query": "DROP TABLE users"}
)BLOCKED: Agents cannot write to the production databaseView violations in the audit trail
trail = client.get_audit_trail(agent_id=agent["id"])
for entry in trail["entries"]:
status = "VIOLATION" if entry.get("violation") else entry["status"]
print(f"[{entry['timestamp']}] {entry['action']} -> {status}")[2026-03-24T10:20:10Z] read_db -> success
[2026-03-24T10:20:11Z] write_db -> VIOLATION#Generate Your First Compliance Report
This tutorial shows you how to set up multiple agents, log activity, define policies, and generate an auditor-ready compliance report — all in one script.
Set up the client and register agents
from boundwr import Boundwr
client = Boundwr(api_key="your_key_here")
# Register three agents with different roles
support_bot = client.register_agent(
name="support-bot",
description="Handles customer support inquiries",
permissions=["read_kb", "send_message"],
owner="alice@company.com"
)
data_bot = client.register_agent(
name="data-pipeline-bot",
description="Runs scheduled ETL jobs on analytics warehouse",
permissions=["read_db", "write_db", "run_query"],
owner="bob@company.com"
)
deploy_bot = client.register_agent(
name="deploy-bot",
description="Manages CI/CD deployments to staging",
permissions=["deploy_staging", "read_config"],
owner="carol@company.com"
)
print(f"Registered: {support_bot['name']}, {data_bot['name']}, {deploy_bot['name']}")Registered: support-bot, data-pipeline-bot, deploy-botLog actions across all agents
# Support bot handles a ticket
client.log_action(
agent_id=support_bot["id"],
action="send_message",
details={"channel": "chat", "recipient": "user@example.com"},
status="success"
)
client.log_action(
agent_id=support_bot["id"],
action="read_kb",
details={"article": "refund-policy-v2"},
status="success"
)
# Data bot runs a query
client.log_action(
agent_id=data_bot["id"],
action="run_query",
details={"db": "analytics", "query": "SELECT count(*) FROM events"},
status="success"
)
# Deploy bot ships to staging
client.log_action(
agent_id=deploy_bot["id"],
action="deploy_staging",
details={"version": "v2.4.1", "commit": "a1b2c3d"},
status="success"
)
# Data bot tries to access production (will be a violation later)
client.log_action(
agent_id=data_bot["id"],
action="write_db",
details={"db": "production", "query": "INSERT INTO metrics ..."},
status="success"
)
print("5 actions logged across 3 agents")5 actions logged across 3 agentsDefine policy rules
# Block production database access
client.define_policy(
name="No Production DB Access",
rules=[{
"action": "write_db",
"resource": "production",
"deny": True,
"message": "Agents cannot write to the production database"
}]
)
# Block deploying to production (only staging allowed)
client.define_policy(
name="Staging Only Deployments",
rules=[{
"action": "deploy_production",
"deny": True,
"message": "Agents can only deploy to staging"
}]
)
print("2 policies created")2 policies createdGenerate the compliance report
import json
report = client.export_compliance_report(format="json")
# Pretty-print the full report
print(json.dumps(report, indent=2)){
"report_id": "rpt_Nm4xTk9WpL",
"generated_at": "2026-03-24T10:30:00Z",
"format": "json",
"summary": {
"total_agents": 3,
"active_agents": 3,
"total_audit_entries": 5,
"total_policies": 2,
"total_violations": 0,
"reporting_period": {
"start": "2026-03-01T00:00:00Z",
"end": "2026-03-24T10:30:00Z"
}
},
"agents": [
{
"id": "agt_8xKp2mVbQ3",
"name": "support-bot",
"owner": "alice@company.com",
"permissions": ["read_kb", "send_message"],
"actions_logged": 2,
"violations": 0
},
{
"id": "agt_Lw3pNx7TmR",
"name": "data-pipeline-bot",
"owner": "bob@company.com",
"permissions": ["read_db", "write_db", "run_query"],
"actions_logged": 2,
"violations": 0
},
{
"id": "agt_Rz1kYn5QvX",
"name": "deploy-bot",
"owner": "carol@company.com",
"permissions": ["deploy_staging", "read_config"],
"actions_logged": 1,
"violations": 0
}
],
"policies": [
{
"id": "pol_Vk8mDxR2nQ",
"name": "No Production DB Access",
"rules_count": 1,
"violations_triggered": 0
},
{
"id": "pol_Bm3xTw8RpN",
"name": "Staging Only Deployments",
"rules_count": 1,
"violations_triggered": 0
}
],
"audit_trail": [
{
"id": "log_Qm9nRtW1xZ",
"agent": "support-bot",
"action": "send_message",
"status": "success",
"timestamp": "2026-03-24T10:25:01Z"
},
{
"id": "log_Xk7mPw2TnR",
"agent": "support-bot",
"action": "read_kb",
"status": "success",
"timestamp": "2026-03-24T10:25:02Z"
},
{
"id": "log_Vm4nRx9WqL",
"agent": "data-pipeline-bot",
"action": "run_query",
"status": "success",
"timestamp": "2026-03-24T10:25:03Z"
},
{
"id": "log_Nm8xTk3WpZ",
"agent": "deploy-bot",
"action": "deploy_staging",
"status": "success",
"timestamp": "2026-03-24T10:25:04Z"
},
{
"id": "log_Qw5nRtX1mK",
"agent": "data-pipeline-bot",
"action": "write_db",
"status": "success",
"timestamp": "2026-03-24T10:25:05Z"
}
]
}Understand the report structure
The compliance report has four key sections:
summaryHigh-level counts — total agents, log entries, policies, and violations for the period.agentsInventory of every registered agent, their permissions, activity count, and violation count.policiesAll active policies, rule counts, and how many violations each has triggered.audit_trailChronological log of every action taken by every agent, with status and timestamps.
Share with your auditor
How you share depends on your plan:
# ---------- Starter plan: save JSON to file ----------
import json
report = client.export_compliance_report(format="json")
with open("compliance-report.json", "w") as f:
json.dump(report, f, indent=2)
print("Saved to compliance-report.json — send to your auditor")
# ---------- Pro plan: export as PDF ----------
pdf_bytes = client.export_compliance_report(format="pdf")
with open("compliance-report.pdf", "wb") as f:
f.write(pdf_bytes)
print("Saved to compliance-report.pdf")
# ---------- Enterprise plan: generate a share link ----------
link = client.export_compliance_report(format="link")
print(f"Share this link with your auditor: {link['url']}")
# https://app.boundwr.com/reports/rpt_Nm4xTk9WpL?token=eyJ...# Starter
Saved to compliance-report.json — send to your auditor
# Pro
Saved to compliance-report.pdf
# Enterprise
Share this link with your auditor: https://app.boundwr.com/reports/rpt_Nm4xTk9WpL?token=eyJ...Full script
Here is the complete script you can copy and run end-to-end:
from boundwr import Boundwr
import json
client = Boundwr(api_key="your_key_here")
# Register agents
support_bot = client.register_agent(
name="support-bot",
description="Handles customer support inquiries",
permissions=["read_kb", "send_message"],
owner="alice@company.com"
)
data_bot = client.register_agent(
name="data-pipeline-bot",
description="Runs scheduled ETL jobs",
permissions=["read_db", "write_db", "run_query"],
owner="bob@company.com"
)
deploy_bot = client.register_agent(
name="deploy-bot",
description="Manages CI/CD deployments",
permissions=["deploy_staging", "read_config"],
owner="carol@company.com"
)
# Log actions
client.log_action(agent_id=support_bot["id"], action="send_message",
details={"channel": "chat"}, status="success")
client.log_action(agent_id=support_bot["id"], action="read_kb",
details={"article": "refund-policy-v2"}, status="success")
client.log_action(agent_id=data_bot["id"], action="run_query",
details={"db": "analytics"}, status="success")
client.log_action(agent_id=deploy_bot["id"], action="deploy_staging",
details={"version": "v2.4.1"}, status="success")
# Define policies
client.define_policy(name="No Production DB Access", rules=[
{"action": "write_db", "resource": "production",
"deny": True, "message": "No production writes"}
])
client.define_policy(name="Staging Only Deployments", rules=[
{"action": "deploy_production", "deny": True,
"message": "Only staging deployments allowed"}
])
# Generate report
report = client.export_compliance_report(format="json")
print(json.dumps(report, indent=2))
print(f"\nTotal agents: {report['summary']['total_agents']}")
print(f"Total actions: {report['summary']['total_audit_entries']}")
print(f"Violations: {report['summary']['total_violations']}")#Plans
Starter
$29/mo
- ✓ 10 agents
- ✓ 10k audit logs/mo
- ✓ 5 policies
- ✓ Compliance export
Pro
$99/mo
- ✓ 50 agents
- ✓ 100k audit logs/mo
- ✓ 25 policies
- ✓ Compliance export
Enterprise
$299/mo
- ✓ Unlimited agents
- ✓ Unlimited audit logs
- ✓ Unlimited policies
- ✓ Compliance export
All plans include the local-first SDK at no cost. View full plan comparison
Ready to get started?
Create a free account and register your first agent in minutes.