Guide Origin: Official | ArcKit Version: [VERSION]
ArcKit includes three security hooks that provide layered protection against accidental secret exposure during Claude Code sessions. These hooks run automatically and require no manual configuration.
The security hooks implement defence in depth with three complementary layers:
| Layer | Hook | Hook Type | Trigger | Purpose |
|---|---|---|---|---|
| 1 | secret-detection.py |
UserPromptSubmit | Every user message | Catches secrets pasted into prompts |
| 2 | file-protection.py |
PreToolUse (Edit|Write) | File edit/write operations | Blocks writes to sensitive file paths |
| 3 | secret-file-scanner.py |
PreToolUse (Edit|Write) | File edit/write operations | Scans content being written for embedded secrets |
-
Layer 1 — Prompt scanning: Before your message reaches the model,
secret-detection.pyscans the prompt text for known secret patterns (API keys, tokens, passwords, connection strings). If a secret is detected, the message is blocked before it is sent. -
Layer 2 — Path protection: When Claude attempts to edit or write a file,
file-protection.pychecks whether the target file path is sensitive (environment files, credential stores, private keys, lock files). Protected files are blocked regardless of content. -
Layer 3 — Content scanning: For files that pass the path check,
secret-file-scanner.pyexamines the actual content being written for secret patterns. This catches cases where a secret is embedded in an otherwise safe file path.
Scans user prompts for:
- Key-value secrets:
pwd=,api_key=,auth_token=,api_secret= - Provider-specific tokens: OpenAI (
sk-), Anthropic (sk-ant-), GitHub (ghp_,gho_,ghs_), AWS (AKIA), Notion (ntn_), Atlassian (ATATT), Slack (xox), Google (AIza) - Bearer tokens:
bearer <value> - Connection strings:
mongodb://,postgres://,mysql://,redis://with credentials - PEM private keys:
-----BEGIN ... KEY-----headers - High-entropy credentials: Long base64-like strings assigned to key/secret variables
Example block:
$ echo '{"userPrompt": "Use this key sk-ant-abc123def456ghi789"}' \
| python3 arckit-claude/hooks/secret-detection.py
# Output: {"decision": "block", "reason": "Warning: Potential secrets detected: ..."}
Blocks writes to:
- Environment files:
.env,.env.local,.env.production,.env.development - Lock files:
package-lock.json,yarn.lock,pnpm-lock.yaml,Gemfile.lock,poetry.lock,Cargo.lock - Version control:
.git/ - Credential directories:
.aws/,.ssh/,.gnupg/ - Secret files:
credentials,credentials.json,secrets.json,secrets.yaml,secrets.yml,.secrets - Private keys:
*.pem,*.key,*.p12,*.pfx,id_rsa,id_ed25519,id_ecdsa - Auth config files:
.npmrc,.pypirc,.netrc - Files with sensitive keywords: filenames containing terms like "credential", "api-key", etc.
Example block:
$ echo '{"tool_name": "Write", "tool_input": {"file_path": ".env", "content": "DB_HOST=localhost"}}' \
| python3 arckit-claude/hooks/file-protection.py
# Output: {"decision": "block", "reason": "Protected: Protected file: .env\nFile: .env\n..."}
Scans the content of files being written or edited using the same pattern library as secret-detection.py. This catches secrets that might be embedded in source code, configuration files, or documentation.
Example block:
$ echo '{"tool_name": "Write", "tool_input": {"file_path": "config.py", "content": "db_host=localhost"}}' \
| python3 arckit-claude/hooks/secret-file-scanner.py
# Output: no output (safe content passes through)
To allow edits to files that would normally be blocked by file-protection.py, you have three options:
1. Add to ALLOWED_EXCEPTIONS — for specific filenames that are legitimate security tools:
ALLOWED_EXCEPTIONS = [
".secrets.baseline",
".pre-commit-config.yaml",
"secret-detection.py",
"secret-file-scanner.py",
"your-new-exception.py", # Add here
]2. Add to ALLOWED_DIRECTORIES — for directories containing documentation or tool files that discuss secrets:
ALLOWED_DIRECTORIES = [
"arckit-claude/commands/",
"arckit-claude/templates/",
"arckit-claude/agents/",
"arckit-claude/hooks/",
"docs/",
".arckit/templates/",
"your-project/docs/", # Add here
]To prevent secret-file-scanner.py from scanning certain files (e.g., documentation that legitimately discusses secret formats), add a regex to SKIP_PATTERNS:
SKIP_PATTERNS = [
r"\.pre-commit-config\.yaml$",
r"secret-detection\.py$",
r"secret-file-scanner\.py$",
r"file-protection\.py$",
r"\.secrets\.baseline$",
r"arckit-claude/commands/.*\.md$",
r"arckit-claude/templates/.*\.md$",
r"docs/.*\.md$",
r"CHANGELOG\.md$",
r"README\.md$",
r"your-custom-pattern\.md$", # Add here
]You can test each hook by piping JSON to stdin. All hooks handle empty input gracefully.
echo '{"tool_name": "Write", "tool_input": {"file_path": ".env", "content": "VALUE=abc"}}' \
| python3 arckit-claude/hooks/file-protection.pyExpected: {"decision": "block", ...}
echo '{"userPrompt": "Use this key sk-ant-abc123def456ghi789"}' \
| python3 arckit-claude/hooks/secret-detection.pyExpected: {"decision": "block", ...}
echo '{"tool_name": "Write", "tool_input": {"file_path": "test.md", "content": "pwd=hunter2"}}' \
| python3 arckit-claude/hooks/secret-file-scanner.pyExpected: {"decision": "block", ...}
echo '{"tool_name": "Write", "tool_input": {"file_path": "arckit-claude/commands/research.md", "content": "Use API key format: sk-xxx"}}' \
| python3 arckit-claude/hooks/secret-file-scanner.pyExpected: no output (exit code 0, file is in a skip pattern)
echo '' | python3 arckit-claude/hooks/file-protection.py
echo '' | python3 arckit-claude/hooks/secret-detection.py
echo '' | python3 arckit-claude/hooks/secret-file-scanner.pyExpected: no output or {} (exit code 0 for all)