Alright, so I've been poking at the Anthropic Agent SDK for a few weeks now, and the biggest red flag for any production deployment is the default outbound call behavior. By default, if you're not careful, an agent can potentially call any external service a tool is configured for. That's a massive attack surface if someone manages to inject a malicious tool definition or if there's a misconfiguration.
The core of the problem is that the SDK's `AnthropicAgent` uses an `HTTPClient` (from the `requests` library) to make tool calls. We need to lock that down at the network layer *and* the SDK configuration layer. Here's how I've been doing it.
**Step 1: Restrict at the HTTPClient level.**
You need to create a custom `HTTPClient` that uses a whitelist. The easiest way is with a custom `requests.adapters.HTTPAdapter` and a custom `Session`. This adapter will reject any URL not matching your allowed gateways.
```python
from requests.adapters import HTTPAdapter
from urllib.parse import urlparse
import requests
class GatewayWhitelistAdapter(HTTPAdapter):
def __init__(self, allowed_base_urls, *args, **kwargs):
self.allowed_base_urls = [urlparse(url).netloc for url in allowed_base_urls]
super().__init__(*args, **kwargs)
def send(self, request, **kwargs):
if urlparse(request.url).netloc not in self.allowed_base_urls:
raise ValueError(f"Blocked outbound call to {request.url}. Not in whitelist.")
return super().send(request, **kwargs)
# Create a locked-down session
session = requests.Session()
allowed_gateways = ["https://tools.mycompany.com", "https://internal-api.example.net"]
adapter = GatewayWhitelistAdapter(allowed_base_urls=allowed_gateways)
session.mount("http://", adapter)
session.mount("https://", adapter)
```
**Step 2: Inject the locked-down client into the SDK.**
When you instantiate your agent, you pass this custom session. This ensures *all* tool calls made by the SDK go through your filtered session.
```python
from anthropic_agent_sdk import AnthropicAgent
agent = AnthropicAgent(
model="claude-3-5-sonnet-20241022",
http_client=session, # <-- Your locked-down session here
# ... your other config
)
```
**Step 3: Double-check your tool definitions.**
This is more of a sanity check, but ensure your tool `name` and `description` fields don't accidentally reference external URLs the SDK might try to resolve. The SDK uses the `url` parameter you provide in the tool schema. Make sure those URLs are only your whitelisted gateways.
**Important Caveats:**
* This doesn't stop the model from *suggesting* a call to a blocked endpoint—it just fails hard when the SDK tries to execute it.
* You must also consider DNS rebinding and ensure your network policies (e.g., Kubernetes network policies, AWS Security Groups) back this up. Defense in depth, people.
* If you're using the hosted Anthropic Agents service, this becomes trickier—you need to rely *entirely* on their upcoming permission features and your gateway's own authentication. My setup here is for the self-managed SDK.
Test it by trying to add a tool with a `url` like ` https://evil.com`. The agent will try to run it, and your adapter should throw that `ValueError`. Log that, alert on it.
kim out
kim out