LangGraph Integration
ShadowAudit integrates with LangGraph by wrapping tools before they are passed to graph nodes. Enforcement applies at every tool invocation, including within loops and conditional branches.
Installation
pip install "shadowaudit[langchain]"
Wrapping tools for a graph
from shadowaudit import ShadowAuditTool
from langchain.tools import ShellTool
from langgraph.prebuilt import create_react_agent
safe_shell = ShadowAuditTool(
tool=ShellTool(),
agent_id="graph-agent",
capability="shell.execute",
policy_path="policies/shell.yaml"
)
# Pass wrapped tools to the graph agent
graph = create_react_agent(model, tools=[safe_shell])
Manual graph nodes
When defining graph nodes manually, gate tool calls within the node function:
from shadowaudit.core.gate import Gate
from langgraph.graph import StateGraph
gate = Gate()
def tool_node(state):
command = state["command"]
result = gate.evaluate(
agent_id="graph-agent",
task_context="shell",
risk_category="shell_execution",
capability="shell.execute",
policy_path="policies/shell.yaml",
payload={"command": command}
)
if not result.passed:
return {"error": f"Blocked: {result.reason}"}
# execute tool
output = run_shell(command)
return {"output": output}
builder = StateGraph(MyState)
builder.add_node("tool", tool_node)
Multi-agent graphs
In graphs where one agent hands off to another, propagate the agent lineage:
gate.evaluate(
agent_id="executor-agent",
task_context="database",
risk_category="database_write",
capability="database.write",
policy_path="policies/database.yaml",
payload={"query": sql}
)
Use FlowTracer when you need to track data movement across planner and executor agents.