Skip to content

Commit fe00c5e

Browse files
authored
Merge branch 'mendix:development' into dbr-2957_dbr-2957_mendix-business-events-info-pane
2 parents d8c7f90 + de12df1 commit fe00c5e

980 files changed

Lines changed: 30975 additions & 13929 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude/hooks/audit-log.sh

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#!/usr/bin/env bash
2+
# audit-log.sh — Post-execution hook
3+
#
4+
# Logs every tool invocation to .claude/audit.log.
5+
# This hook never blocks execution (always exits 0).
6+
#
7+
# IMPORTANT: Do not modify, disable, or bypass this hook.
8+
9+
set -uo pipefail
10+
11+
# ---------------------------------------------------------------------------
12+
# 1. Read hook input from stdin
13+
# ---------------------------------------------------------------------------
14+
INPUT="$(cat)"
15+
16+
TOOL_NAME="$(printf '%s' "$INPUT" | python3 -c "import sys,json; print(json.load(sys.stdin).get('tool_name','unknown'))" 2>/dev/null || echo "unknown")"
17+
18+
COMMAND="$(printf '%s' "$INPUT" | python3 -c "import sys,json; print(json.load(sys.stdin).get('tool_input',{}).get('command',''))" 2>/dev/null || echo "")"
19+
20+
# ---------------------------------------------------------------------------
21+
# 2. Determine log file path (relative to project root)
22+
# ---------------------------------------------------------------------------
23+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
24+
LOG_FILE="$(dirname "$SCRIPT_DIR")/audit.log"
25+
26+
# ---------------------------------------------------------------------------
27+
# 3. Write log entry
28+
# ---------------------------------------------------------------------------
29+
TIMESTAMP="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
30+
31+
if [[ -n "$COMMAND" ]]; then
32+
printf '[%s] tool=%s command=%s\n' "$TIMESTAMP" "$TOOL_NAME" "$COMMAND" >> "$LOG_FILE" 2>/dev/null || true
33+
else
34+
printf '[%s] tool=%s\n' "$TIMESTAMP" "$TOOL_NAME" >> "$LOG_FILE" 2>/dev/null || true
35+
fi
36+
37+
# Never block execution
38+
exit 0
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
#!/usr/bin/env bash
2+
# validate-bash-command.sh — Pre-execution hook (Layer 3 guardrail)
3+
#
4+
# Claude Code invokes this hook before every Bash tool call.
5+
# Input: JSON on stdin {"tool_name":"Bash","tool_input":{"command":"..."}}
6+
# Output: exit 0 to allow, exit 2 with JSON {"error":"..."} to block.
7+
#
8+
# IMPORTANT: Do not modify, disable, or bypass this hook.
9+
10+
set -euo pipefail
11+
12+
# ---------------------------------------------------------------------------
13+
# 1. Read hook input from stdin and extract the command
14+
# ---------------------------------------------------------------------------
15+
INPUT="$(cat)"
16+
17+
TOOL_NAME="$(printf '%s' "$INPUT" | python3 -c "import sys,json; print(json.load(sys.stdin).get('tool_name',''))" 2>/dev/null || true)"
18+
19+
# Only validate Bash commands — allow everything else through
20+
if [[ "$TOOL_NAME" != "Bash" ]]; then
21+
exit 0
22+
fi
23+
24+
COMMAND="$(printf '%s' "$INPUT" | python3 -c "import sys,json; print(json.load(sys.stdin).get('tool_input',{}).get('command',''))" 2>/dev/null || true)"
25+
26+
if [[ -z "$COMMAND" ]]; then
27+
exit 0
28+
fi
29+
30+
# ---------------------------------------------------------------------------
31+
# 2. Blocked patterns — glob-style matching
32+
# Each pattern is checked against the full command string (case-insensitive).
33+
# ---------------------------------------------------------------------------
34+
BLOCKED_PATTERNS=(
35+
# AWS — Destructive operations
36+
"aws * delete*"
37+
"aws * remove*"
38+
"aws * destroy*"
39+
"aws * terminate*"
40+
"aws * deregister*"
41+
"aws * purge*"
42+
"aws s3 rm *"
43+
"aws s3 rb *"
44+
"aws cloudformation delete-stack*"
45+
46+
# AWS — Provisioning & scaling
47+
"aws ec2 run-instances*"
48+
"aws ec2 stop-instances*"
49+
"aws autoscaling set-desired-capacity*"
50+
"aws autoscaling update-auto-scaling-group*"
51+
"aws application-autoscaling *"
52+
"aws ecs update-service*"
53+
54+
# AWS — IAM
55+
"aws iam delete*"
56+
"aws iam create*"
57+
"aws iam put*"
58+
"aws iam attach*"
59+
60+
# Kubernetes — Mutations
61+
"kubectl delete *"
62+
"kubectl apply *"
63+
"kubectl create *"
64+
"kubectl patch *"
65+
"kubectl scale *"
66+
"kubectl rollout *"
67+
"kubectl drain *"
68+
"kubectl cordon *"
69+
"kubectl exec *"
70+
"kubectl edit *"
71+
72+
# Terraform / IaC
73+
"terraform destroy*"
74+
"terraform apply*"
75+
"terraform import *"
76+
"terraform state rm *"
77+
"terraform taint *"
78+
79+
# Helm
80+
"helm install *"
81+
"helm upgrade *"
82+
"helm delete *"
83+
"helm uninstall *"
84+
"helm rollback *"
85+
86+
# Git — Destructive
87+
"git push --force*"
88+
"git push -f *"
89+
"git push --force-with-lease*"
90+
"git push origin main*"
91+
"git push origin master*"
92+
"git reset --hard*"
93+
"git clean -f*"
94+
95+
# File system — Destructive
96+
"rm -rf /"
97+
"rm -rf /*"
98+
"rm -rf ~"
99+
"rm -rf ~/*"
100+
"rm -rf ..*"
101+
"mkfs.*"
102+
"dd if=*/dev/*"
103+
104+
# Credential access via cat/less/head/tail
105+
"cat */.aws/*"
106+
"cat */.kube/*"
107+
"cat */.ssh/*"
108+
"cat *.env"
109+
"cat *.env.*"
110+
"cat */secrets/*"
111+
"cat *credentials*"
112+
"less */.aws/*"
113+
"less */.ssh/*"
114+
"head */.aws/*"
115+
"head */.ssh/*"
116+
"tail */.aws/*"
117+
"tail */.ssh/*"
118+
119+
# Network & remote access
120+
"ssh *"
121+
"scp *"
122+
"curl *|*sh"
123+
"curl *|*bash"
124+
"wget *|*sh"
125+
"wget *|*bash"
126+
127+
# Privilege escalation
128+
"sudo *"
129+
"sudo"
130+
"chmod 777 *"
131+
"chown root *"
132+
)
133+
134+
# ---------------------------------------------------------------------------
135+
# 3. Check function — matches a single sub-command against all patterns
136+
# ---------------------------------------------------------------------------
137+
check_command() {
138+
local cmd="$1"
139+
# Trim leading/trailing whitespace
140+
cmd="$(echo "$cmd" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')"
141+
142+
if [[ -z "$cmd" ]]; then
143+
return 0
144+
fi
145+
146+
# Convert to lowercase for case-insensitive matching
147+
local cmd_lower
148+
cmd_lower="$(echo "$cmd" | tr '[:upper:]' '[:lower:]')"
149+
150+
for pattern in "${BLOCKED_PATTERNS[@]}"; do
151+
local pattern_lower
152+
pattern_lower="$(echo "$pattern" | tr '[:upper:]' '[:lower:]')"
153+
154+
# shellcheck disable=SC2254
155+
if [[ "$cmd_lower" == $pattern_lower ]]; then
156+
printf '{"error":"BLOCKED by guardrail hook: command matches blocked pattern: %s"}\n' "$pattern" >&2
157+
exit 2
158+
fi
159+
done
160+
161+
return 0
162+
}
163+
164+
# ---------------------------------------------------------------------------
165+
# 4. Split on pipes and command chains, then check each sub-command
166+
# ---------------------------------------------------------------------------
167+
# Replace common chain operators with a delimiter
168+
NORMALIZED="$(echo "$COMMAND" | sed 's/&&/\n/g; s/||/\n/g; s/;/\n/g; s/|/\n/g')"
169+
170+
while IFS= read -r subcmd; do
171+
check_command "$subcmd"
172+
done <<< "$NORMALIZED"
173+
174+
# If we reach here, the command is allowed
175+
exit 0

