Skip to main content

OpenTerms protocol integration for LangChain: permission-aware AI agents

Project description

langchain-openterms

Permission-aware LangChain agents that check a domain's openterms.json before taking action.

Fail-closed by default. If the site has no openterms.json, or the permission is not explicitly granted, execution is blocked. You must opt in to permissive behavior explicitly with fail_closed=False.

Installation

pip install langchain-openterms

# With openterms-py SDK (recommended, requires >=0.3.1):
pip install "langchain-openterms[sdk]"

Canonical Permission Keys

Only these 7 keys are recognized:

Key Meaning
read_content Read / display page content
scrape_data Automated scraping / crawling
api_access Access the domain's API
create_account Create a user account
make_purchases Complete a purchase
post_content Post or publish content
allow_training Use content for model training

Fail-Closed Defaults

The following states block execution by default:

  • null / None — domain unreachable or SDK error
  • no_openterms_json — no openterms.json file found
  • not_specified — key absent from openterms.json
  • low-confidence — validator confidence too low
  • conditional — permission has unverifiable conditions
  • denied — explicit deny

Only an explicit allowed: true in openterms.json permits execution.

Quick Start: OpenTermsGuard

Wrap any LangChain tool. Execution is blocked unless permission is explicitly granted.

from langchain_community.tools import BraveSearch
from langchain_openterms import OpenTermsGuard

search = BraveSearch.from_api_key(api_key="...", search_kwargs={"count": 3})

# Fail-closed by default — blocks if no openterms.json or not explicitly allowed
guarded_search = OpenTermsGuard(
    tool=search,
    action="read_content",
)

result = guarded_search.invoke("https://example.com/pricing")

if "blocked" in result.lower():
    # denied, not_specified, missing file, low-confidence — all blocked
    print("Cannot proceed:", result)
else:
    print("Allowed:", result)

The guard never silently proceeds on ambiguous results. If the check returns anything other than an explicit allow, the tool returns a block message.

Permissive Opt-In (explicit, not recommended for production)

# Only use fail_closed=False when you have a deliberate reason
permissive_guard = OpenTermsGuard(
    tool=search,
    action="read_content",
    fail_closed=False,  # pass through when no openterms.json found
)

With fail_closed=False, only an explicit denied blocks. Missing files and unspecified permissions pass through.

Denial Callback

denied_domains = []

guard = OpenTermsGuard(
    tool=search,
    action="scrape_data",
    on_denied=lambda domain, action, result: denied_domains.append(domain),
)

Agent Tool: OpenTermsChecker

Agents can call this tool directly to check permissions before deciding whether to proceed.

import json
from langchain_openterms import OpenTermsChecker

checker = OpenTermsChecker()

# Agent calls: "<domain> <action>"
result_json = checker.invoke("example.com scrape_data")
parsed = json.loads(result_json)

# Gate strictly on allowed=True
if parsed["check"]["allowed"] is True:
    # Only here is execution safe
    pass
else:
    # blocked: denied, not_specified, missing file, low-confidence, conditional
    print("Blocked:", parsed["check"]["reason"])

Passive Observer: OpenTermsCallbackHandler

Logs permission checks without blocking. Use this for monitoring only. Does not enforce permissions — use OpenTermsGuard for that.

from langchain_openterms import OpenTermsCallbackHandler

handler = OpenTermsCallbackHandler(
    default_action="read_content",
    on_check=lambda r: print(f"{r['domain']}: allowed={r['allowed']}"),
)

agent.invoke({"input": "..."}, config={"callbacks": [handler]})

# Review after the run — these are domains where action was NOT explicitly allowed
for check in handler.checks:
    if check["allowed"] is not True:
        print(f"Would be blocked: {check['domain']}{check['reason']}")

bool() Truthiness

Check results use strict truthiness: bool(result) is True only for explicitly allowed results. Do not rely on truthiness for dict results — always check result["allowed"] is True explicitly.

Using with openterms-py SDK

Install with SDK support for the most accurate results:

pip install "langchain-openterms[sdk]"
# Requires openterms-py>=0.3.1

The SDK applies fail-closed semantics at the check level. Empty caches, unreachable domains, and missing files all return non-allow decisions — never a permissive default.

openterms-py Dependency

  • With SDK ([sdk] extra or openterms-py>=0.3.1 installed): Uses the SDK for all permission checks. Requires openterms-py>=0.3.1 for correct fail-closed behavior.
  • Without SDK: Falls back to a built-in HTTP client with equivalent fail-closed semantics. Missing files and unspecified keys return allowed=None, which blocks under fail_closed=True (the default).

Version History

  • 0.4.0 — Fail-closed by default (fail_closed=True). Blocks null, not_specified, no_openterms_json, low-confidence, conditional, denied. fail_closed=False opt-in for permissive behavior. Canonical keys only. openterms-py>=0.3.1 required for SDK mode.
  • 0.3.1 — Initial public release.

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

langchain_openterms-0.4.0.tar.gz (17.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

langchain_openterms-0.4.0-py3-none-any.whl (13.5 kB view details)

Uploaded Python 3

File details

Details for the file langchain_openterms-0.4.0.tar.gz.

File metadata

  • Download URL: langchain_openterms-0.4.0.tar.gz
  • Upload date:
  • Size: 17.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for langchain_openterms-0.4.0.tar.gz
Algorithm Hash digest
SHA256 7175cab2f83a795653b4140bef8d68325727d6f9b7d7eac95025308a360ccc1c
MD5 61f43cc94d0d3f8178979d0cdebeef92
BLAKE2b-256 f0ca318a227b23fb16e4800ffd77b135218c8e81c0fb8ee9746ffcbbd307491a

See more details on using hashes here.

File details

Details for the file langchain_openterms-0.4.0-py3-none-any.whl.

File metadata

File hashes

Hashes for langchain_openterms-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6a25d17578b4ac41cf0f8875839b5224df96e71c3b9a73b4556fc918f04934fa
MD5 4fd36465b361f389c462d9dc4fec71ca
BLAKE2b-256 8f5b743bf3d7467891c02ad045611d2cef1dad6a5b91f9a66d006dfeb21752f9

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page