Azure Command Guard Hook
A PreToolUse hook that protects Azure infrastructure by blocking dangerous Azure CLI commands while allowing safe read operations and explicitly permitted writes.
Features
✅ Blocks dangerous operations
- Resource creation/deletion/updates
- Infrastructure deployments
- Role assignments
- Authentication changes
- Network modifications
✅ Allows safe read operations
az ... showaz ... listaz ... get- Log queries
- Resource information
✅ Allows specific write operations
- KeyVault secret operations (
az keyvault secret set/delete) - Storage blob uploads (
az storage blob upload/copy) - Storage file uploads
✅ Fail-safe by default
- Unrecognized Azure CLI commands are blocked
- Better to ask than to accidentally modify infrastructure
✅ Multi-command detection
- Checks ALL az commands in chained operations
- Example:
az account show && az group delete --yes→ BLOCKED
Installation
Repository-Level (Recommended)
Add to your repository's .claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"command": "~/.claude/hooks/azure-command-guard.sh"
}
]
}
}
Then commit the settings file:
git add .claude/settings.json
git commit -m "feat: add Azure command guard hook"
This protects everyone working on the repository.
Testing
Run the test suite to verify the hook works:
~/.claude/hooks/test-azure-guard.sh
Should output:
✓ All tests passed!
Passed: 31
Failed: 0
What's Blocked
Infrastructure Mutations
❌ az resource create
❌ az resource delete
❌ az resource update
❌ az group delete
❌ az deployment create
Database Changes
❌ az postgres flexible-server create
❌ az postgres flexible-server update
❌ az postgres flexible-server restart
❌ az sql server update
Network Changes
❌ az network vnet create
❌ az network vnet delete
❌ az network subnet update
Auth & Identity
❌ az account set
❌ az role assignment create
❌ az ad ...
Monitoring Changes
❌ az monitor diagnostic-settings create
❌ az monitor diagnostic-settings update
KeyVault Management (but NOT secrets)
❌ az keyvault create
❌ az keyvault delete
❌ az keyvault key create
Storage Account Management (but NOT uploads)
❌ az storage account delete
❌ az storage blob delete
What's Allowed
Authentication
✅ az login
Read Operations
✅ az account show
✅ az resource list
✅ az postgres flexible-server show
✅ az monitor log-analytics query
✅ az keyvault secret show
✅ az storage blob list
KeyVault Secret Operations
✅ az keyvault secret set --vault-name ... --name ... --value ...
✅ az keyvault secret delete --vault-name ... --name ...
✅ az keyvault secret backup
✅ az keyvault secret restore
Storage Uploads
✅ az storage blob upload --account-name ... --file ...
✅ az storage blob copy start --source-uri ...
✅ az storage file upload --share-name ... --source ...
Customization
Adding Safe Patterns
If you have legitimate read commands being blocked, add them to SAFE_PATTERNS in the hook script:
SAFE_PATTERNS=(
# ... existing patterns ...
'^az your-service your-safe-command'
)
Adding Allowed Writes
If you need to allow specific write operations, add them to ALLOWED_WRITES:
ALLOWED_WRITES=(
# ... existing patterns ...
'^az your-service your-allowed-write'
)
Per-Repository Customization
Copy the hook to your repository and customize it:
mkdir -p .claude/hooks
cp ~/.claude/hooks/azure-command-guard.sh .claude/hooks/
chmod +x .claude/hooks/azure-command-guard.sh
Update .claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"command": ".claude/hooks/azure-command-guard.sh"
}
]
}
}
Now you can customize the patterns for your specific needs.
How It Works
- Hook Trigger: Runs before every Bash command
- Azure Detection: Checks if command contains
azcommands - Pattern Matching: Checks each az command against:
- Safe patterns (allow)
- Allowed writes (allow)
- Dangerous patterns (block)
- Unknown patterns (block - fail-safe)
- Result: Returns exit code 0 (allow) or 1 (block)
Example Output
When a dangerous command is blocked:
╔════════════════════════════════════════════════════════════════╗
║ ⛔ BLOCKED: Azure Resource Modification Detected ║
╚════════════════════════════════════════════════════════════════╝
Command: az group delete --name rg-test --yes
Pattern matched: ^az group delete
This command modifies Azure resources and requires explicit approval.
Allowed operations:
✓ Read operations (show, list, get, query)
✓ KeyVault secret operations (set, delete, backup)
✓ Storage blob uploads/copies
To execute this command:
1. Review the command carefully
2. Run it manually in your terminal
3. Or use Claude Code's approval flow if available
Limitations
- Not foolproof: Claude could potentially use
curlto call Azure REST API directly, or use Python SDKs - Maintenance: New Azure CLI commands may not be covered until patterns are updated
- False positives possible: Some safe commands might match dangerous patterns (update the hook if this happens)
- Guardrail, not security boundary: A determined agent could find workarounds
Best Practices
- Use repository-level configuration: Protects the entire team
- Test after customization: Run
test-azure-guard.shafter modifying patterns - Review blocked commands: Don't blindly override - understand why it was blocked
- Keep patterns updated: Add new Azure services as they're introduced
- Combine with other safeguards: Use alongside Azure RBAC, resource locks, and policy
Extending to Other Cloud Providers
The same pattern works for AWS and GCP:
AWS
# In the hook script, add AWS checks:
if [[ "$COMMAND" =~ [[:space:]]aws[[:space:]] ]] || [[ "$COMMAND" =~ ^aws[[:space:]] ]]; then
# Similar pattern matching for aws commands
fi
GCP
# In the hook script, add GCP checks:
if [[ "$COMMAND" =~ [[:space:]]gcloud[[:space:]] ]] || [[ "$COMMAND" =~ ^gcloud[[:space:]] ]]; then
# Similar pattern matching for gcloud commands
fi
Troubleshooting
Hook not running
- Check
.claude/settings.jsonis configured - Restart Claude Code (hooks load at session start)
- Verify hook is executable:
ls -la ~/.claude/hooks/azure-command-guard.sh
Legitimate command blocked
- Identify the command pattern
- Add to
SAFE_PATTERNSorALLOWED_WRITESin the hook - Test with
test-azure-guard.sh - Commit the updated hook
Hook not blocking dangerous command
- Check the command pattern
- Add to
DANGEROUS_PATTERNSif missing - Test with
test-azure-guard.sh - Report the issue if it's a common pattern that should be included
Support
- Report issues: https://github.com/Motium-AI/namshub/issues
- Test suite:
~/.claude/hooks/test-azure-guard.sh - Hook source:
~/.claude/hooks/azure-command-guard.sh