Skip to main content

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.json to 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 → PermissionReceipt
  • openterms.receipt(...) → openterms.permission_receipt(...)
  • openterms.check(..., receipt=True) removed — use IngestClient.emit_receipt
  • openterms.receipts.sign_receipt / verify_receipt now use cryptography (not PyNaCl) and have different signatures
  • License changed: MIT → Apache-2.0

License

Apache-2.0 — see LICENSE.

Release files for openterms-py 1.0.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for openterms-py 1.0.1
File Size Uploaded
openterms_py-1.0.1.tar.gz 50.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for openterms-py 1.0.1
File Interpreter ABI Platform
openterms_py-1.0.1-py3-none-any.whl Python 3 none any Details

Total release size: 85.9 kB

Release files / openterms_py-1.0.1.tar.gz

Download URL openterms_py-1.0.1.tar.gz
Size 50.0 kB
Tags Source
SHA-256 checksum
How to use checksums
23366bf723b825bec2cac2cc873e5eb44a682e0bc0d87ecd7eff30a4ce8b9811
BLAKE2b-256 checksum
How to use checksums
e93ca089c16292dd5747f6ca5f1cf24ee27d6f8af8cb5d8e13e21d010b9ba973
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.3

Release files / openterms_py-1.0.1-py3-none-any.whl

Download URL openterms_py-1.0.1-py3-none-any.whl
Size 36.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
cb82afb8a90cbdc8ceb330e030d0c54a3e144991caeb1cd95e66e53251572f0d
BLAKE2b-256 checksum
How to use checksums
940cf2527a60b1841cd57d74684f48be3821a4a4b602629f858a780ad28f09f6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.3

Release history Release notifications | RSS feed

This release

1.0.1 This release

2 release files

1.0.0

2 release files

0.4.0

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page