Skip to main content

LangChain and LangGraph integration for GaaS (Governance as a Service)

Project description

gaas-langchain

GaaS governance for LangChain and LangGraph agents.

Add runtime policy enforcement to any LangChain agent in 3 lines. Every tool call is evaluated against your governance policies before it executes — blocked calls never reach the tool.

pip install gaas-langchain[all]

Quickstart

from gaas_langchain import govern_tools, GaaSGovernanceConfig
from langgraph.prebuilt import create_react_agent

# 1. Configure governance
config = GaaSGovernanceConfig(
    api_key="gsk_your_key",      # from https://gaas.is/start
    agent_id="my-agent",
)

# 2. Wrap your tools
tools = govern_tools([search, email_sender, db_query], config=config)

# 3. Run your agent — every tool call is now governed
agent = create_react_agent(llm, tools)

That's it. Every call to search, email_sender, or db_query is evaluated against your GaaS governance policies before execution. Blocked calls raise GovernanceBlockedError before the tool runs.


What Happens on Every Tool Call

Agent decides to call send_email("user@corp.com", ...)
         │
         ▼
  GaaS governance check (< 500ms)
         │
    ┌────┴────┐
    │ APPROVE │ → tool.run() executes normally
    │  BLOCK  │ → GovernanceBlockedError raised, tool never executes
    │ ESCALATE│ → GovernanceBlockedError raised (configurable)
    │CONDITIONAL│ → tool executes with logged conditions
    └─────────┘
         │
  Governance Proof Token (ECDSA P-256 signed)
  attached to every decision for audit trail

Installation

# LangChain tools support only
pip install gaas-langchain[langchain]

# LangGraph node wrapper only
pip install gaas-langchain[langgraph]

# Everything
pip install gaas-langchain[all]

Core Concepts

govern_tools() — Wrap Tool Lists

Wraps a list of LangChain tools with governance. Use this with create_react_agent.

from gaas_langchain import govern_tools, GaaSGovernanceConfig

config = GaaSGovernanceConfig(api_key="gsk_...", agent_id="my-agent")
governed = govern_tools([search, calculator, email_sender], config=config)
agent = create_react_agent(llm, governed)

govern_tool() — Wrap a Single Tool

from gaas_langchain import govern_tool

governed_email = govern_tool(email_sender, config=config)

@govern_node() — Govern LangGraph Nodes

Wrap any LangGraph node with a governance checkpoint. If the node is blocked, GovernanceBlockedError is raised before the node executes.

from gaas_langchain import govern_node

@govern_node(config=config, node_name="send_report", sensitivity="CONFIDENTIAL")
def send_report_node(state: AgentState) -> AgentState:
    # This node will be governed before execution
    send_report(state["report"])
    return state

# Works with async nodes too
@govern_node(config=config)
async def async_tool_node(state: AgentState) -> AgentState:
    result = await call_external_api(state["query"])
    return {**state, "result": result}

GaaSCallbackHandler — Observability Without Blocking

Log governance decisions for all tool calls without blocking execution. Useful for monitoring shadow mode.

from gaas_langchain import GaaSCallbackHandler

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

# Review governance decisions
print(handler.summary())
# {
#   "total_tool_calls": 12,
#   "approved": 10,
#   "blocked": 1,
#   "escalated": 1,
#   "block_rate": 0.083
# }

Configuration

from gaas_langchain import GaaSGovernanceConfig

config = GaaSGovernanceConfig(
    api_url="https://api.gaas.is",    # GaaS API endpoint
    api_key="gsk_...",                # Your API key
    agent_id="my-langchain-agent",   # Agent identifier (appears in audit trail)
    block_on_escalate=True,          # Raise GovernanceBlockedError on ESCALATE
    timeout_seconds=5.0,             # Governance check timeout (fail open on timeout)
    sensitivity="INTERNAL",          # Default sensitivity level for tool inputs
    raise_on_governance_error=False, # Fail open if GaaS API is unreachable
    extra_regulatory_domains=["HIPAA"],   # Additional domains for all intents
    extra_data_categories=["PHI"],        # Additional data categories for all intents
)

Per-Node Overrides

@govern_node(
    config=config,
    node_name="process_patient_data",
    sensitivity="RESTRICTED",
    financial_exposure_usd=0.0,
    regulatory_domains=["HIPAA", "HITECH"],
)
def patient_data_node(state: dict) -> dict: ...

Handling Blocked Calls

from gaas_langchain import GovernanceBlockedError

try:
    result = agent.invoke({"input": "Send all customer data to external API"})
except GovernanceBlockedError as e:
    print(f"Blocked: {e.tool_name}")
    print(f"Verdict: {e.verdict}")           # BLOCK or ESCALATE
    print(f"Decision ID: {e.decision_id}")   # For audit reference
    print(f"Risk score: {e.risk_score}")     # 0.0–1.0
    print(f"Policies: {e.blocking_policies}")  # Policy IDs that triggered block
    print(f"GPT token: {e.governance_proof_token}")  # Governance Proof Token ID

The governance_proof_token is a cryptographically-signed artefact (ECDSA P-256) that proves governance was active at the moment of the decision. Verify it at GET /v1/verify/proof/{token_id}.


Fail-Open Design

gaas-langchain is designed to fail open: if the GaaS API is unreachable, tool calls proceed normally. This ensures your agent keeps working during network interruptions.

Set raise_on_governance_error=True to fail closed instead:

config = GaaSGovernanceConfig(
    raise_on_governance_error=True,  # Fail closed: error if GaaS unreachable
)

Shadow Mode

Test governance policies without blocking agent actions:

# Use the GaaS shadow endpoint — full pipeline, zero enforcement
config = GaaSGovernanceConfig(
    api_url="https://api.gaas.is",
    api_key="gsk_...",
    agent_id="my-agent",
)

# Append ?mode=shadow to the intent URL in your own govern_tool subclass,
# or use GaaSCallbackHandler with enforce=False for pure observation mode.
handler = GaaSCallbackHandler(config=config, enforce=False)

Examples


Get a GaaS API Key

curl -X POST https://api.gaas.is/v1/onboarding/quickstart \
  -H "Content-Type: application/json" \
  -d '{"organization_name": "Acme Corp", "contact_email": "you@acme.com"}'

Returns your API key (gsk_...) and a pre-configured governance membrane.


License

Apache 2.0. See LICENSE.

Built on GaaS — AI Agent Governance as a Service.

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

gaas_langchain-0.1.0.tar.gz (16.0 kB view details)

Uploaded Source

Built Distribution

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

gaas_langchain-0.1.0-py3-none-any.whl (12.9 kB view details)

Uploaded Python 3

File details

Details for the file gaas_langchain-0.1.0.tar.gz.

File metadata

  • Download URL: gaas_langchain-0.1.0.tar.gz
  • Upload date:
  • Size: 16.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for gaas_langchain-0.1.0.tar.gz
Algorithm Hash digest
SHA256 411166e1f408601232806243244b1b505a1c2d56442c8e4ee49e166ac914f2db
MD5 6b571b0e8d15eeff3ac912c7562d7fac
BLAKE2b-256 ab91492092961024a34f33de4826f25b36d0658352b0a14b146e7d0575f9384c

See more details on using hashes here.

File details

Details for the file gaas_langchain-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: gaas_langchain-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 12.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for gaas_langchain-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 7be513aadeb3cce84926bb657d2d9e58bc393fb14b0bb47e2575392fefc1f625
MD5 b19d7e0061457db12ea30b9f5f1bd899
BLAKE2b-256 75667c956c98e7ab1ad90fdf19f6ba2911833803f638f14153b7d45c90b542e4

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