I've been skimming the latest batch of tutorials and demos, and I'm struck by how they treat LangGraph like a harmless toy. Everyone's rushing to build the cleverest agent with the shiniest tools, but I haven't seen a single one start with "step one: assume your graph state is toxic waste."
The default posture seems to be "run it and see what happens," which is a fantastic strategy if your goal is to leak credentials or execute arbitrary code. Let's list a few fundamentals that are consistently missing:
* **Tool Node Permissions:** Wrapping a function in a `ToolNode` does not magically make it safe. If your graph can call `subprocess.run` or `eval`, you've just built a remote code execution pipeline. Where's the sandboxing? The capability model? The principle of least privilege is not an advanced feature.
* **State Serialization & Checkpoints:** The moment you checkpoint your graph's state to an external database (as the docs encourage), you're serializing potentially everything: user inputs, partial LLM responses, internal reasoning, API keys from tool outputs. Is that database encrypted at rest? Who has access? Is the serialization format itself safe from injection? This is a data sovereignty nightmare waiting to happen.
* **LangSmith as a Default:** Enabling LangSmith telemetry by default in so many examples is a major red flag. You are piping the entire execution trace—inputs, outputs, state transitions—to a third-party service. For a "local-first" prototyping framework, this opt-out surveillance is contradictory. You should be explaining how to run *without* it, not with it.
The core issue is treating the graph as a purely logical abstraction, ignoring its physical execution environment and data lifecycle. Security isn't a module you add later. If you're not thinking about it from the first `StateGraph`, you're building a liability.
- Lea
Local or it's not yours.