Just started poking at the Anthropic Agent SDK for a side project, and immediately hit a wall: how would this even work with multiple end-users? The docs are great for a single assistant, but the security model seems... implicit?
My main worry is tool execution. If I'm building a platform where each user gets their own agent instance, how do I guarantee User A's agent can't call a tool with User B's data? The SDK's permission system appears to be based on granting functions to the *agent*, not scoping them per *user session*. That means if I'm not extremely careful with my tool implementations, I could be leaking data across tenant boundaries in the tool logic itself. The SDK doesn't enforce that—it's on me.
Then there's the state. The SDK handles message history and tool calls, but where does that live? If I'm using the standard `Anthropic` client, the context goes to their API. That's fine, but my tool execution happens locally. So the split is: Anthropic sees the conversation and tool definitions/names, but the actual tool *execution* and its data stay with me. That means my tool layer has to be the fortress.
I'm trying to design a test suite that spins up isolated agent instances with mocked tools to probe these cross-tenant leaks. Feels like we need a middleware that injects user context into every tool call and validates it before running. Anyone else wrestling with this? What's your isolation strategy?
test first, ask later
You've hit on the exact thing that's been keeping me up! That split you mentioned is so critical - Anthropic gets the conversation flow, but your code runs the actual tools. The isolation burden is 100% on your implementation.
So if the tool logic itself has to be the fortress, does that mean we're basically back to designing a hardened, user-scoped API layer *first*, and then just letting the agent call into it? The SDK just becomes a fancy router. That feels right but also a bit disappointing.
Have you seen any patterns for injecting user context into the tool calls themselves? Like, can you wrap the tool execution in a closure that has the tenant ID baked in, or do you have to parse it from the agent's state every single time?
Exactly. That hardened, user-scoped API layer *is* your trust boundary. The SDK is inside it.
You can bake context into the tool. When you instantiate the agent for a session, construct your tools there, closing over the tenant ID. Your tool implementation becomes a thin wrapper that adds that context to every call before it hits your actual business logic.
This shifts the threat model: you must now guarantee agent *session* isolation, not just tool logic isolation. How are you managing those agent instances? One per container? Are they sharing any mutable memory?
-- sara
That's a great point about shifting the threat model to session isolation. It feels like the tool baking helps, but you're right, if the agent instances themselves are sharing memory or some global state, it all falls apart anyway.
For my little home lab setup, I was thinking one container per user session, but that seems heavy. Is anyone running agents in a serverless function per interaction instead? Then the session is truly ephemeral, but you'd have to re-hydrate the message history from a secure store each time.
How do you make sure that stored history itself is scoped and can't leak between tenants? That seems like another layer.
Your test suite idea is good, but you're still thinking about the SDK as a security component. It isn't. It's a router, like user324 said.
The moment you call `anthropic.messages.create()`, your conversation state leaves your perimeter. The "fortress" is now your entire tool execution runtime. Your test suite should be fuzzing *that* for tenant ID leaks, not the agent's configuration. The SDK is just a fancy way to parse JSON.
So you're testing the wrong layer. You need to assume the agent can and will call any tool you give it, in any order, with any parameters it can dream up. Your tool logic has to enforce the tenant boundary on every single execution, no matter what the SDK says.
Your threat model is missing a row.