SecureAnthropic
Drop-in replacement for the Anthropic Python SDK. All Claude models supported with full policy enforcement, cryptographic signing, and audit logging.
Quick Start
from anthropic import Anthropic
client = Anthropic()
message = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello"}]
)from macaw_adapters.anthropic import SecureAnthropic
client = SecureAnthropic(app_name="my-app")
message = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello"}]
)When to Use Each Path
SecureAnthropic supports three usage patterns depending on your identity requirements:
| Path | When to Use | Identity |
|---|---|---|
| client.messages.create() | Simple scripts, single-user apps | App-level only |
| bind_to_user() | Multi-user SaaS, per-user policies | User JWT + app |
| invoke_tool() | Agent-to-agent, explicit control | Full A2A chain |
Constructor
class SecureAnthropic:
def __init__(
self,
api_key: str = None, # Anthropic API key (or ANTHROPIC_API_KEY env)
app_name: str = None, # Application name for MACAW registration
intent_policy: dict = None, # Application-defined MACAW intent policy
jwt_token: str = None, # User JWT for user-mode (creates user agent)
user_name: str = None # Optional user name for user mode
)Two Modes
- Service mode (default): No jwt_token - creates service agent, registers tools
- User mode: With jwt_token - creates user agent with identity for direct calls
MACAW-Protected Methods
These methods route through MACAW PEP for policy enforcement, signing, and audit:
message = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello"}],
system="You are a helpful assistant",
tools=[...], # Tool calls enforced by policy
stream=False # Streaming supported
)# Context manager style streaming
with client.messages.stream(
model="claude-sonnet-4-20250514",
max_tokens=1024,
messages=[{"role": "user", "content": "Tell me a story"}]
) as stream:
for text in stream.text_stream:
print(text, end="")# Legacy completions API (Claude 2.x)
completion = client.completions.create(
model="claude-2.1",
prompt="\n\nHuman: Hello\n\nAssistant:",
max_tokens_to_sample=256
)Pass-through APIs
These delegate directly to the underlying Anthropic client (no MACAW protection):
| API | Description |
|---|---|
| beta | Beta features (message batches, etc.) |
| count_tokens() | Token counting utility |
bind_to_user()
For multi-user SaaS scenarios, bind the service to a user's MACAWClient:
from macaw_adapters.anthropic import SecureAnthropic
from macaw_client import MACAWClient
# Create shared service (once at startup)
service = SecureAnthropic(app_name="my-saas")
# Per-request: create user client and bind
user_client = MACAWClient(
user_name="alice",
iam_token=request.headers["Authorization"],
agent_type="user"
)
user_client.register()
# Bind service to user - all calls now use user's identity
user_claude = service.bind_to_user(user_client)
# Use exactly like regular client
message = user_claude.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello"}]
)
# Cleanup when done
user_claude.unbind()BoundSecureAnthropic
The bind_to_user() method returns a BoundSecureAnthropic wrapper that routes all calls through the user's MACAWClient to the service. This enables per-user identity and policy enforcement. Call unbind() when done to invalidate the binding.
Streaming Responses
Use messages.stream() for real-time token streaming. Policy enforcement happens before the first chunk is returned — blocked requests never start streaming.
# Streaming response - works identically to Anthropic
with client.messages.stream(
model="claude-3-haiku-20240307",
max_tokens=400,
messages=[{"role": "user", "content": "Write a poem"}]
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)Streaming Security
Policy checks (model, max_tokens, etc.) are validated before streaming begins. Each chunk is logged for audit compliance. The underlying invoke_tool(stream=True) handles this automatically.
A2A: invoke_tool()
For agent-to-agent (A2A) systems or when you need explicit control over tool routing. Returns raw dict instead of SDK types.
# Service registers tools
service = SecureAnthropic(app_name="anthropic-service")
# User agent calls invoke_tool directly
result = user.invoke_tool(
tool_name="tool:anthropic-service/generate", # MAPL name
parameters={
"model": "claude-3-haiku-20240307",
"max_tokens": 100,
"messages": [{"role": "user", "content": "Hello"}]
},
target_agent=service.server_id
)
# Result is raw dict (not Message)
content = result["content"][0]["text"]MAPL Tool Names
SecureAnthropic registers tools with MAPL-compliant names for policy targeting:
| Method | MAPL Tool Name | Example |
|---|---|---|
| messages.create() | tool:<app>/generate | tool:my-app/generate |
| messages.stream() | tool:<app>/generate | tool:my-app/generate |
| completions.create() | tool:<app>/complete | tool:my-app/complete |
Policy Integration
Target SecureAnthropic methods in MAPL policies using the tool names above:
{
"constraints": {
"parameters": {
"tool:my-app/generate": {
"model": {
"allowed_values": [
"claude-3-haiku-20240307",
"claude-sonnet-4-20250514"
]
},
"max_tokens": {
"type": "integer",
"max": 4096
}
}
}
}
}Examples
from macaw_adapters.anthropic import SecureAnthropic
client = SecureAnthropic(app_name="assistant")
tools = [{
"name": "get_weather",
"description": "Get weather for a location",
"input_schema": {
"type": "object",
"properties": {
"location": {"type": "string"}
}
}
}]
message = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
tools=tools,
messages=[
{"role": "user", "content": "What's the weather in SF?"}
]
)
# Tool calls logged and policy-checked
for block in message.content:
if block.type == "tool_use":
print(f"Tool: {block.name}, Input: {block.input}")Official API Reference
SecureAnthropic maintains API compatibility with the official Anthropic Python SDK:
SDK Compatibility: anthropic-sdk-python ≥0.18.0 • Messages API v1