Sentinel SDK for Python — the independent action-gate client for AI agents. Stdlib only, fails closed.
Project description
Sentinel SDK — Python
The stdlib-only Python client for the Sentinel action-gate.
Drop it at your agent's action boundary — fail-closed by default.
montanalabs-sentinel is a thin, dependency-free (stdlib-only) client placed at the action boundary inside your Python agent. It submits a proposed action to the Sentinel sidecar and returns the verdict. The sidecar — not the client — renders and signs the decision; if the sidecar is unreachable the client fails closed by default (it never silently lets an action through).
Install
pip install montanalabs-sentinel # once published
# or from source:
pip install ./sentinel-sdks/python
Requires Python ≥ 3.9. No third-party dependencies.
Quick start
from montanalabs_sentinel import SentinelClient, Action
sentinel = SentinelClient("http://localhost:4000")
action = Action.payment({"amount": 42000, "from": "acct_ops", "to": "vendor_42"})
context = {"runId": run_id, "provider": "anthropic", "model": "claude-sonnet-4-6",
"actor": {"id": "agent-007", "roles": ["ops"]}}
decision = sentinel.guard(action, context, "fintech.payments")
if decision.allowed:
execute_payment(action) # only runs on ALLOW
elif decision.verdict == "ESCALATE":
queue_for_review(decision.escalation_id)
else:
log.warning("blocked: %s", decision.reason) # BLOCK
API
SentinelClient(endpoint, fail_mode="closed", timeout=5.0, headers=None, transport=None)
| Arg | Type | Default | Notes |
|---|---|---|---|
endpoint |
str |
— | Sidecar base URL, e.g. http://localhost:4000 |
fail_mode |
"closed" | "open" |
"closed" |
Transport failure → closed=BLOCK, open=ALLOW |
timeout |
float (seconds) |
5.0 |
Request timeout (treated as a transport failure) |
headers |
dict[str,str] |
None |
Extra headers (e.g. auth to the sidecar) |
transport |
callable | urllib | Inject for tests: (url, body, headers, timeout) -> (status, bytes) |
guard(action, context, policy) -> GuardDecision
@dataclass
class GuardDecision:
verdict: str # "ALLOW" | "BLOCK" | "ESCALATE"
record_id: str # id of the signed provenance record ("" on transport fallback)
checks: list[dict] # per-check results
reason: str | None
escalation_id: str | None # present when verdict == "ESCALATE"
@property
def allowed(self) -> bool: # True only for ALLOW
SentinelClient.allowed(decision) is also available as a static method.
Building actions & context
Action.payment({"amount": 100, "from": "a", "to": "b"}) # typed helper
Action.of("record_update", {"patientId": "p1", "field": "note", "value": "…"}, id=None, meta=None)
# context (a plain dict) — the model trace behind the action
{"runId": "...", "provider": "...", "model": "...", "actor": {"id": "...", "roles": ["..."]}, "tenant": "..."}
Fail modes
closed(default): sidecar unreachable/erroring →guardreturns a synthetic BLOCK with asentinel.transportcheck, so yourif decision.allowed:naturally prevents the action.open: returns a synthetic ALLOW with a transport warning — only where availability outranks control.
guard never raises on transport problems; it always returns a GuardDecision.
Testing
Inject transport to test without a network:
def fake(url, body, headers, timeout):
return 200, b'{"verdict":"ALLOW","recordId":"r","checks":[]}'
client = SentinelClient("http://x", transport=fake)
assert client.guard(Action.payment({}), {"runId": "r"}, "p").allowed
Run the tests
cd sentinel-sdks/python
PYTHONPATH=. python3 -m unittest discover -s tests -v
See also
- Self-hosting the sidecar → sentinel/docs/self-hosting.md
- TypeScript SDK →
@montanalabs/sentinelon npm
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 montanalabs_sentinel-1.0.0.tar.gz.
File metadata
- Download URL: montanalabs_sentinel-1.0.0.tar.gz
- Upload date:
- Size: 11.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0c9009d4dfd5bf6a7b4c1e971c0a725fa900951ce6b55966c675c0b6ec4828f2
|
|
| MD5 |
d1ec452fd57185c1767f865cc4648df8
|
|
| BLAKE2b-256 |
119859fb4e3001cead9cb2aea9f26530008897f6e15d808ea288133200bd2c89
|
Provenance
The following attestation bundles were made for montanalabs_sentinel-1.0.0.tar.gz:
Publisher:
publish-pypi.yml on Montanalabs/sentinel-sdks
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
montanalabs_sentinel-1.0.0.tar.gz -
Subject digest:
0c9009d4dfd5bf6a7b4c1e971c0a725fa900951ce6b55966c675c0b6ec4828f2 - Sigstore transparency entry: 1912394673
- Sigstore integration time:
-
Permalink:
Montanalabs/sentinel-sdks@0edd70490b33c687dc03639d596a7908d754db89 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/Montanalabs
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@0edd70490b33c687dc03639d596a7908d754db89 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file montanalabs_sentinel-1.0.0-py3-none-any.whl.
File metadata
- Download URL: montanalabs_sentinel-1.0.0-py3-none-any.whl
- Upload date:
- Size: 11.2 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 |
bfc46a9b56b90244ac5c8798ef406c866e02f8b967f778efb7f50a94937dd807
|
|
| MD5 |
42aef85968e33808703c6cdf3af18b8e
|
|
| BLAKE2b-256 |
3a5dc77c7d46144d6ed578f61c519253ee2e84bc74e221448b0c62b13a8745c2
|
Provenance
The following attestation bundles were made for montanalabs_sentinel-1.0.0-py3-none-any.whl:
Publisher:
publish-pypi.yml on Montanalabs/sentinel-sdks
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
montanalabs_sentinel-1.0.0-py3-none-any.whl -
Subject digest:
bfc46a9b56b90244ac5c8798ef406c866e02f8b967f778efb7f50a94937dd807 - Sigstore transparency entry: 1912394806
- Sigstore integration time:
-
Permalink:
Montanalabs/sentinel-sdks@0edd70490b33c687dc03639d596a7908d754db89 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/Montanalabs
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@0edd70490b33c687dc03639d596a7908d754db89 -
Trigger Event:
workflow_dispatch
-
Statement type: