Skip to main content

Anthropic Claude SDK

Pavri integrates with the Anthropic Claude Agent SDK through a pre-tool-use hook that enforces runtime governance policies before tool execution.

One-Line Integration

from pavri import PavriConfig, secure

agent = build_claude_agent()
agent = secure(agent, PavriConfig(agent_name="my-agent", plugin="claude_sdk"))

The secure() call attaches the Pavri runtime to the agent, registers it with the backend, and installs the enforcement hook.

Supported Versions

  • Anthropic Python SDK >=0.40.0
  • Python >=3.12

How It Works

Plugin Detection

The ClaudeSDKAdapter matches when either:

  • You pass plugin="claude_sdk" in the config
  • The target object's module name contains "anthropic"

Hooks Attached

When the runtime has an active policy cache and telemetry emitter, secure() attaches the following hook:

HookPurpose
_pavri_pre_tool_useEvaluates policy before tool execution; raises PolicyDeniedError on denial

Pre-Tool-Use Enforcement

The _pavri_pre_tool_use hook is called with the tool name before each tool execution:

# Internal flow — you do not call this directly
agent._pavri_pre_tool_use("tool_name")

The hook calls enforce_policy(f"tool:{tool_name}", ctx) against the local policy cache. This follows the Claude SDK's PreToolUse hook pattern where the hook runs before tool execution and can block it by raising an exception.

Policy evaluation respects the configured fail_mode:

  • fail-open (default): If policy evaluation fails, the tool call is allowed.
  • fail-closed: If policy evaluation fails, the tool call is denied.

When a policy rule denies the action, PolicyDeniedError is raised:

from pavri.core.exceptions import PolicyDeniedError

try:
result = agent.run("user input")
except PolicyDeniedError as e:
print(f"Blocked: {e.reason} (rule: {e.rule_id})")

Configuration

Key PavriConfig options for the Claude SDK:

from pavri import PavriConfig

config = PavriConfig(
agent_name="my-agent",
plugin="claude_sdk",
api_key="fab_...",
backend_url="https://pavri.example.com",
org_id="org-acme",
session_id="session-123",
team="platform",
environment="production",
fail_mode="open",
)
FieldDefaultDescription
fail_mode"open"Whether to allow or deny when policy evaluation fails
telemetry_mode"full"Controls telemetry detail level
environment"development"Deployment environment tag
policy_sync.poll_interval_seconds60How often to poll for policy updates

Claude SDK Security Notes

The Claude SDK has built-in security features that Pavri complements:

  • Permission modes: The Claude SDK supports denyPermissions, acceptPermissions, and bypassPermissions modes. Pavri enforces policies on top of whatever permission mode is configured.
  • Filesystem sandboxing: The Claude SDK restricts file writes to the project directory by default. Pavri adds Landlock enforcement on Linux for stronger path restrictions when OS-level jailing is enabled.
  • allowed_tools / disallowed_tools: The Claude SDK supports declarative tool lists. Pavri adds dynamic, policy-driven tool governance that can change at runtime.

Unsafe Configuration Detection

The design spec identifies a critical risk: the combination of bypassPermissions and allowUnsandboxedCommands silently disables all sandbox protections. Detection of this unsafe configuration combination is planned for a future release and will emit an UnsafeConfigWarning when detected.

Graceful Degradation

If the Pavri runtime cannot build an enforcement context, the plugin skips hook installation entirely. The agent runs without Pavri enforcement. Check the runtime status to verify:

from pavri.core import get_runtime

runtime = get_runtime(agent)
status = runtime.status()
print(status.connected, status.policy_revision)

Troubleshooting

Agent runs but no policy enforcement

  • Verify the backend is reachable and api_key is set.
  • Check runtime.status().policy_revision — if 0, the SDK has no cached policy.
  • The plugin requires both a policy cache and telemetry emitter.

PolicyDeniedError raised unexpectedly

  • Inspect the exception: e.decision contains the full PolicyDecision with the matched rule_id and reason.
  • Check whether fail_mode="closed" is set.
  • Review policies in the dashboard.

Plugin not detected

  • Pass plugin="claude_sdk" explicitly in the config.
  • Ensure the agent object's module includes "anthropic" in its path for auto-detection.

What's Deferred

The following capabilities are planned for Phase 2:

  • Log forwarding from the Claude plugin
  • Trace-link capture (Anthropic has limited native tracing; TraceProvider.anthropic support is planned)
  • PostToolUse hook for result inspection
  • Unsafe config detection (bypassPermissions + allowUnsandboxedCommands warning)
  • PostToolUseFailure hook for error monitoring