provenant-sdk (Python SDK)
First-party Python client for the Provenant control-plane API - the few lines an autonomous agent adds to become governable.
- Zero dependencies. Standard library only (
urllib,json,dataclasses,typing). Offline-friendly and trivial to vendor. - Mirrors the TypeScript SDK (
@identiqube/provenant-sdk) surface, paths, headers, and accepted status codes - using Pythonsnake_casemethod names.
Install
pip install provenant-sdk
Or vendor the provenant_sdk/ package directly - it has no third-party deps.
Quickstart - authorize → act → complete
import os
from provenant_sdk import ProvenantClient
provenant = ProvenantClient(
"https://provenant.identiqube.com",
api_key=os.environ["PROVENANT_KEY"],
)
decision = provenant.authorize({
"type": "payment.send",
"resource": "vendor:acme",
"valueCents": 25_00,
})
if decision["status"] == "authorized":
ref = pay_vendor(...) # your real-world side effect
provenant.complete(decision["id"], {
"success": True,
"externalRef": ref,
"warrant": decision["authorizationToken"], # proves possession
})
else:
# A `deny` decision is returned (not raised) - branch on it.
print("blocked:", decision["decision"]["reason"])
A deny decision is returned, not raised, so you can branch on
decision["status"]. Auth/validation failures raise ProvenantError.
valueCents is an integer in minor units (1/100) of the agent's mandate value unit - a
currency code or any label (USD, tokens); default USD. Pass currency to override per
action: an explicit unit that differs from the mandate's is held for human approval (values never
convert between units).
Binding enforcement - invoke
Act on a resource through Provenant. The control plane evaluates policy and only performs the downstream call (using the connector's server-held credential) when allowed - your agent never holds the credential and cannot bypass the decision.
res = provenant.invoke({
"type": "payment.send",
"resource": "vendor:acme",
"valueCents": 25_00,
"request": {
"method": "POST",
"path": "/v1/charges",
"body": '{"amount": 2500, "currency": "usd"}',
},
})
if res["status"] == "executed":
print(res["output"]) # { "status", "headers", "body" } from the connector
else:
print("blocked/held:", res["action"]["status"])
Convenience - guard
Authorize, run your work if allowed, then report completion automatically. If your
callback raises, the action is completed with success=False and the error re-raised.
def execute(decision):
ref = pay_vendor(...)
return {"result": ref, "externalRef": ref}
outcome = provenant.guard(
{"type": "payment.send", "resource": "vendor:acme", "valueCents": 25_00},
execute,
)
if outcome["authorized"]:
print("done:", outcome["result"])
else:
print("blocked:", outcome["decision"]["decision"]["reason"])
Governed tools (any framework)
govern_tool wraps a tool's function so every call is authorized, executed, and
completed through Provenant - with no framework dependency. Drop it into LangChain
(StructuredTool.from_function), CrewAI (@tool), a LangGraph node, or a plain callable.
from provenant_sdk import ProvenantClient, govern_tool
def pay_vendor(vendor: str, amount_cents: int) -> str:
...
governed_pay = govern_tool(
provenant,
pay_vendor,
type="payment.send",
resource=lambda a: f"vendor:{a['vendor']}",
value_cents=lambda a: a["amount_cents"],
)
# LangChain: from langchain_core.tools import StructuredTool
tool = StructuredTool.from_function(governed_pay, name="pay", description="Pay a vendor")
Mappers receive the tool's arguments - the kwargs dict for keyword tools (LangChain/CrewAI) or the single input object for a positional tool.
When policy allows, the tool runs and the outcome is reported automatically. When it
denies or holds for approval, the tool never runs and the call returns a
GovernBlocked dict the model reads as the tool result:
{"provenant": "blocked", "status": "denied", "reason": "over budget",
"approvalId": None, "actionId": "act_2"}
The agent then explains the refusal (or that it's awaiting a human) instead of acting.
Methods
| Method | HTTP |
|---|---|
authorize(input) |
POST /v1/actions/authorize (ok: 200, 202, 403) |
get_action(action_id) |
GET /v1/agent/actions/{id} |
simulate(input) |
POST /v1/actions/simulate (ok: 200) |
complete(action_id, result) |
POST /v1/actions/{id}/complete (ok: 200) |
invoke(input) |
POST /v1/gateway/invoke (ok: 200, 202, 403, 502) |
mint_credential(input) |
POST /v1/gateway/credential (ok: 200, 202, 403) |
connectors() |
GET /v1/connectors/available → connectors list |
spawn(input) |
POST /v1/agents/delegate (ok: 201) |
guard(input, execute) |
convenience: authorize → execute → complete |
Auth header: x-provenant-key: <api_key>. Request bodies are JSON
(content-type: application/json).
Errors
On a non-ok status, methods raise ProvenantError(code, message, status), parsed from
the JSON {"error": {"code", "message"}} envelope (falling back to request_failed /
HTTP {status}).
from provenant_sdk import ProvenantError
try:
provenant.authorize({"type": "payment.send", "resource": "vendor:acme"})
except ProvenantError as e:
print(e.code, e.status, e.message)
Testing
ProvenantClient accepts an injectable opener so you can test offline without a
network. See tests/test_client.py.
client = ProvenantClient("https://api.test", "key", opener=my_stub_opener)
License
Apache-2.0 (see the LICENSE file in this package). This SDK is open source; the Provenant server product it talks to is separately licensed (proprietary).
Metadata
Release files for provenant-sdk 0.12.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| provenant_sdk-0.12.0.tar.gz | 17.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| provenant_sdk-0.12.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 33.3 kB
Release files / provenant_sdk-0.12.0.tar.gz
| Download URL | provenant_sdk-0.12.0.tar.gz |
|---|---|
| Size | 17.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
54e5c936f029c0c6decc0f657d4b6ade824afccb438e38599628427214318f4a
|
|
BLAKE2b-256 checksum How to use checksums |
dc73294af4172245ae999d1a87f7155ae35b3834f8b9495fd781fdbe00b566b5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 11, 2026.
Transparency logRelease files / provenant_sdk-0.12.0-py3-none-any.whl
| Download URL | provenant_sdk-0.12.0-py3-none-any.whl |
|---|---|
| Size | 15.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
273a89ed1b05bb7722df9137fedf0758b1ba7fae23a1133ddaa9638265ba30f6
|
|
BLAKE2b-256 checksum How to use checksums |
6eb9acb101bf4c572fc6e771af100c3beebb24534b010092a3fee7c9740da9ee
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 11, 2026.
Transparency log