Rationale

Prompt injection and tool execution: LangGraph’s ToolNode validates tool names against the registered set but does not inspect or sanitize argument values. This is the correct boundary — the framework cannot know what constitutes a “safe” argument for an arbitrary user-defined tool. The tool’s own Pydantic schema and implementation must validate inputs. The framework’s responsibility is to not execute unregistered tools and to correctly route registered ones. The injection system (InjectedState/InjectedStore/ToolRuntime) is safe because system-injected values always overwrite LLM-supplied collisions via dict merge order, and injected parameter names are hidden from the LLM’s tool schema.

State integrity: LangGraph channels enforce type contracts (e.g., LastValue accepts one value per step, BinaryOperatorAggregate applies a reducer). The framework validates graph structure at compile time (libs/langgraph/langgraph/pregel/_validate.py:validate_graph). However, the semantic correctness of state updates is the user’s responsibility — the framework cannot know what values are “valid” for a user-defined state schema.

Checkpoint access control: The framework provides BaseCheckpointSaver as an abstract interface and the Auth handler system for authorization (libs/sdk-py/langgraph_sdk/auth/__init__.py:Auth). It does not enforce authentication by default because it operates as a library, not a server. The langgraph-api server layer (out of scope) is responsible for enforcing auth on API endpoints. Users embedding LangGraph directly must implement their own access controls.

Encryption handler safety: The SDK Encryption module (libs/sdk-py/langgraph_sdk/encryption/) provides a registration framework for developer-authored encryption handlers. These handlers run server-side with full process access, identical to any application code. A buggy or malicious handler could return crafted data, but this is the same trust model as any developer-written code. The SDK validates handler shape (async, 2-param) but not handler behavior — this is the correct boundary for developer-trust-level code.