.claude/rules/aws.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# AWS Rules
2+
3+
## Environment Context
4+
5+
- We use **AWS Bedrock** for AI model invocation
6+
- Sandbox accounts are accessed via **Mendix SSO**
7+
- **Production accounts exist on the same machine** — DO NOT use them
8+
- If a command references an AWS profile or region you don't recognize, STOP and ask
9+
10+
## Credential Safety
11+
12+
- NEVER read files in `~/.aws/` (credentials, config, SSO cache)
13+
- NEVER output or display AWS access keys, secret keys, or session tokens
14+
- NEVER set or export `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, or `AWS_SESSION_TOKEN` in commands
15+
- If you need to verify identity, use `aws sts get-caller-identity` — this is safe and read-only
16+
17+
## Allowed Operations (Read-Only)
18+
19+
These AWS CLI commands are safe and auto-approved:
20+
21+
- `aws * describe*` — describe any resource
22+
- `aws * list*` — list any resources
23+
- `aws * get*` — get resource details
24+
- `aws s3 ls` — list S3 buckets and objects
25+
- `aws sts get-caller-identity` — verify current identity
26+
27+
## Blocked Operations
28+
29+
### Destructive (deny — never allowed)
30+
- `aws * delete*`, `aws * remove*`, `aws * destroy*`, `aws * terminate*`
31+
- `aws * deregister*`, `aws * purge*`
32+
- `aws s3 rm`, `aws s3 rb`
33+
- `aws cloudformation delete-stack`
34+
35+
### Provisioning & Scaling (deny — never allowed)
36+
- `aws ec2 run-instances`, `aws ec2 stop-instances`
37+
- `aws autoscaling set-desired-capacity`, `aws autoscaling update-auto-scaling-group`
38+
- `aws application-autoscaling *`
39+
- `aws ecs update-service`
40+
41+
### IAM (deny — never allowed)
42+
- `aws iam create*`, `aws iam delete*`, `aws iam put*`, `aws iam attach*`
43+
44+
## Verification Steps
45+
46+
Before running any AWS command:
47+
48+
1. **Check the profile** — is this a sandbox account? If unsure, run `aws sts get-caller-identity` first
49+
2. **Check the region** — is this an expected region? If it looks unfamiliar, ask the user
50+
3. **Check the action** — is this read-only? If it mutates state, do NOT run it
51+
4. **When in doubt** — explain the command and let the human decide

.claude/rules/security.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Security Rules
2+
3+
These rules are loaded automatically by Claude Code at session start. They are non-negotiable.
4+
5+
## Safety Rules (NON-NEGOTIABLE)
6+
7+
1. NEVER run commands that delete, destroy, or modify production resources
8+
2. NEVER use AWS credentials for production accounts — only sandbox accounts
9+
3. NEVER deploy code, infrastructure, or configuration changes — a human must do this
10+
4. NEVER run `terraform apply`, `terraform destroy`, `kubectl apply`, `kubectl delete` against production
11+
5. NEVER read or output secrets, API keys, tokens, or credentials from files or environment variables
12+
6. NEVER run commands with `sudo`
13+
7. NEVER run `rm -rf` on any path outside the current project directory
14+
8. NEVER disable, bypass, or modify the guardrail hooks in `.claude/hooks/`
15+
9. NEVER push to `main` or `master` branches directly
16+
17+
## Core Principles
18+
19+
- **The agent works FOR you** — it must never take irreversible actions without explicit human approval
20+
- **Deny by default** — if a command is not explicitly allowed, it should require human confirmation
21+
- **Credentials are off-limits** — never read, display, or transmit secrets, tokens, or credentials
22+
- **Guardrails are mandatory** — the `.claude/hooks/` scripts must remain active and unmodified
23+
24+
## When In Doubt
25+
26+
If you are unsure whether a command is safe to run, **do not run it**. Instead:
27+
1. Explain what command you would run and why
28+
2. Describe the potential risks
29+
3. Wait for the human to decide
30+
31+
It is always better to ask than to act when safety is uncertain.

0 commit comments

Comments
 (0)