LangChain integration for LatchGate — execution security kernel for AI agents
Project description
latchgate-langchain
LangChain integration for LatchGate — execution security kernel for AI agents.
Every tool call goes through LatchGate's enforcement pipeline: auth => policy => WASM sandbox => verification => signed receipt. The LLM never holds credentials and never contacts external systems directly.
Installation
pip install latchgate-langchain
Requires a running LatchGate instance:
curl -fsSL https://raw.githubusercontent.com/latchgate-ai/latchgate/main/install.sh | bash && latchgate up
Quick start
import asyncio
from langchain_openai import ChatOpenAI
from langchain.agents import AgentExecutor, create_tool_calling_agent
from langchain_core.prompts import ChatPromptTemplate
from latchgate_langchain import LatchGateToolset
async def main():
# Discover all LatchGate actions as LangChain tools.
async with await LatchGateToolset.create(
gate_url="http://localhost:3000",
agent_id="my-langchain-agent",
) as toolset:
tools = toolset.get_tools()
llm = ChatOpenAI(model="gpt-4o")
prompt = ChatPromptTemplate.from_messages([
("system", "You are a helpful assistant with access to gated tools."),
("human", "{input}"),
("placeholder", "{agent_scratchpad}"),
])
agent = create_tool_calling_agent(llm, tools, prompt)
executor = AgentExecutor(agent=agent, tools=tools)
result = await executor.ainvoke({"input": "Fetch https://httpbin.org/get"})
print(result["output"])
asyncio.run(main())
API
LatchGateToolset
Main entry point. Discovers actions and wraps them as LangChain tools.
toolset = await LatchGateToolset.create(
gate_url="http://localhost:3000", # Required (or set LATCHGATE_URL)
agent_id="my-agent", # Default: "langchain"
include={"http_fetch", "database"}, # Optional: only these actions
exclude={"send_message"}, # Optional: skip these actions
on_audit=my_audit_callback, # Optional: receipt callback
)
tools = toolset.get_tools() # list[BaseTool]
ids = toolset.action_ids # list[str]
client = toolset.client # LatchGateClient (for direct access)
await toolset.close() # Clean up transport
Use as an async context manager for automatic cleanup:
async with await LatchGateToolset.create(gate_url="...") as toolset:
tools = toolset.get_tools()
Or create from pre-fetched descriptors (synchronous, no I/O):
toolset = LatchGateToolset.from_descriptors(descriptors, client=client)
LatchGateTool
Individual tool wrapping a single action. Created automatically by the toolset, but can be used directly:
from latchgate import LatchGateClient
from latchgate_langchain import LatchGateTool, ActionDescriptor
client = LatchGateClient(base_url="http://localhost:3000", agent_id="my-agent")
descriptor = ActionDescriptor(
action_id="http_fetch",
version="1.0.0",
risk_level="low",
request_schema={"type": "object", "properties": {"url": {"type": "string"}}, "required": ["url"]},
description="Fetch a URL through LatchGate",
)
tool = LatchGateTool.from_descriptor(descriptor, client)
result = await tool.ainvoke({"url": "https://httpbin.org/get"})
discover_actions
Low-level discovery function for advanced control:
from latchgate_langchain import discover_actions
descriptors = await discover_actions(
"http://localhost:3000",
include={"http_fetch"},
timeout=10.0,
)
Error handling
LatchGate errors are surfaced as ToolException with structured messages the LLM can reason about:
| LatchGate error | Tool behavior |
|---|---|
| Policy denied | ToolException — "denied: {reason}" |
| Approval required | ToolException — "requires human approval" (approval_id emitted via callback, not to the model) |
| Budget exhausted | ToolException — "obtain a new lease" |
| Transport / infra | ToolException — retryable failure |
All tools have handle_tool_error=True so errors are returned to the LLM as text rather than crashing the agent.
Output format
Tool output is a JSON string containing only the action result. Enforcement metadata (receipt ID, trace ID, verification) is never returned to the model — it is emitted at INFO log level and via the optional on_audit callback.
{"status": 200, "body": "{...}"}
License
Apache-2.0
Project details
Release history Release notifications | RSS feed
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 latchgate_langchain-0.1.1.tar.gz.
File metadata
- Download URL: latchgate_langchain-0.1.1.tar.gz
- Upload date:
- Size: 99.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f69ca684e6fe09464c3d953277f405322d225e2179f232a98ccd38ec7ce9abc2
|
|
| MD5 |
f7f146f014798dd8705a643a8fe2202a
|
|
| BLAKE2b-256 |
df8bfeae7047a884af127cd72e242153bfe77035b53a8fc37e3206f89673094b
|
Provenance
The following attestation bundles were made for latchgate_langchain-0.1.1.tar.gz:
Publisher:
release.yml on latchgate-ai/latchgate-integrations
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
latchgate_langchain-0.1.1.tar.gz -
Subject digest:
f69ca684e6fe09464c3d953277f405322d225e2179f232a98ccd38ec7ce9abc2 - Sigstore transparency entry: 1754733816
- Sigstore integration time:
-
Permalink:
latchgate-ai/latchgate-integrations@00b7380c470ac7386569e68d1cf429a1e2354829 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/latchgate-ai
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@00b7380c470ac7386569e68d1cf429a1e2354829 -
Trigger Event:
push
-
Statement type:
File details
Details for the file latchgate_langchain-0.1.1-py3-none-any.whl.
File metadata
- Download URL: latchgate_langchain-0.1.1-py3-none-any.whl
- Upload date:
- Size: 12.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8406adec31e4b055336aaa6cbc354832b6ffcbf96a5af76e5f4a0904a9c3b151
|
|
| MD5 |
5345d33c90f0187f4d9e4f9e368756ff
|
|
| BLAKE2b-256 |
830b560980f05eaff5c7bdc084a4ec1cae1c3a42dc3350f9e146a20952578e08
|
Provenance
The following attestation bundles were made for latchgate_langchain-0.1.1-py3-none-any.whl:
Publisher:
release.yml on latchgate-ai/latchgate-integrations
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
latchgate_langchain-0.1.1-py3-none-any.whl -
Subject digest:
8406adec31e4b055336aaa6cbc354832b6ffcbf96a5af76e5f4a0904a9c3b151 - Sigstore transparency entry: 1754733826
- Sigstore integration time:
-
Permalink:
latchgate-ai/latchgate-integrations@00b7380c470ac7386569e68d1cf429a1e2354829 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/latchgate-ai
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@00b7380c470ac7386569e68d1cf429a1e2354829 -
Trigger Event:
push
-
Statement type: