OpenTerms Python SDK — permission lookup and ORS v0.1 signed receipts for AI agents.
Project description
openterms-py
Python SDK for the OpenTerms Protocol.
Two halves of the same agent-governance story, in one library:
- Permissions — before an agent acts, query
openterms.jsonto see what the site owner permits. - Receipts — after an agent acts, sign and emit an ORS v0.1 receipt so the action is auditable and verifiable later.
pip install openterms-py
Runtime dependencies: cryptography>=42, requests>=2.28. Python >=3.10.
Quickstart
Before you act: check permissions
import openterms
result = openterms.check("example.com", "scrape_data")
if result:
print("allowed")
else:
print(f"blocked: {result.decision}")
After you act: emit a signed receipt
from openterms import IngestClient, generate_keypair
sk, pk = generate_keypair()
private_seed = sk.private_bytes_raw()
client = IngestClient(
base_url="http://localhost:3000",
workspace_id="00000000-0000-4000-8000-0000000000aa",
key_id="my-key",
private_key=private_seed,
agent_id="my-agent",
)
response = client.emit_receipt(
action_type="tool_call",
action_context={"tool_id": "web.fetch", "url": "https://example.com"},
)
print(response.receipt_id, response.canonical_hash)
End-to-end loop: check, act, sign
import openterms
from openterms import IngestClient
result = openterms.check("example.com", "scrape_data")
if not result:
raise SystemExit(f"blocked: {result.decision}")
# ... agent does the work ...
client = IngestClient(...)
client.emit_receipt(
action_type="scrape_data",
action_context={
"domain": "example.com",
"openterms_hash": result.raw_value and "...",
},
)
Permissions API
Top-level convenience functions:
| Function | Purpose |
|---|---|
openterms.fetch(domain) |
Fetch and parse the domain's openterms.json |
openterms.check(domain, action) |
Decide allow/deny/not_specified |
openterms.discover(domain) |
Read the discovery block (MCP servers, API specs) |
openterms.permission_receipt(domain, action, decision) |
Local audit artifact (unsigned) |
openterms.configure(...) |
Tune TTL, timeout, user agent, registry URL |
openterms.clear_cache(domain=None) |
Evict cached entries |
Lookup order: https://{domain}/.well-known/openterms.json, then
https://{domain}/openterms.json, then the configured registry URL.
Lower-level: openterms.OpenTermsClient, openterms.TermsCache,
openterms.CheckResult, openterms.DiscoveryResult, openterms.PermissionReceipt.
Receipts API (ORS v0.1)
Top-level:
| Symbol | Purpose |
|---|---|
sign_receipt(payload, private_key, key_id) |
Ed25519-sign a canonical ORS payload |
verify_receipt(receipt, jwks) |
Verify; returns a VerifyResult (no raise) |
canonicalize(payload) / canonical_hash(payload) |
RFC 8785-ish JSON canonicalization |
build_payload(receipt) |
Strip signature/key fields, return signable payload |
generate_keypair() |
Ed25519 keypair |
public_key_to_jwk(pk, kid) / build_jwks(keys) |
JWKS helpers |
IngestClient |
Build, sign, POST receipts to an ingest service |
Policy engine
from openterms import evaluate, Policy, Rule
policy = Policy(rules=[Rule(rule_id="r1", type="max_amount", params={"amount_cents": 5000})])
decision = evaluate(policy, receipt={...})
Framework adapters
| Package | Install |
|---|---|
| LangChain callback | pip install langchain-openterms |
| CrewAI tool wrapper | pip install crewai-openterms |
Both depend on openterms-py>=1.0.0 and surface the same IngestClient.
Migrating from 0.4.x
See CHANGELOG.md for the full migration table. The short version:
Receipt→PermissionReceiptopenterms.receipt(...)→openterms.permission_receipt(...)openterms.check(..., receipt=True)removed — useIngestClient.emit_receiptopenterms.receipts.sign_receipt/verify_receiptnow usecryptography(not PyNaCl) and have different signatures- License changed: MIT → Apache-2.0
License
Apache-2.0 — see LICENSE.
Project details
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 openterms_py-1.0.1.tar.gz.
File metadata
- Download URL: openterms_py-1.0.1.tar.gz
- Upload date:
- Size: 50.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
23366bf723b825bec2cac2cc873e5eb44a682e0bc0d87ecd7eff30a4ce8b9811
|
|
| MD5 |
8d2c264d487ada24a3ba1aec4ca4105e
|
|
| BLAKE2b-256 |
e93ca089c16292dd5747f6ca5f1cf24ee27d6f8af8cb5d8e13e21d010b9ba973
|
File details
Details for the file openterms_py-1.0.1-py3-none-any.whl.
File metadata
- Download URL: openterms_py-1.0.1-py3-none-any.whl
- Upload date:
- Size: 36.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cb82afb8a90cbdc8ceb330e030d0c54a3e144991caeb1cd95e66e53251572f0d
|
|
| MD5 |
028fc60cc10b7f785841654521fdc3e6
|
|
| BLAKE2b-256 |
940cf2527a60b1841cd57d74684f48be3821a4a4b602629f858a780ad28f09f6
|