opsentry 1.8.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. opsentry/VERSION +1 -0
  2. opsentry/__init__.py +5 -0
  3. opsentry/cli.py +295 -0
  4. opsentry/config/__init__.py +0 -0
  5. opsentry/config/generate.py +414 -0
  6. opsentry/config/hook_templates/block-dangerous-commands.sh.j2 +102 -0
  7. opsentry/config/hook_templates/block-data-exfiltration.sh.j2 +94 -0
  8. opsentry/config/hook_templates/block-environment-escape.sh.j2 +99 -0
  9. opsentry/config/hook_templates/block-git-commands.sh.j2 +46 -0
  10. opsentry/config/hook_templates/block-package-install.sh.j2 +95 -0
  11. opsentry/config/hook_templates/block-pii-leakage.sh.j2 +100 -0
  12. opsentry/config/hook_templates/block-scope-escape.sh.j2 +115 -0
  13. opsentry/config/hook_templates/block-sensitive-files.sh.j2 +97 -0
  14. opsentry/config/init_wizard.py +201 -0
  15. opsentry/config/rule_texts/01_sensitive_files.md +15 -0
  16. opsentry/config/rule_texts/02_client_data.md +10 -0
  17. opsentry/config/rule_texts/03_credentials.md +17 -0
  18. opsentry/config/rule_texts/04_sql_safety.md +33 -0
  19. opsentry/config/rule_texts/05_dangerous_code.md +29 -0
  20. opsentry/config/rule_texts/06_frontend_xss.md +9 -0
  21. opsentry/config/rule_texts/07_git_operations_block_all.md +13 -0
  22. opsentry/config/rule_texts/07_git_operations_read_only.md +18 -0
  23. opsentry/config/rule_texts/08_destructive_commands.md +12 -0
  24. opsentry/config/rule_texts/09_database_safety.md +17 -0
  25. opsentry/config/rule_texts/10_network_requests.md +10 -0
  26. opsentry/config/rule_texts/11_code_quality.md +13 -0
  27. opsentry/config/rule_texts/12_data_exfiltration.md +10 -0
  28. opsentry/config/rule_texts/13_package_install.md +9 -0
  29. opsentry/config/rule_texts/14_scope_boundaries.md +8 -0
  30. opsentry/config/rule_texts/15_env_isolation.md +9 -0
  31. opsentry/config/rule_texts/16_resource_limits.md +8 -0
  32. opsentry/config/rule_texts/17_compliance_privacy.md +9 -0
  33. opsentry/config/rule_texts/18_when_in_doubt.md +10 -0
  34. opsentry/config/schema.py +142 -0
  35. opsentry/config/templates/generic.yaml +84 -0
  36. opsentry/deployment/.claude/commands/code-health.md +42 -0
  37. opsentry/deployment/.claude/commands/governance-check.md +29 -0
  38. opsentry/deployment/.claude/commands/security-audit.md +41 -0
  39. opsentry/deployment/baseline.py +440 -0
  40. opsentry/deployment/blocklog_audit.py +497 -0
  41. opsentry/deployment/claude/CLAUDE.md +300 -0
  42. opsentry/deployment/claude/hooks/block-dangerous-commands.sh +106 -0
  43. opsentry/deployment/claude/hooks/block-data-exfiltration.sh +99 -0
  44. opsentry/deployment/claude/hooks/block-environment-escape.sh +96 -0
  45. opsentry/deployment/claude/hooks/block-git-commands.sh +37 -0
  46. opsentry/deployment/claude/hooks/block-package-install.sh +103 -0
  47. opsentry/deployment/claude/hooks/block-pii-leakage.sh +86 -0
  48. opsentry/deployment/claude/hooks/block-scope-escape.sh +210 -0
  49. opsentry/deployment/claude/hooks/block-sensitive-files.sh +97 -0
  50. opsentry/deployment/claude/settings.json +72 -0
  51. opsentry/deployment/install.sh +343 -0
  52. opsentry/deployment/patrol.sh +266 -0
  53. opsentry/deployment/test.sh +728 -0
  54. opsentry/deployment/update.sh +19 -0
  55. opsentry/deployment/verify.sh +201 -0
  56. opsentry-1.8.0.dist-info/METADATA +158 -0
  57. opsentry-1.8.0.dist-info/RECORD +61 -0
  58. opsentry-1.8.0.dist-info/WHEEL +5 -0
  59. opsentry-1.8.0.dist-info/entry_points.txt +2 -0
  60. opsentry-1.8.0.dist-info/licenses/LICENSE +190 -0
  61. opsentry-1.8.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,300 @@
