Summary
PreToolUse hooks currently require permissionDecision: "allow" to apply updatedInput modifications. This prevents using hooks for input sanitization while preserving the normal permission flow (Deny Rules → Allow Rules → Ask Rules → canUseTool).
Use Case
We're building a multi-tenant Claude SDK application where we need to:
- Pass
ANTHROPIC_API_KEY to the SDK subprocess for API authentication
- Prevent Bash tool commands from accessing sensitive environment variables
Our security approach:
- Intercept Bash commands via PreToolUse hook
- Prepend
unset ANTHROPIC_API_KEY FACETS_TOKEN ...; to commands
- Let the normal permission flow decide whether to allow/deny/ask
Current Behavior
# Hook returns only updatedInput (no permissionDecision)
return {
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"updatedInput": {
"command": f"unset SENSITIVE_VAR; {original_command}"
}
}
}
Result: updatedInput is ignored, original command runs unmodified.
Expected Behavior
Hook should be able to modify input AND continue to normal permission flow:
PreToolUse Hook (modify input) → Deny Rules → Allow Rules → Ask Rules → canUseTool
↓
updatedInput applied
Current Workarounds (All Have Drawbacks)
| Approach |
Problem |
Hook + permissionDecision: "allow" |
Auto-allows all Bash, bypasses user confirmation |
canUseTool callback |
Bypassed when Allow Rules match ("Allow for Session") |
| Don't pass API key to subprocess |
SDK can't authenticate API calls |
Proposed Solution
Support updatedInput without permissionDecision:
return {
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"updatedInput": {"command": secured_command},
# No permissionDecision → continue to Deny/Allow/Ask rules with modified input
}
}
Alternative Solutions
CLI Argument for API Key Authentication
Support passing ANTHROPIC_API_KEY via CLI argument instead of environment variable:
claude --api-key "sk-ant-..." [other options]
Or via SDK options:
ClaudeAgentOptions(
api_key="sk-ant-...", # Passed as CLI arg, NOT as env var
env={}, # No sensitive vars in subprocess environment
)
Benefits:
- CLI process authenticates using the argument
- Argument is NOT inherited by child processes (unlike env vars)
- Bash subprocesses never see the API key
- No hooks or input modification needed
This follows the security principle of least privilege - authentication credentials are scoped to the process that needs them, not leaked to all descendants.
Environment
- Claude Code CLI version: 2.x
- claude-agent-sdk (Python): 0.1.6
- Platform: Linux/macOS
Impact
This limitation affects any SDK integrator who needs to:
- Sanitize tool inputs for security
- Transform tool parameters based on context
- Protect sensitive credentials from Bash tool access
- While still respecting permission rules and user confirmations
Summary
PreToolUse hooks currently require
permissionDecision: "allow"to applyupdatedInputmodifications. This prevents using hooks for input sanitization while preserving the normal permission flow (Deny Rules → Allow Rules → Ask Rules → canUseTool).Use Case
We're building a multi-tenant Claude SDK application where we need to:
ANTHROPIC_API_KEYto the SDK subprocess for API authenticationOur security approach:
unset ANTHROPIC_API_KEY FACETS_TOKEN ...;to commandsCurrent Behavior
Result:
updatedInputis ignored, original command runs unmodified.Expected Behavior
Hook should be able to modify input AND continue to normal permission flow:
Current Workarounds (All Have Drawbacks)
permissionDecision: "allow"canUseToolcallbackProposed Solution
Support
updatedInputwithoutpermissionDecision:Alternative Solutions
CLI Argument for API Key Authentication
Support passing
ANTHROPIC_API_KEYvia CLI argument instead of environment variable:claude --api-key "sk-ant-..." [other options]Or via SDK options:
Benefits:
This follows the security principle of least privilege - authentication credentials are scoped to the process that needs them, not leaked to all descendants.
Environment
Impact
This limitation affects any SDK integrator who needs to: