Skip to main content

Cyberstrike is now open source! AI-powered penetration testing for security professionals. Star on GitHub

Config Hooks

Config hooks allow you to define hook behavior directly in configuration files, running shell commands in response to tool events.

📸 SCREENSHOT: config-hooks-action.png

Config hooks blocking a dangerous command

Overview

Config hooks:

  • Defined in JSON configuration
  • Run shell commands
  • No code required
  • Project-specific customization
  • Quick validation logic

Basic Configuration

cyberstrike.json
{
"hooks": {
"preToolUse": [
{
"matcher": "Bash",
"command": "./scripts/validate-command.sh"
}
]
}
}

Hook Events

PreToolUse

Runs before tool execution:

{
"hooks": {
"preToolUse": [
{
"matcher": "Bash",
"command": "./scripts/validate.sh $TOOL_ARGS"
}
]
}
}

PostToolUse

Runs after tool execution:

{
"hooks": {
"postToolUse": [
{
"matcher": "Write(*)",
"command": "npm run lint --fix $TOOL_FILE"
}
]
}
}

Notification

Runs on events:

{
"hooks": {
"notification": [
{
"type": "error",
"command": "./scripts/notify-slack.sh"
}
]
}
}

Stop

Runs when session stops:

{
"hooks": {
"stop": [
{
"command": "./scripts/cleanup.sh"
}
]
}
}

SessionStart

Runs at session start:

{
"hooks": {
"sessionStart": [
{
"command": "./scripts/init-session.sh"
}
]
}
}

Matcher Patterns

Tool Name

{
"matcher": "Bash"
}

Glob Pattern

{
"matcher": "Write(src/**/*.ts)"
}

Multiple Tools

{
"matcher": "Bash|Write|Edit"
}

All Tools

{
"matcher": "*"
}

Argument Pattern

{
"matcher": "Bash(npm *)"
}

Environment Variables

Hooks receive context via environment variables:

VariableDescription
TOOL_NAMEName of the tool
TOOL_ARGSJSON-encoded arguments
TOOL_FILEFile path (for file tools)
TOOL_COMMANDCommand (for Bash)
TOOL_CONTENTContent (for Write)
SESSION_IDCurrent session ID
WORKING_DIRWorking directory

Using Variables

scripts/validate.sh
#!/bin/bash
ARGS=$(echo "$TOOL_ARGS" | jq -r '.command')
if [[ "$ARGS" == *"rm -rf"* ]]; then
echo "BLOCK: Dangerous command detected"
exit 1
fi
exit 0

Exit Codes

Hook commands control behavior via exit codes:

Exit CodeAction
0Continue execution
1Block execution
2Skip with warning

Example Script

scripts/check-command.sh
#!/bin/bash
# Parse command
CMD="$TOOL_COMMAND"
# Check for dangerous patterns
if [[ "$CMD" =~ (rm -rf|dd if=|mkfs) ]]; then
echo "Blocked: Dangerous command pattern"
exit 1
fi
# Check for sudo
if [[ "$CMD" == sudo* ]]; then
echo "Warning: Sudo command"
exit 2
fi
# Allow
exit 0

Hook Output

Standard Output

Hook stdout is displayed to user:

#!/bin/bash
echo "Validating command..."
# validation logic
echo "Command approved"
exit 0

Standard Error

Hook stderr is logged:

#!/bin/bash
echo "Error: Invalid command" >&2
exit 1

JSON Response

Return structured data:

#!/bin/bash
cat <<EOF
{
"action": "block",
"message": "Command not allowed",
"reason": "Contains dangerous pattern"
}
EOF
exit 1

Conditional Hooks

By File Extension

{
"hooks": {
"postToolUse": [
{
"matcher": "Write(*.ts)",
"command": "npx tsc --noEmit $TOOL_FILE"
},
{
"matcher": "Write(*.py)",
"command": "python -m py_compile $TOOL_FILE"
}
]
}
}

By Directory

{
"hooks": {
"preToolUse": [
{
"matcher": "Write(src/secure/**)",
"command": "./scripts/security-review.sh"
}
]
}
}

Multiple Hooks

Multiple hooks run in order:

{
"hooks": {
"postToolUse": [
{
"matcher": "Write(*.ts)",
"command": "npx eslint --fix $TOOL_FILE"
},
{
"matcher": "Write(*.ts)",
"command": "npx prettier --write $TOOL_FILE"
},
{
"matcher": "Write(*.ts)",
"command": "npx tsc --noEmit $TOOL_FILE"
}
]
}
}

Timeout

Set Timeout

{
"hooks": {
"postToolUse": [
{
"matcher": "Write(*)",
"command": "npm run test",
"timeout": 30000
}
]
}
}

Timeout in milliseconds (default: 10000).

Async Execution

Run in Background

{
"hooks": {
"postToolUse": [
{
"matcher": "*",
"command": "./scripts/log-async.sh &",
"async": true
}
]
}
}

Async hooks don’t block execution.

Examples

Lint on Write

{
"hooks": {
"postToolUse": [
{
"matcher": "Write(*.{ts,js,tsx,jsx})",
"command": "npx eslint --fix $TOOL_FILE && npx prettier --write $TOOL_FILE"
}
]
}
}

Security Validation

{
"hooks": {
"preToolUse": [
{
"matcher": "Bash",
"command": "./scripts/security-check.sh"
},
{
"matcher": "Write(.env*)",
"command": "echo 'BLOCK: Cannot modify .env files' && exit 1"
}
]
}
}

Audit Logging

{
"hooks": {
"postToolUse": [
{
"matcher": "*",
"command": "echo \"$(date -Iseconds) $TOOL_NAME\" >> .cyberstrike/audit.log",
"async": true
}
]
}
}

Auto-Format

{
"hooks": {
"postToolUse": [
{
"matcher": "Write(*.py)",
"command": "black $TOOL_FILE && isort $TOOL_FILE"
},
{
"matcher": "Write(*.go)",
"command": "gofmt -w $TOOL_FILE"
},
{
"matcher": "Write(*.rs)",
"command": "rustfmt $TOOL_FILE"
}
]
}
}

Troubleshooting

Hook Not Running

Check:

  • Matcher pattern is correct
  • Script is executable (chmod +x)
  • Path is correct

Permission Denied

Terminal window
chmod +x ./scripts/validate.sh

Timeout

Increase timeout or optimize script:

{
"timeout": 60000
}

Caution

Long-running hooks can slow down Cyberstrike. Keep hooks fast or run them async.