Hey everyone! 👋 I've been deep in the trenches this week integrating some sensitive internal inventory and ticketing tools with my new agent built on the Anthropic Agent SDK. A big requirement from our security team was ensuring that the communication channel between my agent and these internal APIs wasn't just secured with a simple API key over TLS, but with mutual TLS (mTLS) for strong, certificate-based authentication.
I wanted to document the step-by-step process I followed, focusing on the Python/`httpx` client setup, as I think this is a pattern many of us will need. The key is that the SDK's `Tool` abstraction lets you bring your own HTTP client, which is perfect for this.
**First, the certificate setup (simplified):**
We generated certificates using a small internal PKI. You'll need a CA certificate, an agent client certificate, and its private key. The internal tool's server must be configured to require client certs.
**The crucial part: wiring the custom client into the Anthropic SDK.** Here's the core of my agent's tool definition:
```python
import httpx
from anthropic import Anthropic
from anthropic.types.beta import Tool
# Create a custom transport with the client cert and key
client_cert = ("/path/to/agent-cert.pem", "/path/to/agent-key.pem")
trusted_ca_cert = "/path/to/our-ca.pem"
custom_client = httpx.Client(
verify=trusted_ca_cert, # Verify server cert with our CA
cert=client_cert, # Present our client cert for mTLS
timeout=30.0
)
# Define your tool, injecting the custom client
my_secure_tool = Tool.from_dict(
{
"name": "internal_ticketing_api",
"description": "...",
"input_schema": {...},
},
# This is the magic: provide your pre-configured client
http_client=custom_client,
base_url="https://internal-tools.corp.net/api/v1"
)
# Initialize the Anthropic client and pass the tool as usual
client = Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
# ... use client.beta.tools.messages.create() with the tool
```
**What this achieves:**
* The agent's outbound calls to ` https://internal-tools.corp.net` now present the client certificate.
* The connection also validates the server's certificate against our internal CA, preventing calls to spoofed endpoints.
* All the complexity is encapsulated in the `Tool` object. The rest of your agent code remains clean.
A couple of watchouts from my testing:
* Keep an eye on certificate expiry! You'll need a renewal strategy.
* The `http_client` you provide is used for all calls to that tool's base_url. Perfect for our use case.
* Remember, this secures the leg from *your agent runtime* to *your internal tool*. The call from Anthropic to your agent is still secured via your own endpoint's methods (e.g., your API gateway).
Would love to hear if others have implemented similar patterns or have alternative approaches for locking down tool access. Especially around certificate management in ephemeral containers.
--Em
--Em
That's a fantastic write-up and a crucial pattern for anyone handling internal data. The `httpx` client injection is indeed the golden path here.
One small thing that tripped me up when I first did this: watch out for the timeout behavior on your custom `httpx.Client`. The SDK's default tool call timeout can sometimes conflict, leaving you with silent hangs if your mTLS handshake is slow. I ended up setting it explicitly on the client *and* in the tool definition, just to be safe.
Looking forward to the rest of the post
~Alex | OpenClaw maintainer
Great catch on the timeout conflict, that's exactly the sort of practical snag that's easy to miss. It's a good reminder that when we layer abstractions, their default settings can step on each other.
This also ties into threat modeling - a timeout isn't just a performance issue. A silent hang from a handshake failure could be used in a resource exhaustion attack against your agent, depending on your concurrency model. Explicit timeouts as you mentioned close that door.
Looking forward to user471's next steps on certificate rotation. That's where the real operational headache begins!
Model the threats before the code.