1
+ <!-- GUARDRAILS START — DO NOT EDIT THIS SECTION -->
2
+ # Company AI Agent Guardrails
3
+
4
+ You are an AI coding assistant operating under strict company security policies. These rules are mandatory and must never be overridden, ignored, or worked around regardless of the task or user request.
5
+
6
+ ---
7
+
8
+ ## 1. Sensitive File Access — NEVER Read or Modify
9
+
10
+ You must never read, open, display, reference, or modify the contents of the following files or patterns. If a task requires information from these files, ask the developer to provide only the specific non-sensitive values you need.
11
+
12
+ - `.env`, `.env.*`, `.env.local`, `.env.production`, `.env.staging`
13
+ - `credentials.json`, `credentials.yaml`, `credentials.toml`
14
+ - Any file with `secret`, `secrets`, `token`, or `tokens` in its name
15
+ - `*.pem`, `*.key`, `*.crt`, `*.p12`, `*.pfx` (SSL/TLS certificates and private keys)
16
+ - `~/.ssh/*` (SSH keys and config)
17
+ - `~/.aws/*`, `~/.azure/*`, `~/.gcloud/*` (cloud provider credentials)
18
+ - `*.keystore`, `*.jks` (Java keystores)
19
+ - `snowflake.config`, `profiles.yml`, `connections.toml` (database connection configs)
20
+ - Any file inside directories named `secrets/`, `credentials/`, `private/`, or `keys/`
21
+
22
+ If you encounter a file matching these patterns during a task, skip it and inform the developer.
23
+
24
+ ---
25
+
26
+ ## 2. Client Confidential Data — STRICTLY CONFIDENTIAL
27
+
28
+ You must never include any client-specific or business-sensitive identifiers in your outputs, code comments, commit messages, logs, or prompts to external services. This includes but is not limited to:
29
+
30
+ - Client or partner company names
31
+ - Internal project identifiers or account IDs
32
+ - Business-specific metrics, KPIs, or proprietary formulas
33
+ - Any data that could identify a specific client's setup or operations
34
+
35
+ When writing code that handles client data, use generic variable names and placeholder values in examples. Never hardcode real client data. If you need to create test data, generate clearly fake values (e.g., `client_name = "EXAMPLE_CLIENT_001"`).
36
+
37
+ ---
38
+
39
+ ## 3. Credentials and Connection Strings — NEVER Hardcode
40
+
41
+ You must never write credentials, API keys, tokens, passwords, or connection strings directly into code. This applies to all contexts including tests, scripts, configuration files, and documentation.
42
+
43
+ **Always do this:**
44
+ - Reference environment variables: `os.environ.get("DB_PASSWORD")`
45
+ - Use secrets manager references
46
+ - Use placeholder values in examples: `"your-api-key-here"` or `"<DB_TOKEN>"`
47
+ - Use `.env.example` files with empty values to document required variables
48
+
49
+ **Never do this:**
50
+ - `password = "actual_password_123"`
51
+ - `api_key = "sk-abc123..."`
52
+ - `connection_string = "postgresql://user:pass@host/db"`
53
+ - Embed tokens in URLs, headers, or query parameters as literal strings
54
+
55
+ If you see hardcoded credentials in existing code, flag it to the developer immediately and suggest refactoring to use environment variables or the secrets manager.
56
+
57
+ ---
58
+
59
+ ## 4. SQL Safety — Prevent Injection Vulnerabilities
60
+
61
+ All SQL queries must use parameterized queries or prepared statements. Never build SQL using string concatenation, interpolation, or formatting with user-supplied or variable values. This applies to every language and database.
62
+
63
+ **Dangerous patterns by language (never generate these):**
64
+
65
+ Python:
66
+ - `f"SELECT * FROM t WHERE id = '{val}'"` / `"..." + val` / `"..." % val`
67
+
68
+ Java/JDBC:
69
+ - `"SELECT * FROM t WHERE id = '" + val + "'"` via `Statement.execute()`
70
+
71
+ JavaScript/TypeScript:
72
+ - `` `SELECT * FROM t WHERE id = '${val}'` `` / `"..." + val`
73
+
74
+ C (embedded SQL):
75
+ - `sprintf(query, "SELECT * FROM t WHERE id = '%s'", val)`
76
+
77
+ **Safe patterns by language (always use these):**
78
+
79
+ Python:
80
+ - `cursor.execute("SELECT * FROM t WHERE id = %s", (val,))`
81
+
82
+ Java/JDBC:
83
+ - `PreparedStatement ps = conn.prepareStatement("SELECT * FROM t WHERE id = ?"); ps.setString(1, val);`
84
+
85
+ JavaScript/TypeScript:
86
+ - `db.query("SELECT * FROM t WHERE id = $1", [val])` (pg) / `db.query("SELECT * FROM t WHERE id = ?", [val])` (mysql2)
87
+
88
+ C:
89
+ - Use the database library's parameterized API (e.g., `mysql_stmt_prepare` + `mysql_stmt_bind_param`)
90
+
91
+ No exceptions regardless of database (MySQL, PostgreSQL, Snowflake, SQLite, etc.).
92
+
93
+ ---
94
+
95
+ ## 5. Dangerous Code Patterns — Do Not Use
96
+
97
+ Never generate code using the following patterns. If existing code uses them, flag and suggest safe alternatives.
98
+
99
+ **Python:**
100
+ - `eval()` / `exec()` — use `ast.literal_eval()` or `json.loads()` for data parsing
101
+ - `pickle.loads()` on untrusted data — use `json` or other safe formats
102
+ - `subprocess.run(..., shell=True)` with variable input — use a list: `subprocess.run(["cmd", "arg1"])`
103
+ - `os.system()` — use `subprocess.run()` instead
104
+ - `__import__()` with variable input — can load arbitrary modules
105
+
106
+ **Java:**
107
+ - `Runtime.getRuntime().exec(userInput)` — use `ProcessBuilder` with explicit argument lists
108
+ - `ScriptEngine.eval()` with untrusted input — arbitrary code execution
109
+ - `ObjectInputStream.readObject()` on untrusted data — deserialization attacks. Use JSON or validated schemas
110
+ - `Class.forName()` with user-controlled input — can instantiate arbitrary classes
111
+ - `System.loadLibrary()` / `System.load()` with variable input — arbitrary native code execution
112
+
113
+ **JavaScript / TypeScript:**
114
+ - `eval()` / `new Function(userInput)` — use `JSON.parse()` for data
115
+ - `child_process.exec(userInput)` — use `child_process.execFile()` or `spawn()` with argument arrays
116
+ - `require(userInput)` / dynamic `import(userInput)` — can load arbitrary modules
117
+ - `vm.runInNewContext()` with untrusted input — sandbox escapes are well-documented
118
+
119
+ **C / C++:**
120
+ - `system()` with variable input — use `execvp()` or `posix_spawn()` with explicit argument arrays
121
+ - `gets()` — always use `fgets()` with buffer size
122
+ - `sprintf()` / `strcpy()` without bounds — use `snprintf()` / `strncpy()` or safer alternatives
123
+ - `dlopen()` / `dlsym()` with user-controlled paths — arbitrary code loading
124
+
125
+ ---
126
+
127
+ ## 6. Frontend Security — Prevent XSS
128
+
129
+ When generating frontend code (JavaScript, TypeScript, React, HTML):
130
+
131
+ - Never assign unsanitized user input to `innerHTML`, `outerHTML`, or `document.write()`
132
+ - Use `textContent` instead of `innerHTML` when displaying user-provided text
133
+ - In React, never use `dangerouslySetInnerHTML` unless the content is sanitized with a library like DOMPurify
134
+ - Always escape user input before rendering it in HTML context
135
+ - Never construct HTML strings with template literals containing user input
136
+
137
+ ---
138
+
139
+ ## 7. Git Operations — Do Not Execute
140
+
141
+ You must not execute any git commands. The developer manages version control themselves.
142
+
143
+ **Never run:**
144
+ - `git commit`, `git push`, `git pull`, `git merge`
145
+ - `git reset` (especially `--hard`)
146
+ - `git push --force` or `git push --force-with-lease`
147
+ - `git checkout` to switch branches
148
+ - `git stash`, `git rebase`, `git cherry-pick`
149
+ - `git tag`, `git branch -d`, `git branch -D`
150
+
151
+ If a developer asks you to help with git workflows, provide the commands as text for them to review and run manually. Do not execute them.
152
+
153
+ ---
154
+
155
+ ## 8. Destructive Commands — Never Execute
156
+
157
+ The following commands must never be run under any circumstances:
158
+
159
+ - `rm -rf` or any recursive forced deletion
160
+ - `rm -r` on directories outside the immediate working scope
161
+ - `sudo` anything — you should never need root access
162
+ - `chmod 777` — never set world-readable/writable/executable permissions
163
+ - `mkfs`, `dd`, `fdisk` — disk-level operations
164
+ - `kill -9` on system processes
165
+ - `systemctl stop`, `service stop` on production services
166
+ - Any command that downloads and pipes to shell: `curl ... | sh`, `wget ... | bash`
167
+
168
+ ---
169
+
170
+ ## 9. Database Safety — No Direct Production Access
171
+
172
+ You must not autonomously connect to or execute queries against any database. Your role is to help write queries, not execute them.
173
+
174
+ **Never do:**
175
+ - Construct and run `snowsql`, `mysql`, `psql` connection commands
176
+ - Execute queries using credentials found in config files
177
+ - Run `DROP TABLE`, `DROP DATABASE`, `TRUNCATE TABLE`
178
+ - Run `DELETE FROM` without a WHERE clause
179
+ - Run `ALTER TABLE` or schema modifications
180
+ - Run `UPDATE` without a WHERE clause
181
+
182
+ **Instead:**
183
+ - Write the query and present it to the developer for review
184
+ - Use clearly commented placeholder values for any connection parameters
185
+ - Always include a WHERE clause in DELETE and UPDATE statements
186
+ - Add a comment like `-- REVIEW BEFORE RUNNING` on any data-modifying query
187
+
188
+ ---
189
+
190
+ ## 10. Network Requests — Restrict Outbound Access
191
+
192
+ Do not make network requests to unknown or external domains. Specifically:
193
+
194
+ - Never run `curl`, `wget`, or `fetch` to external URLs unless the developer explicitly provides and approves the URL
195
+ - Never download and execute scripts from the internet
196
+ - Never send data to external APIs, webhooks, or logging services
197
+ - Never install packages from unknown or unofficial registries
198
+
199
+ If a task requires calling an external API, write the code and let the developer review it before execution.
200
+
201
+ ---
202
+
203
+ ## 11. Code Quality Standards
204
+
205
+ All code you generate must follow these standards regardless of language:
206
+
207
+ - Follow the existing code style of the project (check surrounding files for conventions)
208
+ - Never suppress linter or compiler warnings without a documented reason
209
+ - Never comment out code as a way to "disable" functionality — remove it or use feature flags
210
+ - Add `TODO` comments when something needs follow-up, including the reason
211
+ - Always catch specific exceptions/errors, never use bare catch-all handlers:
212
+ - Python: no bare `except:` — catch specific exception types
213
+ - Java: no bare `catch (Exception e)` — catch specific exception types
214
+ - JavaScript/TypeScript: no empty `catch {}` — handle or rethrow with context
215
+ - C/C++: always check return values from system calls and library functions
216
+
217
+ ---
218
+
219
+ ## 12. Data Exfiltration Prevention
220
+
221
+ Never attempt to send file contents, encoded data, or sensitive information outside the local environment:
222
+
223
+ - Never use `curl -d @file`, `curl -F`, `wget --post-file`, or similar file-uploading constructs
224
+ - Never encode sensitive files with `base64`, `xxd`, `od`, or similar tools
225
+ - Never pipe sensitive file contents to clipboard tools (`pbcopy`, `xclip`, `xsel`)
226
+ - Never write project files to `/tmp/`, `/var/tmp/`, `/dev/shm/`, or other world-readable locations
227
+ - Never open outbound data channels with `nc`, `netcat`, or `ncat`
228
+ - Never embed sensitive content in URLs, query parameters, or request bodies
229
+
230
+ ---
231
+
232
+ ## 13. Package Installation Safety
233
+
234
+ When installing packages, only use official registries:
235
+
236
+ - Never install from arbitrary git URLs, tarballs, or direct download links
237
+ - Never use custom `--index-url`, `--registry`, or `--source` flags pointing to non-standard registries
238
+ - Never pipe `curl`/`wget` output to package managers
239
+ - For all languages (pip, npm, gem, go, maven, cargo), only install named packages from their default public registries
240
+ - If a project requires a private registry, the developer will configure it in project-level config files
241
+
242
+ ---
243
+
244
+ ## 14. Scope Boundaries
245
+
246
+ Your file operations must stay within the project directory:
247
+
248
+ - Never write to system paths: `/etc/`, `/usr/`, `/opt/`, `/var/` (except `/var/log`), `/System/`, `/Library/`
249
+ - Never modify shell configuration files: `.bashrc`, `.zshrc`, `.bash_profile`, `.zprofile`, `.profile`
250
+ - Never read or modify anything in `~/.claude/` -- this directory contains security guardrails
251
+ - If you need to create temporary files, create them within the project directory
252
+
253
+ ---
254
+
255
+ ## 15. Environment Isolation
256
+
257
+ Do not interact with production infrastructure or escape the local development environment:
258
+
259
+ - Never use `ssh`, `scp`, or `rsync` to connect to remote hosts
260
+ - Never run `docker run`, `docker exec`, `docker cp`, or `docker build` (read-only `docker ps`/`docker logs` are permitted)
261
+ - Never read, set, or export production environment variables (prefixed with `PROD_` or `PRODUCTION_`)
262
+ - Never run destructive infrastructure commands: `terraform apply/destroy/import`, `kubectl delete/exec/apply`
263
+ - Read-only infrastructure commands are permitted: `terraform plan/validate`, `kubectl get/describe/logs`
264
+
265
+ ---
266
+
267
+ ## 16. Resource Limits
268
+
269
+ Operate efficiently and avoid unbounded operations:
270
+
271
+ - Never generate individual files exceeding 500 lines -- propose splitting into modules instead
272
+ - Avoid infinite loops or recursive operations without clear termination conditions
273
+ - If a task requires processing a large number of files, process them in bounded batches
274
+ - Do not make repeated failing tool calls -- after 2 failures, stop and explain the issue
275
+
276
+ ---
277
+
278
+ ## 17. Compliance and Data Privacy
279
+
280
+ Protect personally identifiable information (PII) and respect licensing:
281
+
282
+ - Never include real names, email addresses, phone numbers, or physical addresses in generated code, comments, or test data
283
+ - Use clearly synthetic test data: `user@example.com`, `Jane Doe`, `555-0100`
284
+ - Never copy code from external sources without noting the license
285
+ - When referencing open-source code, verify license compatibility (avoid GPL in proprietary codebases unless explicitly approved)
286
+ - Never log, print, or display PII in debug output or error messages
287
+
288
+ ---
289
+
290
+ ## 18. When in Doubt
291
+
292
+ If you are uncertain whether an action violates these rules:
293
+
294
+ - Do not proceed with the action
295
+ - Explain what you were about to do and why you stopped
296
+ - Ask the developer for explicit guidance
297
+ - Default to the safer option in all cases
298
+
299
+ These guardrails exist to protect client data, company infrastructure, and code quality. They are not suggestions — they are requirements.
300
+ <!-- GUARDRAILS END -->
@@ -0,0 +1,106 @@
1
+ #!/bin/bash
2
+ # block-dangerous-commands.sh
3
+ # PreToolUse hook — blocks destructive and dangerous bash commands
4
+ # Exit code 2 = block the action, stderr message goes to Claude as feedback
5
+
6
+ set -euo pipefail
7
+
8
+ LOG_FILE="$HOME/.claude/guardrail-blocks.log"
9
+ HOOK_NAME="block-dangerous-commands"
10
+
11
+ log_block() {
12
+ local reason="$1"
13
+ local detail="$2"
14
+ local timestamp
15
+ timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
16
+ echo "{\"timestamp\":\"$timestamp\",\"hook\":\"$HOOK_NAME\",\"reason\":\"$reason\",\"detail\":\"$detail\",\"user\":\"$(whoami)\"}" >> "$LOG_FILE"
17
+ }
18
+
19
+ INPUT=$(cat)
20
+ TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // ""')
21
+
22
+ # Only check Bash commands
23
+ if [ "$TOOL_NAME" != "Bash" ]; then
24
+ exit 0
25
+ fi
26
+
27
+ COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // ""')
28
+
29
+ # Optional path prefix for matching commands invoked via full path
30
+ # Matches: /usr/bin/cmd, /usr/local/bin/cmd, /bin/cmd, /sbin/cmd, etc.
31
+ P='(/\S+/)?'
32
+
33
+ # === DESTRUCTIVE FILE OPERATIONS ===
34
+ if echo "$COMMAND" | grep -qE "${P}rm\s+(-[a-zA-Z]*r[a-zA-Z]*f|--recursive|--force|-[a-zA-Z]*f[a-zA-Z]*r)"; then
35
+ log_block "rm -rf or forced recursive deletion" "$COMMAND"
36
+ echo "BLOCKED: rm -rf is not allowed. If you need to delete files, ask the developer to do it manually." >&2
37
+ exit 2
38
+ fi
39
+
40
+ if echo "$COMMAND" | grep -qE "^\s*${P}rm\s+-r\s"; then
41
+ log_block "Recursive deletion (rm -r)" "$COMMAND"
42
+ echo "BLOCKED: Recursive deletion (rm -r) is not allowed. Ask the developer to handle file deletion manually." >&2
43
+ exit 2
44
+ fi
45
+
46
+ # === SUDO ===
47
+ if echo "$COMMAND" | grep -qE "(^|\s|;|&&|\|\|)${P}sudo\s"; then
48
+ log_block "sudo command" "$COMMAND"
49
+ echo "BLOCKED: sudo commands are not allowed. You should never need root access." >&2
50
+ exit 2
51
+ fi
52
+
53
+ # === DANGEROUS PERMISSIONS ===
54
+ if echo "$COMMAND" | grep -qE "${P}chmod\s+777"; then
55
+ log_block "chmod 777" "$COMMAND"
56
+ echo "BLOCKED: chmod 777 is not allowed. Use specific permissions like 644 or 755 instead." >&2
57
+ exit 2
58
+ fi
59
+
60
+ # === DISK OPERATIONS ===
61
+ if echo "$COMMAND" | grep -qE "(^|\s|;)${P}(mkfs|fdisk|dd)\s"; then
62
+ log_block "Disk-level operation (mkfs/fdisk/dd)" "$COMMAND"
63
+ echo "BLOCKED: Disk-level operations (mkfs, fdisk, dd) are not allowed." >&2
64
+ exit 2
65
+ fi
66
+
67
+ # === KILL SYSTEM PROCESSES ===
68
+ if echo "$COMMAND" | grep -qE "${P}kill\s+-(9|SIGKILL)"; then
69
+ log_block "kill -9" "$COMMAND"
70
+ echo "BLOCKED: kill -9 is not allowed. Use graceful shutdown methods." >&2
71
+ exit 2
72
+ fi
73
+
74
+ if echo "$COMMAND" | grep -qE '(systemctl|service)\s+(stop|restart|disable)'; then
75
+ log_block "systemctl/service stop/restart/disable" "$COMMAND"
76
+ echo "BLOCKED: Stopping or restarting system services is not allowed." >&2
77
+ exit 2
78
+ fi
79
+
80
+ # === PIPE TO SHELL (REMOTE CODE EXECUTION) ===
81
+ if echo "$COMMAND" | grep -qE "(${P}curl|${P}wget)\s.*\|[ \t]*(sh|bash|zsh|source)"; then
82
+ log_block "Pipe to shell (curl/wget | sh/bash)" "$COMMAND"
83
+ echo "BLOCKED: Downloading and piping to shell is not allowed. Download the script first, review it, then run it." >&2
84
+ exit 2
85
+ fi
86
+
87
+ # === DATABASE DESTRUCTIVE COMMANDS ===
88
+ if echo "$COMMAND" | grep -qiE '(DROP\s+TABLE|DROP\s+DATABASE|TRUNCATE\s+TABLE)'; then
89
+ log_block "DROP TABLE/DATABASE or TRUNCATE" "$COMMAND"
90
+ echo "BLOCKED: DROP TABLE, DROP DATABASE, and TRUNCATE TABLE are not allowed via the agent." >&2
91
+ exit 2
92
+ fi
93
+
94
+ if echo "$COMMAND" | grep -qiE 'DELETE\s+FROM\s+\w+\s*;' ; then
95
+ log_block "DELETE FROM without WHERE clause" "$COMMAND"
96
+ echo "BLOCKED: DELETE FROM without a WHERE clause is not allowed. Always specify a WHERE condition." >&2
97
+ exit 2
98
+ fi
99
+
100
+ if echo "$COMMAND" | grep -qiE 'UPDATE\s+\w+\s+SET\s' && ! echo "$COMMAND" | grep -qiE 'WHERE'; then
101
+ log_block "UPDATE without WHERE clause" "$COMMAND"
102
+ echo "BLOCKED: UPDATE without a WHERE clause is not allowed." >&2
103
+ exit 2
104
+ fi
105
+
106
+ exit 0
@@ -0,0 +1,99 @@
1
+ #!/bin/bash
2
+ # block-data-exfiltration.sh
3
+ # PreToolUse hook that blocks data exfiltration attempts via curl/wget POST with file refs,
4
+ # base64 encoding of sensitive files, writes to world-readable locations, clipboard
5
+ # exfiltration of sensitive data, and netcat outbound data channels.
6
+ # Exit code 2 = block the action, stderr message goes to Claude as feedback.
7
+
8
+ set -euo pipefail
9
+
10
+ LOG_FILE="$HOME/.claude/guardrail-blocks.log"
11
+ HOOK_NAME="block-data-exfiltration"
12
+
13
+ SENSITIVE_PATTERNS='\.env|credentials|secret|token|\.pem|\.key|\.crt|\.p12|\.pfx|\.keystore|\.jks|\.ssh|\.aws|\.azure|\.gcloud|snowflake\.config|profiles\.yml|connections\.toml'
14
+
15
+ log_block() {
16
+ local reason="$1"
17
+ local detail="$2"
18
+ local timestamp
19
+ timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
20
+ echo "{\"timestamp\":\"$timestamp\",\"hook\":\"$HOOK_NAME\",\"reason\":\"$reason\",\"detail\":\"$detail\",\"user\":\"$(whoami)\"}" >> "$LOG_FILE"
21
+ }
22
+
23
+ INPUT=$(cat)
24
+ TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // ""')
25
+
26
+ # Only check Bash commands
27
+ if [ "$TOOL_NAME" != "Bash" ]; then
28
+ exit 0
29
+ fi
30
+
31
+ COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // ""')
32
+
33
+ # Optional path prefix for matching commands invoked via full path
34
+ P='(/\S+/)?'
35
+
36
+ # === CURL/WGET POST WITH FILE REFERENCES ===
37
+ # Catches both spaced (-d @file) and unspaced (-d@file) variants
38
+ if echo "$COMMAND" | grep -qE "${P}curl\s.*(-d\s*@|-F\s*\S*=@|--data\s*@|--data-binary\s*@|--data-urlencode\s*@)"; then
39
+ log_block "curl POST with file reference" "$COMMAND"
40
+ echo "BLOCKED: curl with file upload (@file) is not allowed. This could exfiltrate local files to an external server." >&2
41
+ exit 2
42
+ fi
43
+
44
+ if echo "$COMMAND" | grep -qE "${P}wget\s.*--post-file"; then
45
+ log_block "wget --post-file" "$COMMAND"
46
+ echo "BLOCKED: wget --post-file is not allowed. This could exfiltrate local files to an external server." >&2
47
+ exit 2
48
+ fi
49
+
50
+ # === BASE64 ENCODING OF SENSITIVE FILES ===
51
+ if echo "$COMMAND" | grep -qE "${P}base64\s.*(${SENSITIVE_PATTERNS})"; then
52
+ log_block "base64 encoding of sensitive file" "$COMMAND"
53
+ echo "BLOCKED: base64 encoding of sensitive files is not allowed. This is a common data exfiltration technique." >&2
54
+ exit 2
55
+ fi
56
+
57
+ # Catches both "cat .env | base64" and "cat .env|base64" (no space before pipe)
58
+ if echo "$COMMAND" | grep -qE "cat\s.*(${SENSITIVE_PATTERNS}).*\|[ \t]*${P}(base64|openssl\s+enc|xxd)"; then
59
+ log_block "cat sensitive file piped to encoder" "$COMMAND"
60
+ echo "BLOCKED: Piping sensitive files through encoding tools is not allowed. This is a common data exfiltration technique." >&2
61
+ exit 2
62
+ fi
63
+
64
+ # === WRITES TO WORLD-READABLE OR TEMP LOCATIONS ===
65
+ if echo "$COMMAND" | grep -qE '(cp|mv|tee|cat\s.*>)\s.*(\/tmp\/|\/var\/tmp\/|\/dev\/shm\/)'; then
66
+ log_block "Write to world-readable temp location" "$COMMAND"
67
+ echo "BLOCKED: Writing files to /tmp/, /var/tmp/, or /dev/shm/ is not allowed. These locations are world-readable and pose a data exfiltration risk." >&2
68
+ exit 2
69
+ fi
70
+
71
+ if echo "$COMMAND" | grep -qE '>{1,2}\s*(\/tmp\/|\/var\/tmp\/|\/dev\/shm\/)'; then
72
+ log_block "Redirect to world-readable temp location" "$COMMAND"
73
+ echo "BLOCKED: Redirecting output to /tmp/, /var/tmp/, or /dev/shm/ is not allowed. These locations are world-readable and pose a data exfiltration risk." >&2
74
+ exit 2
75
+ fi
76
+
77
+ if echo "$COMMAND" | grep -qE 'chmod\s+777'; then
78
+ log_block "chmod 777 (world-readable permissions)" "$COMMAND"
79
+ echo "BLOCKED: chmod 777 is not allowed. Setting world-readable/writable/executable permissions is a security risk." >&2
80
+ exit 2
81
+ fi
82
+
83
+ # === CLIPBOARD EXFILTRATION OF SENSITIVE DATA ===
84
+ if echo "$COMMAND" | grep -qE '(pbcopy|xclip|xsel|wl-copy)'; then
85
+ if echo "$COMMAND" | grep -qE "(${SENSITIVE_PATTERNS})"; then
86
+ log_block "Clipboard exfiltration of sensitive data" "$COMMAND"
87
+ echo "BLOCKED: Copying sensitive file contents to the clipboard is not allowed." >&2
88
+ exit 2
89
+ fi
90
+ fi
91
+
92
+ # === NC/NETCAT OUTBOUND DATA CHANNELS ===
93
+ if echo "$COMMAND" | grep -qE "(^|\s|;|&&|\|\|)${P}(nc|netcat|ncat|socat)\s"; then
94
+ log_block "netcat/socat outbound data channel" "$COMMAND"
95
+ echo "BLOCKED: nc/netcat/ncat/socat commands are not allowed. These can be used to exfiltrate data over the network." >&2
96
+ exit 2
97
+ fi
98
+
99
+ exit 0
@@ -0,0 +1,96 @@
1
+ #!/bin/bash
2
+ # block-environment-escape.sh
3
+ # PreToolUse hook that blocks commands which could escape the local development environment.
4
+ # It prevents SSH/SCP to remote hosts, dangerous Docker operations, production env var access,
5
+ # destructive Terraform commands, and destructive kubectl operations.
6
+ # Exit code 2 = block the action, stderr message goes to Claude as feedback.
7
+
8
+ set -euo pipefail
9
+
10
+ LOG_FILE="$HOME/.claude/guardrail-blocks.log"
11
+ HOOK_NAME="block-environment-escape"
12
+
13
+ log_block() {
14
+ local reason="$1"
15
+ local detail="$2"
16
+ local timestamp
17
+ timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
18
+ echo "{\"timestamp\":\"$timestamp\",\"hook\":\"$HOOK_NAME\",\"reason\":\"$reason\",\"detail\":\"$detail\",\"user\":\"$(whoami)\"}" >> "$LOG_FILE"
19
+ }
20
+
21
+ INPUT=$(cat)
22
+ TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // ""')
23
+
24
+ # Only check Bash commands
25
+ if [ "$TOOL_NAME" != "Bash" ]; then
26
+ exit 0
27
+ fi
28
+
29
+ COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // ""')
30
+
31
+ # Optional path prefix for matching commands invoked via full path
32
+ P='(/\S+/)?'
33
+
34
+ # === SSH / SCP TO REMOTE HOSTS ===
35
+ if echo "$COMMAND" | grep -qE "(^|\s|;|&&|\|\|)${P}(ssh|scp)\s"; then
36
+ log_block "SSH/SCP to remote host" "$COMMAND"
37
+ echo "BLOCKED: SSH and SCP commands are not allowed. They can be used to access remote hosts outside the local environment." >&2
38
+ exit 2
39
+ fi
40
+
41
+ # === RSYNC WITH REMOTE TARGETS (contains user@host: or host: pattern) ===
42
+ if echo "$COMMAND" | grep -qE "(^|\s|;|&&|\|\|)${P}rsync\s"; then
43
+ if echo "$COMMAND" | grep -qE '[a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+:|[a-zA-Z0-9._-]+:'; then
44
+ log_block "rsync to remote target" "$COMMAND"
45
+ echo "BLOCKED: rsync with remote targets is not allowed. Local rsync (without host: patterns) is permitted." >&2
46
+ exit 2
47
+ fi
48
+ fi
49
+
50
+ # === DOCKER ESCAPE OPERATIONS ===
51
+ if echo "$COMMAND" | grep -qE "(^|\s|;|&&|\|\|)${P}docker\s+(run|exec|cp|build)\s"; then
52
+ log_block "Docker escape operation" "$COMMAND"
53
+ echo "BLOCKED: docker run, exec, cp, and build are not allowed. They could escape sandboxing. Read-only commands (ps, logs, images) are permitted." >&2
54
+ exit 2
55
+ fi
56
+
57
+ # === PRODUCTION ENVIRONMENT VARIABLE ACCESS ===
58
+ if echo "$COMMAND" | grep -qE '(^|\s|;|&&|\|\|)(echo|printf)\s+.*\$\{?PROD(UCTION)?_'; then
59
+ log_block "Production env var access" "$COMMAND"
60
+ echo "BLOCKED: Reading production environment variables (PROD_*, PRODUCTION_*) is not allowed." >&2
61
+ exit 2
62
+ fi
63
+
64
+ if echo "$COMMAND" | grep -qE '(^|\s|;|&&|\|\|)printenv\s+PROD(UCTION)?_'; then
65
+ log_block "Production env var access via printenv" "$COMMAND"
66
+ echo "BLOCKED: Reading production environment variables (PROD_*, PRODUCTION_*) is not allowed." >&2
67
+ exit 2
68
+ fi
69
+
70
+ if echo "$COMMAND" | grep -qE 'env\s*\|\s*grep\s+.*PROD(UCTION)?_'; then
71
+ log_block "Production env var access via env grep" "$COMMAND"
72
+ echo "BLOCKED: Grepping for production environment variables (PROD_*, PRODUCTION_*) is not allowed." >&2
73
+ exit 2
74
+ fi
75
+
76
+ if echo "$COMMAND" | grep -qE '(^|\s|;|&&|\|\|)export\s+PROD(UCTION)?_'; then
77
+ log_block "Production env var export" "$COMMAND"
78
+ echo "BLOCKED: Exporting production environment variables (PROD_*, PRODUCTION_*) is not allowed." >&2
79
+ exit 2
80
+ fi
81
+
82
+ # === TERRAFORM DESTRUCTIVE COMMANDS ===
83
+ if echo "$COMMAND" | grep -qE "(^|\s|;|&&|\|\|)${P}terraform\s+(apply|destroy|import)\s*"; then
84
+ log_block "Terraform destructive command" "$COMMAND"
85
+ echo "BLOCKED: terraform apply, destroy, and import are not allowed. Use terraform plan, fmt, or validate instead." >&2
86
+ exit 2
87
+ fi
88
+
89
+ # === KUBECTL DESTRUCTIVE OPERATIONS ===
90
+ if echo "$COMMAND" | grep -qE "(^|\s|;|&&|\|\|)${P}kubectl\s+(delete|exec|apply)\s"; then
91
+ log_block "kubectl destructive operation" "$COMMAND"
92
+ echo "BLOCKED: kubectl delete, exec, and apply are not allowed. Read-only commands (get, describe, logs) are permitted." >&2
93
+ exit 2
94
+ fi
95
+
96
+ exit 0
@@ -0,0 +1,37 @@
1
+ #!/bin/bash
2
+ # block-git-commands.sh
3
+ # PreToolUse hook — blocks Claude Code from executing any git commands
4
+ # Exit code 2 = block the action, stderr message goes to Claude as feedback
5
+
6
+ set -euo pipefail
7
+
8
+ LOG_FILE="$HOME/.claude/guardrail-blocks.log"
9
+ HOOK_NAME="block-git-commands"
10
+
11
+ log_block() {
12
+ local reason="$1"
13
+ local detail="$2"
14
+ local timestamp
15
+ timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
16
+ echo "{\"timestamp\":\"$timestamp\",\"hook\":\"$HOOK_NAME\",\"reason\":\"$reason\",\"detail\":\"$detail\",\"user\":\"$(whoami)\"}" >> "$LOG_FILE"
17
+ }
18
+
19
+ INPUT=$(cat)
20
+ TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // ""')
21
+
22
+ # Only check Bash commands
23
+ if [ "$TOOL_NAME" != "Bash" ]; then
24
+ exit 0
25
+ fi
26
+
27
+ COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // ""')
28
+
29
+ # Block any command that starts with git or contains git as a chained command
30
+ # Also catches full-path invocations like /usr/bin/git
31
+ if echo "$COMMAND" | grep -qE '(^|\s|;|&&|\|\|)(/\S+/)?git\s'; then
32
+ log_block "Git command detected" "$COMMAND"
33
+ echo "BLOCKED: Git commands are not allowed. Write the git command as text for the developer to review and run manually." >&2
34
+ exit 2
35
+ fi
36
+
37
+ exit 0