Dome Platform Python SDK — AI agent governance
Project description
Dome Python SDK
The official Python SDK for the Dome Platform — AI agent governance with local Cedar evaluation.
Install
pip install dome
Quick Start
import dome
client = dome.DomeClient(dome.DomeConfig(
base_url="https://api.dome.example.com",
token="dome_at_...",
))
client.start()
client.check(
tool="database:query",
on_allow=lambda result: print(f"Allowed: {result.reason}"),
on_deny=lambda req, reason: print(f"Denied: {reason}"),
)
client.close()
How It Works
The SDK syncs Cedar rule bundles from the Dome Platform and evaluates authorization decisions locally using cedarpy. This means:
- Fast — no network round-trip per check, sub-millisecond evaluation
- Reliable — background sync keeps rules fresh
- Consistent — identical Cedar evaluation as the Go SDK
Framework Adapters
Framework adapters are separate packages that wrap the core SDK for specific AI frameworks:
| Package | Install | Framework |
|---|---|---|
dome-langchain |
pip install dome-langchain |
LangChain |
LangChain Example
import dome
from dome_langchain import govern_tools
client = dome.DomeClient(dome.DomeConfig(base_url="https://...", token="dome_at_..."))
client.start()
# Wrap all tools at once — authorization is automatic
governed = govern_tools(client, [search_tool, db_tool])
Configuration
All configuration is explicit — passed via DomeConfig.
| Argument | Required | Default | Description |
|---|---|---|---|
base_url |
yes | — | Dome API URL |
token |
yes | — | Agent token (dome_ key or base64 envelope) |
rule_sync_interval |
no | 30s | Seconds between rule bundle syncs |
audit_batch_size |
no | 100 | Max on-device decision events buffered before a flush |
audit_flush_interval |
no | 5s | Seconds between buffered-decision flushes |
logger |
no | None | Custom logger instance |
Audit
The SDK both writes and reads audit. On every check(), the SDK reports
the on-device policy decision to the control plane via the Audit IngestEvents
RPC (asynchronous, batched, drop-not-block — a failed audit flush never blocks
the request path). The agent supplies only the decision facts (action, tool,
result, reason, rule id, latency); the server derives scope, actor, producer
(dome-device), and identity from the authenticated caller — client-supplied
identity is never trusted, so an agent can only write audit within its own
workspace. These self-reported device.decision events are evidence of an
agent's own decisions; gateway/sidecar topologies remain the source of
independently-observed traffic.
Hosted Audit v1 also exposes read APIs for querying, fetching, and streaming the typed audit envelope.
from dome.audit import AuditPayloadFilter, AuditQuery
from dome.client import ControlPlaneClient
from dome.token import TokenManager
token_mgr = TokenManager("https://api.dome.example.com", "dome_at_...")
token_mgr.exchange()
control = ControlPlaneClient("https://api.dome.example.com", token_mgr)
page = control.query_audit_events(
AuditQuery(
event_types=("mcp.tool_call.completed",),
results=("EVENT_RESULT_SUCCEEDED",),
actor_kind="ACTOR_KIND_AGENT",
producer_service="gateway",
request_surface="INITIATOR_SURFACE_GATEWAY_MCP",
operation_id="018fc629-4a74-7cc0-b41c-869f7ef7f6c4",
start_time="2026-05-30T00:00:00Z",
end_time="2026-05-31T00:00:00Z",
payload_filters=(
AuditPayloadFilter(
event_type="mcp.tool_call.completed",
field="toolName",
values=("read_file",),
),
AuditPayloadFilter(
event_type="mcp.tool_call.completed",
field="statusCode",
operator="exists",
),
),
page_size=50,
)
)
for event in page.events:
print(event.accepted_at, event.type, event.result, event.operation_id)
print(event.scope.workspace_id, event.actor.kind, event.payload)
event = control.get_audit_event(page.events[0].id)
for event in control.stream_audit_events(
AuditQuery(
event_types=("access.denied",),
page_token=page.next_page_token,
payload_filters=(
AuditPayloadFilter(field="requiredPermission", operator="exists"),
),
)
):
print(event.id)
AuditQuery uses the protobuf JSON enum names for enum filters. QueryEvents
supports cursor pagination (page_token / next_page_token), time ranges,
actor filters, producer/surface filters, operation linkage filters, resource
filters, and registry-declared payload equality/exists filters. StreamEvents
uses the same event/actor/producer/surface/operation/payload/cursor filters as
the v1 stream RPC; query-only filters such as time ranges and primary-resource
filters raise locally instead of being silently dropped.
Activity Correlation (Sessions)
Audit events normally chain only within one request (by trace_id). To chain
the events from many Dome calls into one activity chain — a session, an
LLM turn, a run — open a Session. Every Dome control-plane RPC issued while
the session is active carries a stable X-Dome-Activity-Id header, and the
resulting Dome audit events share that activity_id.
with client.session() as s:
print("activity_id:", s.activity_id) # a fresh, high-entropy UUID
# Every Dome RPC in this block carries X-Dome-Activity-Id: <s.activity_id>.
page = s.query_audit_events(event_types=("access.denied",))
# Outside the session, calls carry no activity_id — the SDK never mints one
# implicitly. To supply your own correlation id, pass it explicitly:
with client.session(activity_id="nightly-batch-2026-06-03") as s:
...
The id is minted as a UUIDv4 — a random, opaque token with no PII. (Dome
mints it because a Dome-minted id is the only kind we can assert is PII-free.)
Without a with block, use client.start_session() and call session.end()
yourself, ideally in a finally. Sessions nest; exiting an inner session
restores the outer one's id.
The header is first-party only — it rides on the SDK's calls to the Dome
control plane and is never attached to third-party requests (e.g. OIDC/JWKS
discovery). Server-side, a caller-supplied id is recorded as CALLER_ASSERTED.
Note that streaming results are lazy: iterate s.stream_audit_events(...)
inside the with block so the request fires while the session is still active.
Authorization Checks
check() requires on_allow and on_deny callbacks — both outcomes must be handled:
client.check(
tool="db:query",
on_allow=lambda result: execute_query(),
on_deny=lambda req, reason: log_denial(reason),
)
Act-As (End-User Delegation)
Pass the end-user identity to enable user-aware authorization rules:
# Plain mode (development / trusted environments)
client.check(
tool="db:query",
act_as=dome.ActAs(sub="user-123", email="alice@corp.com"),
on_allow=..., on_deny=...,
)
# OIDC mode (verified — pass the user's real token)
client.check(
tool="db:query",
act_as=user_oidc_token, # raw JWT string from the IdP
on_allow=..., on_deny=...,
)
SDK errors (not policy denials) still raise exceptions:
try:
client.check(tool="db:query", on_allow=..., on_deny=...)
except dome.NoBundleLoadedError:
# No rule bundle available (fail-closed)
pass
except dome.NotInitializedError:
# SDK not started yet
pass
except dome.ShutdownError:
# SDK already closed
pass
Fail-Closed
The SDK denies all requests by default when:
- No rule bundle has been loaded →
NoBundleLoadedError - No rules match the request → calls
on_deny - The SDK has not been started →
NotInitializedError
Documentation
License
Proprietary. See LICENSE for details.
Project details
Release history Release notifications | RSS feed
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 dome_sdk-0.1.0.tar.gz.
File metadata
- Download URL: dome_sdk-0.1.0.tar.gz
- Upload date:
- Size: 117.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
816b6c533d90d6acbd6148aca45baaed6a1381e0b1a77dcfc54b5e3923f20adb
|
|
| MD5 |
60a9377901ae1f6e9201bd4533f569b0
|
|
| BLAKE2b-256 |
a24e7426531a1f5333944e83f75b9a8b2aee34a72dcac0d968365ed45464d42a
|
Provenance
The following attestation bundles were made for dome_sdk-0.1.0.tar.gz:
Publisher:
release.yml on dome-systems/sdk-dome-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dome_sdk-0.1.0.tar.gz -
Subject digest:
816b6c533d90d6acbd6148aca45baaed6a1381e0b1a77dcfc54b5e3923f20adb - Sigstore transparency entry: 1789110222
- Sigstore integration time:
-
Permalink:
dome-systems/sdk-dome-python@cf4367216fa0c3f414855f68a6b9d7e3608e6e50 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/dome-systems
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@cf4367216fa0c3f414855f68a6b9d7e3608e6e50 -
Trigger Event:
release
-
Statement type:
File details
Details for the file dome_sdk-0.1.0-py3-none-any.whl.
File metadata
- Download URL: dome_sdk-0.1.0-py3-none-any.whl
- Upload date:
- Size: 40.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0e5adf449fa3612135a0a8376f85964392a81ae59c745c04a0ec650b15e93231
|
|
| MD5 |
7c8884c81c5fe04964990c44c676ecd7
|
|
| BLAKE2b-256 |
2e11de53c1f0cc278fd808d1a64a867c5f74dde45bdce05d1b4917efafa197ac
|
Provenance
The following attestation bundles were made for dome_sdk-0.1.0-py3-none-any.whl:
Publisher:
release.yml on dome-systems/sdk-dome-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dome_sdk-0.1.0-py3-none-any.whl -
Subject digest:
0e5adf449fa3612135a0a8376f85964392a81ae59c745c04a0ec650b15e93231 - Sigstore transparency entry: 1789110245
- Sigstore integration time:
-
Permalink:
dome-systems/sdk-dome-python@cf4367216fa0c3f414855f68a6b9d7e3608e6e50 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/dome-systems
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@cf4367216fa0c3f414855f68a6b9d7e3608e6e50 -
Trigger Event:
release
-
Statement type: