- להקים סביבת Docker מאובטחת ל-Claude Code עם devcontainer.json, Dockerfile ו-init-firewall.sh מלאים
- לנהל volume mounts נכון — read-only source, writable output, credential injection בלי לחשוף secrets
- לחבר Vault ו-AWS Secrets Manager לסביבת Claude Code — zero secrets ב-image
- לפרוס Claude Code על Kubernetes עם K8s YAML מלא — multi-session לצוות שלם
- לאפשר סביבות air-gapped מלאות דרך AWS Bedrock ו-Google Vertex AI
- לבנות audit logging ו-cost allocation לפי צוות/פרויקט
- להגדיר Enterprise Managed Policies ו-policy enforcement ארגוני
- פרקים 1-6: Headless mode, CI/CD, SDK, agent teams, production pipelines — הפרק הזה משלב את הכל
- Pipeline מפרק 6: צריך להיות פעיל — תפרסו אותו ב-Docker בתרגיל הראשון
- כלים: Docker Desktop (או Docker Engine), kubectl (לסעיף Kubernetes), Claude Code v2.1.32+
- ידע: Docker basics (images, containers, volumes), YAML, בסיסי Kubernetes — לא מתחילים מאפס
- זמן: 3-4 שעות | עלות: $0 לסביבה מקומית, $3-15 לסביבות cloud
- קובץ
.devcontainer/devcontainer.jsonמלא — copy-paste ready לכל פרויקט - קובץ
.devcontainer/Dockerfileעם non-root user, tool installation, hardening - קובץ
.devcontainer/init-firewall.sh— network isolation מלא - קובץ
docker-compose.ymlל-multi-session team — עם per-user containers - K8s YAML מלא — Deployment + Service + ConfigMap + Secret לסביבת enterprise
- תוכנית Secrets Management — Vault או AWS Secrets Manager מחוברים
- תוכנית אימוץ ארגוני 3-פאזות עם metrics, training, ו-change management
בפרק 6 בניתם Production Pipelines — orchestrators רב-שלביים עם checkpoints, error handling ו-structured logging. ה-pipeline שלכם עובד. עכשיו השאלה היא: איפה הוא רץ, מי מורשה להריץ אותו, ואיך מבטיחים שהוא לא יוצא מגבולות האבטחה שהארגון מגדיר. פרק 7 לוקח את ה-pipeline ועוטף אותו בשכבות הגנה: Docker container, firewall, secrets management, K8s orchestration ו-enterprise policies. בפרק 8 — הפרק האחרון — נסתכל קדימה: לאן Claude Code הולך, מה המיומנויות שישרדו, ואיך לבנות קריירה סביב AI-first development.
| English Term | הסבר בעברית |
|---|---|
| Dev Container | סביבת Docker מוגדרת מראש שמשתלבת עם VS Code — כולל כלים, הרשאות ו-firewall |
| Volume Mount | חיבור תיקייה מה-host לתוך ה-container — read-only או writable לפי הצורך |
| init-firewall.sh | סקריפט שמגביל outbound connections לדומיינים מורשים בלבד (npm, GitHub, Claude API) |
| Vault (HashiCorp) | מערכת secrets management — שומרת API keys, certificates ו-credentials בצורה מוצפנת |
| AWS Secrets Manager | שירות AWS לניהול secrets — rotation אוטומטי, audit log מובנה |
| Kubernetes (K8s) | מערכת orchestration לקונטיינרים — מנהלת deployment, scaling ו-recovery |
| ConfigMap | אובייקט Kubernetes לאחסון config שאינו sensitive — env vars, settings |
| K8s Secret | אובייקט Kubernetes לאחסון credentials — מוצפן ב-etcd |
| Managed Policies | כללים שמנהל ארגוני מגדיר ואי-אפשר לדרוס — חסימת פקודות, חובת code review |
| Settings Cascade | היררכיית הגדרות: Enterprise Policy > User Allow Rules > Project Settings > Defaults |
| Bedrock / Vertex | שירותי AWS ו-GCP שמריצים Claude בתוך התשתית הארגונית — data residency, VPC |
| Air-Gapped | סביבה ללא גישה ישירה לאינטרנט — הכל עובר דרך ה-VPC הארגוני |
| Audit Trail | יומן מלא של כל פעולה — tool calls, file access, commands, עלויות |
| Cost Allocation | שיוך עלויות API לפי צוות / פרויקט / משתמש — לצורכי chargeback |
| SSO (Single Sign-On) | אימות SAML/OIDC — גישה ל-Claude Code דרך חשבון ארגוני אחד |
| Data Residency | דרישה שנתונים יישמרו באזור גיאוגרפי ספציפי — EU, US-East וכו' |
למה Docker ל-Claude Code בפרודקשן
Claude Code, בגדרותיו, הוא agent שיכול לקרוא ולכתוב קבצים, להריץ פקודות מסוף, ולגשת לרשת. בסביבת dev זה נוח. בפרודקשן — זה סיכון. Docker פותר שלושה בעיות קריטיות בבת-אחת:
- Isolation: ה-agent רואה רק מה שמותר לו לראות — filesystem, network, resources
- Reproducibility: אותה סביבה בדיוק ב-dev, staging ו-production — לא עוד "works on my machine"
- Auditability: כל מה שהאגנט עשה בתוך ה-container מתועד — tool calls, file access, network connections
הנקודה השלישית קריטית לאנטרפרייז: לא רק שהאגנט לא יכול לצאת מגבולות — אפשר גם להוכיח שהוא לא יצא. זה מה שמאפשר Claude Code בסביבות מוסדרות (SOC 2, HIPAA, GDPR).
| מצב | Docker? | הסיבה |
|---|---|---|
| Pipeline רץ ב-production | כן — חובה | בידוד, אבטחה, reproducibility |
| CI/CD workflows | כן — חובה | סביבה עקבית, firewall לבניות |
| Multi-developer team | כן — מומלץ מאוד | כולם מקבלים אותו setup בדיוק |
| Regulated environment | כן — הכרחי | audit trail, data residency, isolation |
| Agent ניגש ל-external APIs | כן — חשוב | firewall מגביל לאיזה endpoints |
| Dev אישי, ניסויים מקומיים | לא חובה | overhead מיותר בשלב exploration |
| Quick one-off queries | לא | docker startup מאט workflow |
בדק שה-tooling קיים: הרץ docker --version ו-docker compose version. אם Docker לא מותקן — הורד Docker Desktop מ-docker.com. בדק גם docker run hello-world לאישור שהכל עובד. אל תמשיך לפני שיש לך Docker פעיל.
הקמת Dev Containers — devcontainer.json + Dockerfile
Dev Containers הם הדרך הרשמית לעבוד עם Claude Code בסביבה מבודדת. תיקיית .devcontainer/ בשורש הפרויקט מגדירה את כל הסביבה — VS Code פותח אותה אוטומטית בתוך container.
Anthropic מספקים devcontainer רשמי ב-github.com/anthropics/claude-code תחת .devcontainer/. אנחנו ניקח אותו כבסיס ונוסיף hardening לפי הצרכים שלנו.
קובץ devcontainer.json מלא
{
"name": "Claude Code Enterprise Dev",
"build": {
"dockerfile": "Dockerfile",
"args": {
"NODE_VERSION": "20",
"PYTHON_VERSION": "3.11"
}
},
"postCreateCommand": "bash .devcontainer/init-firewall.sh && npm install",
"postStartCommand": "echo 'Container started at' $(date) >> /tmp/container.log",
"customizations": {
"vscode": {
"extensions": [
"anthropic.claude-code",
"ms-python.python",
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode"
],
"settings": {
"terminal.integrated.shell.linux": "/bin/bash",
"editor.formatOnSave": true
}
}
},
"remoteEnv": {
"ANTHROPIC_API_KEY": "${localEnv:ANTHROPIC_API_KEY}",
"CLAUDE_CODE_MAX_OUTPUT_TOKENS": "32000",
"NODE_ENV": "development"
},
"mounts": [
"source=${localWorkspaceFolder},target=/workspace,type=bind,consistency=cached,readonly=false",
"source=claude-output,target=/workspace/output,type=volume",
"source=${localEnv:HOME}/.ssh,target=/home/developer/.ssh,type=bind,readonly=true"
],
"runArgs": [
"--cap-drop=ALL",
"--security-opt=no-new-privileges",
"--memory=4g",
"--cpus=2",
"--network=claude-isolated"
],
"forwardPorts": [],
"remoteUser": "developer"
}
קובץ Dockerfile מלא
FROM node:20-slim AS base
ARG PYTHON_VERSION=3.11
ARG DEVELOPER_UID=1000
# Install system dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
git \
curl \
wget \
ca-certificates \
iptables \
iproute2 \
python3 \
python3-pip \
python3-venv \
jq \
&& rm -rf /var/lib/apt/lists/*
# Install Claude Code globally
RUN npm install -g @anthropic-ai/claude-code@latest
# Create non-root user
RUN groupadd --gid ${DEVELOPER_UID} developer \
&& useradd --uid ${DEVELOPER_UID} --gid developer \
--shell /bin/bash \
--create-home developer \
&& mkdir -p /workspace /workspace/output \
&& chown -R developer:developer /workspace
# Install Python packages as developer user
USER developer
WORKDIR /workspace
# Set up Python virtual environment
RUN python3 -m venv /home/developer/.venv
ENV PATH="/home/developer/.venv/bin:$PATH"
# Pre-install common Claude Code dependencies
RUN pip install --no-cache-dir \
anthropic \
claude-agent-sdk \
python-dotenv \
structlog
# Claude Code config directory
RUN mkdir -p /home/developer/.claude
# Copy CLAUDE.md defaults (project-level, overridden at runtime)
COPY --chown=developer:developer claude-defaults.md /home/developer/.claude/CLAUDE.md
WORKDIR /workspace
# Health check — verify claude CLI available
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD claude --version || exit 1
קובץ init-firewall.sh
זה הקובץ שמגביל את ה-network access של ה-container לדומיינים מורשים בלבד. הרץ אחרי שה-container עולה.
#!/bin/bash
# init-firewall.sh — Network isolation for Claude Code containers
# Allows ONLY: Anthropic API, npm registry, GitHub, PyPI
# Blocks: everything else
set -euo pipefail
echo "[firewall] Initializing network isolation..."
# Allowed outbound destinations (by IP range or hostname)
ALLOWED_HOSTS=(
"api.anthropic.com"
"registry.npmjs.org"
"github.com"
"api.github.com"
"pypi.org"
"files.pythonhosted.org"
"pkg.anthropic.com"
)
# Flush existing rules
iptables -F OUTPUT 2>/dev/null || true
iptables -F INPUT 2>/dev/null || true
# Allow loopback
iptables -A OUTPUT -o lo -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT
# Allow established connections
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Allow DNS (needed to resolve allowed hosts)
iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 53 -j ACCEPT
# Allow HTTPS to approved hosts
for HOST in "${ALLOWED_HOSTS[@]}"; do
# Resolve IP and allow
IPS=$(getent ahosts "$HOST" 2>/dev/null | awk '{ print $1 }' | sort -u)
for IP in $IPS; do
iptables -A OUTPUT -d "$IP" -p tcp --dport 443 -j ACCEPT
echo "[firewall] Allowed $HOST ($IP):443"
done
done
# Block everything else outbound
iptables -A OUTPUT -j DROP
echo "[firewall] Network isolation active. Allowed hosts: ${ALLOWED_HOSTS[*]}"
echo "[firewall] Run 'iptables -L OUTPUT -n' to verify rules."
מה שעושים בטעות: כותבים ENV ANTHROPIC_API_KEY=sk-ant-api03-... בתוך ה-Dockerfile. ה-key נשרף לתוך ה-image layer — מי שיש לו גישה ל-image יכול לחלץ אותו עם docker history או docker inspect. גם אחרי שמוחקים את השורה — הוא נשאר בלayers הישנים. מה לעשות במקום: remoteEnv ב-devcontainer.json שמושך מ-${localEnv:ANTHROPIC_API_KEY} — הערך מוזרק בזמן ריצה בלבד, אף פעם לא נשמר ב-image.
צור את תיקיית .devcontainer/ בפרויקט שלך. העתק את שלושת הקבצים (devcontainer.json, Dockerfile, init-firewall.sh) מהדוגמאות למעלה. ב-VS Code: Ctrl+Shift+P ← "Dev Containers: Reopen in Container". המתן ל-build. אחרי שה-container עלה — הרץ claude --version מה-terminal הפנימי.
- צור תיקיית
.devcontainer/בשורש הפרויקט שלך - העתק את devcontainer.json מהדוגמה — עדכן את
nameלשם הפרויקט שלך - העתק את Dockerfile — שנה את
DEVELOPER_UIDל-1001אם יש לך conflict - העתק את init-firewall.sh — הוסף domain אחד שה-pipeline שלך צריך לדומיין
ALLOWED_HOSTS - הרץ
chmod +x .devcontainer/init-firewall.sh - פתח ב-VS Code → Dev Containers: Reopen in Container
- כשה-container עלה: הרץ
claude -p "say hello from container" --bare - הרץ
iptables -L OUTPUT -nוודא שהfirewall פעיל
תוצר: devcontainer.json + Dockerfile + init-firewall.sh פועלים — Claude Code רץ בבידוד מלא.
Docker Security — 7 כללים
כל כלל כאן לא תיאורטי — כל אחד מסגיר וקטור תקיפה ספציפי שנצפה בסביבות production.
כלל 1: לעולם לא mount של Docker socket
מה שאנשים כותבים בטעות: -v /var/run/docker.sock:/var/run/docker.sock. Docker socket = root access ל-host machine מחוץ לכל בידוד. agent שיש לו גישה ל-socket יכול להריץ container חדש עם --privileged ולצאת מה-sandbox לחלוטין. אם ה-agent צריך להריץ containers — השתמש ב-Docker-in-Docker עם --privileged על DinD container נפרד שמבודד מה-host, או ב-Podman rootless.
כלל 2: Non-root user חובה
ה-Dockerfile למעלה מגדיר user developer עם UID 1000. תמיד הוסף ל-docker run: --user developer. אם ה-container נפרץ והאגנט מנסה privilege escalation — הוא תקוע כ-unprivileged user.
כלל 3: Read-only filesystem עם חריגים ספציפיים
docker run \
--read-only \
--tmpfs /tmp:size=512m \
--tmpfs /var/run:size=64m \
-v /my/project:/workspace:ro \
-v claude-output:/workspace/output:rw \
claude-code-image
Source code: read-only (:ro). Output directory: writable ב-named volume. /tmp: tmpfs זמני. כך אפשר לאשר שהאגנט לא שינה קוד מקור — רק יצר output.
כלל 4: Resource limits תמיד
docker run \
--memory=4g \
--memory-swap=4g \
--cpus=2 \
--pids-limit=500 \
--ulimit nofile=1024:1024 \
claude-code-image
runaway agent שנכנס ללולאה אינסופית לא יפיל את ה-host. Pids limit מונע fork bomb. Nofile limit מונע exhaustion של file descriptors.
כלל 5: Cap drop — הסר יכולות kernel
docker run \
--cap-drop=ALL \
--cap-add=NET_BIND_SERVICE \
--security-opt=no-new-privileges \
claude-code-image
ברירת המחדל של Docker מעניק ~14 capabilities. רובן מיותרות לאגנט. --cap-drop=ALL מוריד הכל, ואז מחזיר רק מה שצריך בפועל.
כלל 6: Network isolation
צור Docker network נפרד לסביבת Claude Code:
# Create isolated network
docker network create \
--driver bridge \
--subnet 172.20.0.0/16 \
--opt com.docker.network.bridge.enable_icc=false \
claude-isolated
# Run with isolated network
docker run --network claude-isolated claude-code-image
enable_icc=false מונע inter-container communication — כל container בnetwork לא יכול לדבר ישירות לcontainer אחר בו. בשילוב עם init-firewall.sh: בידוד כמעט מוחלט.
כלל 7: Image scanning לפני deployment
# Scan with Trivy (free, open source)
docker run --rm aquasec/trivy image your-claude-image:latest
# Scan with Docker Scout (built into Docker Desktop)
docker scout cves your-claude-image:latest
# In CI/CD — fail the build if HIGH or CRITICAL vulns found
trivy image --exit-code 1 --severity HIGH,CRITICAL your-claude-image:latest
Node:latest, Python:latest, ubuntu:latest — כולם כוללים מאות packages שאינך צריך, ורובם מכילים vulnerabilities ידועות. השתמש תמיד ב-slim variants: node:20-slim, python:3.11-slim-bookworm. Alpine קטן עוד יותר אבל glibc compatibility בעייתי לחלק מה-native modules. Distroless images של Google הם האופציה הכי מינימלית אם אין צורך ב-bash בתוך ה-container.
בדוק את ה-container שלך מול הרשימה: הרץ docker inspect CONTAINER_ID וחפש: (1) האם User הוא non-root? (2) האם ReadonlyRootfs הוא true? (3) האם Memory יש ערך? (4) האם CapDrop כולל ALL? סמן כמה מ-4 הנקודות עברתם.
Volume Mounts וניהול Credentials
Volume mount לא נכון הוא אחד הבעיות הנפוצות ביותר בסביבות Claude Code production. הכלל: הרשאה מינימלית לכל mount.
מפת ה-Mounts המומלצת
volumes:
# Source code — read-only, agent reads but cannot modify
- type: bind
source: ${PWD}
target: /workspace
read_only: true
# Output directory — writable named volume, not host path
- type: volume
source: claude-output
target: /workspace/output
# SSH keys — read-only, for git operations
- type: bind
source: ${HOME}/.ssh
target: /home/developer/.ssh
read_only: true
# CLAUDE.md project config — read-only
- type: bind
source: ${PWD}/CLAUDE.md
target: /workspace/CLAUDE.md
read_only: true
# Logs — separate named volume for persistence across container restarts
- type: volume
source: claude-logs
target: /var/log/claude
מה לא לעשות עם mounts
| Mount | הבעיה | במקום |
|---|---|---|
/var/run/docker.sock | root access ל-host | DinD מבודד בלבד |
/etc | גישה ל-system config | אין סיבה לעשות זאת |
${HOME}/.aws עם write | agent יכול לשנות credentials | :ro תמיד |
/ (root) | גישה לכל ה-filesystem | mount ספציפי per-directory |
| Host path ל-output | agent כותב מחוץ לsandbox | named volume בלבד |
Credential Injection בזמן ריצה
שלוש שיטות — לפי רמת ה-security שצריכים:
שיטה 1 — Environment variables (dev/staging):
# docker run
docker run -e ANTHROPIC_API_KEY="${ANTHROPIC_API_KEY}" claude-code-image
# docker-compose
environment:
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY} # מ-.env מקומי
# devcontainer.json
"remoteEnv": {
"ANTHROPIC_API_KEY": "${localEnv:ANTHROPIC_API_KEY}"
}
שיטה 2 — Docker secrets (production):
# Create secret
echo "sk-ant-api03-..." | docker secret create anthropic_api_key -
# Use in service
services:
claude-agent:
image: claude-code-image
secrets:
- anthropic_api_key
environment:
- ANTHROPIC_API_KEY_FILE=/run/secrets/anthropic_api_key
secrets:
anthropic_api_key:
external: true
שיטה 3 — Vault/AWS Secrets Manager (enterprise): מוסבר בסעיף הבא.
בדוק את כל ה-mounts הקיימים ב-container שלך: docker inspect CONTAINER_ID | jq '.[0].Mounts'. לכל mount שאינו output — וודא שיש "Mode": "ro". אם יש ל-source code mount שהוא writable — תקן אותו עכשיו.
Secrets Management — Vault ו-AWS Secrets Manager
בסביבת אנטרפרייז, secrets לא עוברים כ-env vars ב-CI config, לא נשמרים ב-.env files, ולא מוכנסים ל-Docker image. כל secrets מנוהלים ממערכת ייעודית עם audit trail, rotation אוטומטי ו-access control.
אפשרות A — HashiCorp Vault
Vault הוא הסטנדרט בתעשייה לניהול secrets. אינטגרציה עם Claude Code containers:
#!/bin/bash
# vault-inject.sh — Inject secrets from Vault before starting Claude Code
# Run as entrypoint script in Dockerfile
set -euo pipefail
# Authenticate with Vault using Kubernetes service account token
# (when running inside K8s — see Kubernetes section below)
export VAULT_ADDR="${VAULT_ADDR:-http://vault.vault.svc.cluster.local:8200}"
export VAULT_TOKEN=$(vault write -field=token auth/kubernetes/login \
role="claude-code-agent" \
jwt="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)")
# Fetch API key
export ANTHROPIC_API_KEY=$(vault kv get -field=api_key \
secret/claude-code/anthropic)
# Fetch optional additional secrets
export GITHUB_TOKEN=$(vault kv get -field=token \
secret/claude-code/github 2>/dev/null || echo "")
echo "[vault] Secrets loaded. Starting Claude Code..."
unset VAULT_TOKEN # Don't leak Vault token to child processes
# Hand off to main process
exec "$@"
ב-Dockerfile: הגדר את vault-inject.sh כ-ENTRYPOINT:
COPY vault-inject.sh /usr/local/bin/vault-inject.sh
RUN chmod +x /usr/local/bin/vault-inject.sh
ENTRYPOINT ["/usr/local/bin/vault-inject.sh"]
CMD ["claude", "--version"] # overridden at runtime
Policy ב-Vault עבור Claude Code agent (least-privilege):
path "secret/data/claude-code/anthropic" {
capabilities = ["read"]
}
path "secret/data/claude-code/github" {
capabilities = ["read"]
}
# Deny everything else
path "secret/*" {
capabilities = ["deny"]
}
אפשרות B — AWS Secrets Manager
לסביבות AWS, Secrets Manager עם IAM role-based access הוא הגישה המקובלת:
#!/bin/bash
# aws-secrets-inject.sh — Inject secrets from AWS Secrets Manager
set -euo pipefail
AWS_REGION="${AWS_DEFAULT_REGION:-us-east-1}"
SECRET_NAME="${SECRET_NAME:-claude-code/production}"
echo "[aws-sm] Fetching secrets from $SECRET_NAME in $AWS_REGION..."
# Fetch the secret (structured as JSON)
SECRET_JSON=$(aws secretsmanager get-secret-value \
--secret-id "$SECRET_NAME" \
--region "$AWS_REGION" \
--query SecretString \
--output text)
# Parse and export
export ANTHROPIC_API_KEY=$(echo "$SECRET_JSON" | jq -r '.anthropic_api_key')
export GITHUB_TOKEN=$(echo "$SECRET_JSON" | jq -r '.github_token // empty')
# Verify we got the key
if [ -z "$ANTHROPIC_API_KEY" ]; then
echo "[aws-sm] ERROR: Failed to retrieve ANTHROPIC_API_KEY"
exit 1
fi
echo "[aws-sm] Secrets loaded successfully."
exec "$@"
IAM Policy ל-container task role (ECS/EKS):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"secretsmanager:GetSecretValue",
"secretsmanager:DescribeSecret"
],
"Resource": [
"arn:aws:secretsmanager:us-east-1:123456789:secret:claude-code/*"
]
},
{
"Effect": "Allow",
"Action": "kms:Decrypt",
"Resource": "arn:aws:kms:us-east-1:123456789:key/your-kms-key-id"
}
]
}
| קריטריון | HashiCorp Vault | AWS Secrets Manager |
|---|---|---|
| סביבת הפעלה | On-premise, multi-cloud, K8s | AWS-native בלבד |
| Rotation אוטומטי | כן (plugin-based) | כן (built-in עבור RDS, Redshift) |
| Audit trail | Vault Audit Device | CloudTrail אוטומטי |
| עלות | Open source (self-hosted) / HCP Vault | $0.40/secret/month + API calls |
| Learning curve | בינוני-גבוה | נמוך — AWS console ידידותי |
| בחר אם... | multi-cloud, K8s, או כבר יש Vault | all-in AWS, פשטות חשובה |
גם אם אין לך Vault/AWS SM עדיין — מפה את ה-secrets הנוכחיים שלך: רשום ב-scratch file את כל ה-API keys שה-Claude Code environment שלך צריך. ספור אותם. כל key שנמצא ב-dotenv, ב-CI config, או ב-shell profile — זה candidate להעברה ל-secrets manager.
Kubernetes לסביבות Enterprise
כשיש צוות של מפתחים שכל אחד צריך Claude Code environment, או כשיש pipelines שצריכים scaling, Kubernetes הוא הפתרון הטבעי. K8s נותן: scheduling, scaling, health checks, rolling updates ו-resource quotas ברמת namespace.
K8s YAML מלא — Claude Code Deployment
# namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: claude-agents
labels:
env: production
team: platform
---
# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: claude-config
namespace: claude-agents
data:
CLAUDE_CODE_MAX_OUTPUT_TOKENS: "32000"
NODE_ENV: "production"
LOG_LEVEL: "info"
ALLOWED_TOOLS: "Read,Write,Bash,Glob,Grep"
---
# secret.yaml (secrets injected from Vault/AWS SM — not hardcoded here)
apiVersion: v1
kind: Secret
metadata:
name: claude-secrets
namespace: claude-agents
annotations:
# Vault agent injector annotation — auto-inject from Vault
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/role: "claude-code-agent"
vault.hashicorp.com/agent-inject-secret-anthropic: "secret/claude-code/anthropic"
vault.hashicorp.com/agent-inject-template-anthropic: |
{{- with secret "secret/claude-code/anthropic" -}}
export ANTHROPIC_API_KEY="{{ .Data.data.api_key }}"
{{- end }}
type: Opaque
---
# serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: claude-agent-sa
namespace: claude-agents
annotations:
# AWS EKS IRSA — map to IAM role with Secrets Manager access
eks.amazonaws.com/role-arn: arn:aws:iam::123456789:role/ClaudeCodeAgentRole
---
# rbac.yaml — minimal permissions for Claude Code agent
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: claude-agent-role
namespace: claude-agents
rules:
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "list"]
- apiGroups: [""]
resources: ["pods"]
verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: claude-agent-rolebinding
namespace: claude-agents
subjects:
- kind: ServiceAccount
name: claude-agent-sa
namespace: claude-agents
roleRef:
kind: Role
name: claude-agent-role
apiGroup: rbac.authorization.k8s.io
---
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: claude-agent
namespace: claude-agents
labels:
app: claude-agent
version: "2.1.32"
spec:
replicas: 3
selector:
matchLabels:
app: claude-agent
template:
metadata:
labels:
app: claude-agent
spec:
serviceAccountName: claude-agent-sa
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 1000
seccompProfile:
type: RuntimeDefault
containers:
- name: claude-code
image: your-registry/claude-code-enterprise:2.1.32
imagePullPolicy: Always
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
resources:
requests:
memory: "512Mi"
cpu: "500m"
limits:
memory: "4Gi"
cpu: "2000m"
envFrom:
- configMapRef:
name: claude-config
env:
- name: ANTHROPIC_API_KEY
valueFrom:
secretKeyRef:
name: claude-secrets
key: anthropic_api_key
volumeMounts:
- name: workspace
mountPath: /workspace
readOnly: false
- name: tmp
mountPath: /tmp
- name: logs
mountPath: /var/log/claude
livenessProbe:
exec:
command: ["claude", "--version"]
initialDelaySeconds: 10
periodSeconds: 30
readinessProbe:
exec:
command: ["test", "-f", "/tmp/ready"]
initialDelaySeconds: 5
periodSeconds: 10
volumes:
- name: workspace
persistentVolumeClaim:
claimName: claude-workspace-pvc
- name: tmp
emptyDir:
medium: Memory
sizeLimit: 512Mi
- name: logs
persistentVolumeClaim:
claimName: claude-logs-pvc
---
# resource-quota.yaml — limit total resource usage per namespace
apiVersion: v1
kind: ResourceQuota
metadata:
name: claude-agents-quota
namespace: claude-agents
spec:
hard:
pods: "20"
requests.cpu: "10"
requests.memory: "20Gi"
limits.cpu: "40"
limits.memory: "80Gi"
persistentvolumeclaims: "10"
הפעלה
# Apply all resources
kubectl apply -f namespace.yaml
kubectl apply -f configmap.yaml
kubectl apply -f serviceaccount.yaml
kubectl apply -f rbac.yaml
kubectl apply -f secret.yaml
kubectl apply -f deployment.yaml
kubectl apply -f resource-quota.yaml
# Verify
kubectl get pods -n claude-agents
kubectl logs -n claude-agents deploy/claude-agent --follow
# Run ad-hoc task in a pod
kubectl exec -n claude-agents deploy/claude-agent -- \
claude -p "analyze /workspace/src and report issues" --bare
- צור namespace בשם
claude-agentsב-local cluster שלך (minikube / kind) - העתק את ה-ConfigMap — עדכן
ALLOWED_TOOLSלפי ה-pipeline שלך - צור Secret בסיסי עם
kubectl create secret generic claude-secrets --from-literal=anthropic_api_key=$ANTHROPIC_API_KEY -n claude-agents - בנה את ה-image שלך:
docker build -t claude-code-enterprise:local . - עדכן את ה-Deployment YAML לpull מ-
claude-code-enterprise:local - Apply:
kubectl apply -f deployment.yamlובדק status - הרץ משימה:
kubectl exec -n claude-agents deploy/claude-agent -- claude -p "hello from k8s" --bare - בדוק ResourceQuota:
kubectl describe resourcequota -n claude-agents
תוצר: Claude Code רץ ב-Kubernetes namespace מבודד עם resource quotas, non-root security context ו-secret management.
Multi-Session לצוותים
כשצוות שלם עובד עם Claude Code, כל developer צריך container משלו. docker-compose.yml מגדיר את כל הסביבה בקובץ אחד.
docker-compose.yml לצוות
version: "3.9"
networks:
claude-isolated:
driver: bridge
driver_opts:
com.docker.network.bridge.enable_icc: "false"
volumes:
shared-output:
driver: local
claude-logs:
driver: local
# Base service definition (DRY — all services inherit from this)
x-claude-base: &claude-base
image: your-registry/claude-code-enterprise:2.1.32
networks:
- claude-isolated
environment:
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
- CLAUDE_CODE_MAX_OUTPUT_TOKENS=32000
- LOG_LEVEL=info
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
read_only: true
tmpfs:
- /tmp:size=256m
restart: unless-stopped
services:
# Developer 1 — Alice
claude-alice:
<<: *claude-base
container_name: claude-alice
user: "1001:1001"
volumes:
- ${ALICE_WORKSPACE:-./workspace/alice}:/workspace:ro
- shared-output:/workspace/output:rw
- claude-logs:/var/log/claude:rw
environment:
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
- DEVELOPER_NAME=alice
mem_limit: 4g
cpus: 2.0
# Developer 2 — Bob
claude-bob:
<<: *claude-base
container_name: claude-bob
user: "1002:1002"
volumes:
- ${BOB_WORKSPACE:-./workspace/bob}:/workspace:ro
- shared-output:/workspace/output:rw
- claude-logs:/var/log/claude:rw
environment:
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
- DEVELOPER_NAME=bob
mem_limit: 4g
cpus: 2.0
# CI/CD agent — lightweight, headless
claude-ci:
<<: *claude-base
container_name: claude-ci
user: "2000:2000"
volumes:
- ${CI_WORKSPACE:-./workspace/ci}:/workspace:ro
- shared-output:/workspace/output:rw
- claude-logs:/var/log/claude:rw
environment:
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
- DEVELOPER_NAME=ci-agent
- CLAUDE_CODE_MAX_OUTPUT_TOKENS=8000
mem_limit: 2g
cpus: 1.0
restart: "no" # CI containers don't auto-restart
הפעלה:
# Start all team containers
docker compose up -d
# Run task for specific developer
docker compose exec claude-alice claude -p "review src/api.ts" --bare
# View logs for entire team
docker compose logs -f
# Scale CI agents (ephemeral)
docker compose up --scale claude-ci=5 -d
העתק את docker-compose.yml ועדכן את שמות ה-developers לשמות אמיתיים בצוות שלך. שנה את ה-workspace paths לפרויקטים שכל אחד עובד עליהם. שמור — זהו ה-template לonboarding הבא.
Bedrock, Vertex ו-Air-Gapped Environments
ארגונים עם דרישות data residency, compliance, או network isolation מוחלטת מריצים Claude Code דרך cloud providers במקום Anthropic API ישירות. זה מאפשר: data שנשאר ב-VPC שלך, billing מרכזי, ו-certifications (SOC 2, HIPAA, FedRAMP) של ה-cloud provider.
AWS Bedrock — הגדרה מלאה
# Environment variables
export CLAUDE_CODE_USE_BEDROCK=1
export AWS_DEFAULT_REGION=us-east-1
export AWS_PROFILE=claude-code-prod # IAM profile with Bedrock access
# OR — explicit credentials (better: use IAM roles)
export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
# Model selection (Bedrock model IDs for Claude)
# Default: claude-sonnet-4-5
# For specific model:
export ANTHROPIC_MODEL=anthropic.claude-sonnet-4-5-20251101-v1:0
# Verify connection
aws bedrock list-foundation-models --region us-east-1 \
--query "modelSummaries[?contains(modelId, 'claude')]"
IAM Policy ל-Bedrock access:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"bedrock:InvokeModel",
"bedrock:InvokeModelWithResponseStream"
],
"Resource": [
"arn:aws:bedrock:us-east-1::foundation-model/anthropic.claude-*"
]
}
]
}
Google Vertex AI — הגדרה מלאה
# Environment variables
export CLAUDE_CODE_USE_VERTEX=1
export CLOUD_ML_REGION=us-east5 # Region must support Claude on Vertex
export ANTHROPIC_VERTEX_PROJECT_ID=my-gcp-project-id
# Authentication via service account
export GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account-key.json
# OR — Application Default Credentials (better for K8s with Workload Identity)
gcloud auth application-default login
# Verify
gcloud ai models list --region=us-east5 | grep claude
Air-Gapped Setup — VPC Private Endpoints
לסביבות ללא outbound internet בכלל:
# AWS VPC Endpoint for Bedrock
# 1. Create VPC Interface Endpoint for Bedrock
aws ec2 create-vpc-endpoint \
--vpc-id vpc-12345678 \
--service-name com.amazonaws.us-east-1.bedrock-runtime \
--vpc-endpoint-type Interface \
--subnet-ids subnet-12345 subnet-67890 \
--security-group-ids sg-12345
# 2. DNS resolution — private DNS name resolves within VPC
# bedrock-runtime.us-east-1.amazonaws.com → private IP (no internet)
# 3. Container runs with NO internet access
# All traffic to Bedrock goes through VPC endpoint
# init-firewall.sh blocks everything EXCEPT internal VPC CIDR
# Modified init-firewall.sh for air-gapped Bedrock:
ALLOWED_CIDRS=(
"10.0.0.0/8" # VPC internal (Bedrock endpoint)
"172.16.0.0/12" # Internal subnets
)
# Instead of hostname-based rules, use CIDR-based rules
אם ה-pipeline שלך כולל WebSearch tool (fact-checking, market research), הוא לא יעבוד דרך cloud provider routing. Bedrock ו-Vertex מגישים רק את model calls — לא את ה-built-in tools של Anthropic. פתרון: stages שצריכים WebSearch צריכים לרוץ דרך Anthropic API ישירות, בעוד שאר ה-stages רצים דרך Bedrock/Vertex. תכנן hybrid routing לפי tool requirements.
| קריטריון | Anthropic API | AWS Bedrock | Google Vertex |
|---|---|---|---|
| Data residency | Anthropic infra | AWS region שלך | GCP region שלך |
| WebSearch tool | כן | לא | לא |
| Latency overhead | baseline | +50-150ms | +50-200ms |
| Billing | Anthropic invoice | AWS bill | GCP bill |
| Compliance certs | SOC 2 | SOC 2, HIPAA, FedRAMP | SOC 2, HIPAA, ISO 27001 |
| VPC private endpoint | לא | כן | כן |
| בחר אם... | פשטות, WebSearch | AWS shop, regulated | GCP shop, regulated |
בדוק אם הארגון שלך כבר משתמש ב-AWS או GCP. אם כן — הגדר CLAUDE_CODE_USE_BEDROCK=1 (או Vertex) ב-.env. הרץ claude -p "hello" --bare ובדוק שה-request עובר דרך ה-cloud provider. אם מופיעה שגיאה של credentials — זה בסדר, תעד מה צריך להגדיר.
Audit Logging ו-Cost Allocation
כל ארגון שמשתמש ב-Claude Code בפרודקשן צריך לדעת: מי עשה מה, מתי, כמה זה עלה. Audit logging ו-cost allocation הם תנאי הכרחי לאימוץ ארגוני — בלעדיהם אין visibility ואין accountability.
Structured Audit Logging
הגדר logging hook ב-CLAUDE.md ברמת הפרויקט:
# CLAUDE.md — Audit logging configuration
# Every tool call logs to structured audit trail
## Audit Requirements
- Log all file reads, writes, and bash commands
- Include: timestamp, developer_id, project, tool, args summary, outcome
- Send to: /var/log/claude/audit.jsonl (append-only)
- Never log: file contents, credentials, PII
- Log format: JSON Lines (one JSON object per line)
Hook script ב-.claude/hooks/post-tool-use.sh:
#!/bin/bash
# post-tool-use.sh — Called after every tool use by Claude Code
# Receives tool info via environment variables (Claude Code hook protocol)
TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
DEVELOPER="${DEVELOPER_NAME:-unknown}"
PROJECT="${PROJECT_NAME:-$(basename $PWD)}"
TEAM="${TEAM_NAME:-unassigned}"
# Build structured log entry
LOG_ENTRY=$(jq -n \
--arg ts "$TIMESTAMP" \
--arg dev "$DEVELOPER" \
--arg proj "$PROJECT" \
--arg team "$TEAM" \
--arg tool "${CLAUDE_TOOL_NAME:-unknown}" \
--arg result "${CLAUDE_TOOL_RESULT:-unknown}" \
--arg tokens "${CLAUDE_TOKENS_USED:-0}" \
'{
timestamp: $ts,
developer: $dev,
project: $proj,
team: $team,
tool: $tool,
result: $result,
tokens_used: ($tokens | tonumber),
cost_usd: (($tokens | tonumber) * 0.000015)
}')
# Append to audit log
echo "$LOG_ENTRY" >> /var/log/claude/audit.jsonl
# Optional: send to centralized logging (ELK, Datadog, Splunk)
if [ -n "${AUDIT_WEBHOOK_URL:-}" ]; then
curl -s -X POST "$AUDIT_WEBHOOK_URL" \
-H "Content-Type: application/json" \
-d "$LOG_ENTRY" &
fi
Cost Allocation Dashboard
ניתוח עלויות מה-audit log:
#!/bin/bash
# cost-report.sh — Weekly cost allocation report
LOG_FILE="/var/log/claude/audit.jsonl"
REPORT_DATE=$(date +"%Y-%m-%d")
echo "=== Claude Code Cost Report — $REPORT_DATE ==="
echo ""
# Cost per team
echo "--- Cost per Team (this week) ---"
jq -r '[.team, .cost_usd] | @tsv' "$LOG_FILE" | \
awk '{team[$1] += $2} END {for (t in team) printf "%-20s $%.4f\n", t, team[t]}' | \
sort -k2 -rn
echo ""
# Cost per developer
echo "--- Cost per Developer ---"
jq -r '[.developer, .cost_usd] | @tsv' "$LOG_FILE" | \
awk '{dev[$1] += $2} END {for (d in dev) printf "%-20s $%.4f\n", d, dev[d]}' | \
sort -k2 -rn
echo ""
# Most expensive operations
echo "--- Top 10 Expensive Operations ---"
jq -r '[.timestamp, .developer, .tool, .cost_usd] | @tsv' "$LOG_FILE" | \
sort -k4 -rn | head -10
echo ""
# Total
echo "--- Total ---"
jq -r '.cost_usd' "$LOG_FILE" | \
awk '{sum += $1} END {printf "Total: $%.4f\n", sum}'
פלט דוגמה (מייצג):
=== Claude Code Cost Report — 2026-04-08 ===
--- Cost per Team (this week) ---
backend-team $4.2300
frontend-team $2.1100
platform-team $8.9400
data-team $1.3200
--- Cost per Developer ---
alice $3.1200
bob $2.8900
carol $5.2700
dave $0.9900
--- Total ---
Total: $16.6000
Tags ל-Cost Allocation ב-Bedrock
כש-Claude Code רץ דרך AWS Bedrock, אפשר לתייג requests לצרכי AWS Cost Explorer:
# בcontainer של כל developer — env vars שהופכים ל-tags
export AWS_REQUEST_PAYER_TAG="team:backend|developer:alice|project:api-v2"
# Bedrock supports user-defined tags per model invocation
# ב-Cost Explorer: filter by tag "team" ל-chargeback accuracy
הרץ: ls /var/log/claude/ 2>/dev/null || mkdir -p /var/log/claude. אחרי ה-devcontainer שלך עולה — בדוק אם יש audit log בנתיב הזה. אם לא — זהו gap ראשון. הוסף את hook script למעלה ל-.claude/hooks/post-tool-use.sh בפרויקט שלך ו-chmod +x.
Policy Enforcement ו-Enterprise Managed Policies
Enterprise plan של Anthropic מוסיף שכבת שליטה ארגונית מעל לכל הגדרה של משתמש. זו לא "recommendation" — זו enforcement. מנהל שמגדיר deny על פקודה — המשתמש לא יכול לפתוח אותה, גם אם ינסה.
Settings Cascade
Priority (highest to lowest):
1. Enterprise Managed Policy ← מנהל ארגוני, לא ניתן לדרוס
2. User Allow Rules ← המשתמש מוסיף permissions מורשות
3. Project Settings (CLAUDE.md) ← הגדרות ברמת הפרויקט
4. Defaults ← ברירות מחדל של Claude Code
הדגמה: אם ה-Enterprise policy אומר "bash:rm -rf:deny" — גם אם המשתמש הוסיף allow rule ב-settings האישיות שלו, הפקודה חסומה. אי-אפשר לדרוס policy ארגונית.
Enterprise Policy Configuration
Enterprise policies מוגדרות ב-Anthropic Console ברמת הארגון:
# enterprise-policy.json (example — managed via Anthropic Console UI)
{
"organization": "my-corp",
"policies": {
"bash": {
"allowed": true,
"denied_patterns": [
"rm -rf",
"curl | bash",
"wget.*sh.*|.*bash",
"chmod 777",
"sudo",
"su -"
]
},
"network": {
"allowed_domains": [
"api.anthropic.com",
"registry.npmjs.org",
"github.com",
"*.your-corp-internal.com"
],
"deny_all_others": true
},
"file_access": {
"denied_paths": [
"/etc",
"/var/run",
"**/.ssh",
"**/.aws/credentials"
]
},
"required_tools": [
"code-review-mcp" // All agents must load this MCP server
],
"audit": {
"enabled": true,
"webhook_url": "https://audit.your-corp.com/claude-code"
}
},
"sso": {
"provider": "okta",
"saml_entity_id": "https://your-corp.okta.com",
"require_mfa": true
}
}
SSO Integration
Enterprise plan תומך ב-SAML 2.0 ו-OIDC. Developers מתחברים ל-Claude Code עם חשבון ארגוני — אין API keys אישיים:
# בלי SSO — developer מנהל API key אישי:
export ANTHROPIC_API_KEY=sk-ant-api03-personal-key-...
# עם SSO — developer מתחבר דרך Okta/Azure AD:
claude login --sso --provider okta --org my-corp
# → פותח browser, מתחבר עם חשבון ארגוני
# → Claude Code מקבל session token אוטומטי
# → אין API keys אישיים שיכולים להיחשף
Policy כ-Code ב-CLAUDE.md
ברמת הפרויקט, כל מה שב-Enterprise policy אפשר גם להגדיר ב-CLAUDE.md:
# CLAUDE.md — Project-level policy
## Security Rules (cannot be overridden by user prompts)
- Never execute: rm -rf, curl | bash, chmod 777
- Never read: .env, *.key, *.pem, .ssh/
- Never write outside: ./src, ./tests, ./docs
- Always run tests before marking task complete
- Always create a git commit message for each change
## Compliance
- Never include PII in outputs or logs
- Never hardcode credentials
- Flag any code that handles payment data for manual review
## Required Tools
- Load MCP server: code-review at mcp://review.your-corp.com
| רמה | מנגנון | מי מגדיר | ניתן לדרוס |
|---|---|---|---|
| Enterprise | Anthropic Console Managed Policies | Security/Platform Admin | לא בשום אופן |
| Project | CLAUDE.md ב-repo | Tech Lead | רק על ידי מי שיש לו git push |
| Container | init-firewall.sh + Docker config | DevOps Engineer | רק מי שיוצר את ה-image |
| User | ~/.claude/settings.json | Developer | כן — בתוך מה שEnterprise מאפשר |
בדוק את ה-CLAUDE.md הקיים בפרויקט שלך. האם יש בו Security Rules? אם לא — הוסף מקטע ## Security Rules עם לפחות 3 כללים רלוונטיים לפרויקט שלך: מה אסור לקרוא, מה אסור לכתוב, ואיזו פקודה מסוכנת אסור להריץ.
CI/CD בתוך Containers
בפרק 6 בניתם CI/CD pipelines. עכשיו מריצים אותם בתוך Docker containers — כך ה-pipeline עצמו מבודד, reproducible, ומוגן.
GitHub Actions עם Docker Container
# .github/workflows/claude-enterprise.yml
name: Claude Code Enterprise Pipeline
on:
push:
branches: [main]
pull_request:
types: [opened, synchronize]
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}/claude-code-ci
jobs:
build-image:
runs-on: ubuntu-latest
permissions:
packages: write
outputs:
image-digest: ${{ steps.build.outputs.digest }}
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push Claude Code CI image
id: build
uses: docker/build-push-action@v5
with:
context: .devcontainer
file: .devcontainer/Dockerfile
push: true
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
cache-from: type=gha
cache-to: type=gha,mode=max
claude-review:
needs: build-image
runs-on: ubuntu-latest
container:
image: ${{ needs.build-image.outputs.image-digest }}
options: >-
--user 1000:1000
--cap-drop ALL
--security-opt no-new-privileges
--memory 4g
--cpus 2
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
PROJECT_NAME: ${{ github.repository }}
DEVELOPER_NAME: ci-bot
TEAM_NAME: platform
steps:
- uses: actions/checkout@v4
- name: Initialize firewall
run: bash .devcontainer/init-firewall.sh
- name: Run Claude Code review
run: |
claude -p "Review the changes in this PR. Focus on:
1. Security vulnerabilities
2. Performance regressions
3. Missing test coverage
Output a structured JSON report to /workspace/output/review.json" \
--bare --output-format json
- name: Upload review results
uses: actions/upload-artifact@v4
with:
name: claude-review
path: /workspace/output/review.json
- name: Post review as PR comment
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const review = require('/workspace/output/review.json');
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: `## Claude Code Review\n${review.summary}\n\n${review.details}`
});
security-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Scan Claude Code image for vulnerabilities
uses: aquasecurity/trivy-action@master
with:
image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
exit-code: 1
severity: HIGH,CRITICAL
format: sarif
output: trivy-results.sarif
- uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: trivy-results.sarif
ב-CI/CD, שימוש ב-:latest כ-image tag אומר שכל build מושך image שונה. pipeline שעבד ב-production אמש עלול להישבר היום עקב שינוי ב-base image. תמיד pin ל-digest ספציפי ב-CI: image@sha256:abc123.... עדכון ה-image צריך להיות פעולה מכוונת, לא תופעת לוואי של pull.
אימוץ ארגוני — 3 פאזות
מ-pilot של 3 מפתחים ל-deployment ארגוני מלא — הדרך הזו עוברת 3 פאזות. דילוג על פאזה = כישלון צפוי. כל פאזה מספקת data לפאזה הבאה.
Phase 1 — Pilot (שבועות 1-4)
מי: 2-5 מפתחים early adopters על פרויקטים לא-קריטיים.
מה מגדירים: devcontainer בסיסי, CLAUDE.md לפרויקט, structured logging.
מה מודדים:
- זמן ממוצע per PR — לפני ואחרי
- זמן ממוצע per feature — לפני ואחרי
- שביעות רצון developers (1-10)
- עלות API חודשית
- בעיות אבטחה שעלו (hopefully zero)
Go/No-Go gate: 20%+ improvement בלפחות 2 מדדים.
Phase 2 — Team (חודשים 2-3)
מי: צוות שלם (5-20 מפתחים).
מה מגדירים: CLAUDE.md משותף ב-repo, docker-compose.yml לצוות, hooks, CI/CD integration, audit logging.
מה מוסיפים:
- Code review automation (מפרק 6) רץ ב-Docker
- Cost tracking per developer
- Shared output volumes לתוצרים משותפים
- Workshop: 2 שעות — הצגת best practices, common mistakes
Go/No-Go gate: 90% adoption rate, cost per developer יציב ומתוקצב.
Phase 3 — Organization (חודשים 4-6)
מי: כל הארגון, כולל non-technical teams.
מה מגדירים: Enterprise plan, managed policies, SSO, K8s deployment, Bedrock/Vertex לdata residency.
מה מוסיפים:
- Centralized audit logging → SIEM
- Per-team cost allocation ו-chargeback
- Compliance review: SOC 2, GDPR, HIPAA לפי הצורך
- Cowork לteams לא-טכניים (product, design, marketing)
Change Management — איך לטפל בחששות
| חשש נפוץ | תשובה מבוססת נתונים |
|---|---|
| "Claude Code יחליף אותי" | Claude Code מגביר productivity, לא מחליף judgment. הביאו data מPhase 1 — מפתחים עשו יותר, לא פחות, עבודות מעניינות. |
| "הקוד שלו לא מאובטח" | Docker + policy enforcement + code review = output עובר אותו review כמו כל קוד אחר. ה-agent לא bypass את ה-PR process. |
| "הנתונים שלנו עוברים ל-Anthropic" | Bedrock/Vertex: data לא יוצא מה-VPC שלכם. Enterprise plan: data retention controls. |
| "זה יקר מדי" | הציגו ROI מ-Phase 1: $X עלות, Y hours שנחסכו × שכר ממוצע = Z חיסכון חודשי. |
- כתב Phase 1 plan: מי 2-5 המפתחים הראשונים? באיזה פרויקט? מה 3 ה-KPIs שתמדוד?
- הכן "before" baseline: מדוד זמן ממוצע על משימה נבחרת עכשיו, לפני Claude Code
- כתב Phase 2 checklist: מה צריך להיות מוכן לפני שהצוות מתחיל?
- בנה ROI calculation: אם Phase 1 מראה 25% improvement ב-PR cycle time, כמה שעות נחסכות לחודש? מה הערך ב-$?
- הכן תשובות ל-3 חששות נפוצים של הצוות שלך (לא generic — ספציפי לסביבה שלך)
- קבע תאריך ל-go/no-go gate של Phase 1
תוצר: מסמך adoption plan 1 עמוד עם Phase 1 specifics, baseline metrics ו-ROI projection.
Compliance ו-Data Governance
לפני deployment בסביבות מוסדרות, צריך לתעד שכל control הרלוונטי קיים. זה לא theoretical — ה-checklist הזה הוא מה שה-auditor שואל.
Data Residency
| דרישה | פתרון ב-Claude Code | אימות |
|---|---|---|
| Data נשאר ב-EU | Vertex AI ב-EU region / Bedrock ב-eu-west-1 | VPC endpoint logs, region config |
| Data לא עובר Anthropic infra | Bedrock/Vertex routing בלבד | Network flow logs, no direct API calls |
| Conversation logs מוגבלים | Enterprise plan — data retention controls | Audit trail מ-Anthropic Console |
PII Handling
# CLAUDE.md — PII Protection Rules
## PII Policy (MANDATORY — applies to all sessions)
- Never include names, emails, phone numbers, or SSNs in outputs
- Never log or store user-provided data beyond task completion
- If task involves PII dataset — work only with anonymized samples
- Flag any code that processes PII for privacy review before commit
- Output files must not contain PII — use identifiers only
PII detection hook (pre-tool-use):
#!/bin/bash
# pre-tool-use.sh — Block PII patterns before file write
if [ "$CLAUDE_TOOL_NAME" = "Write" ]; then
OUTPUT="${CLAUDE_TOOL_INPUT:-}"
# Check for common PII patterns
if echo "$OUTPUT" | grep -qE '[0-9]{3}-[0-9]{2}-[0-9]{4}'; then # SSN
echo "BLOCKED: Output contains SSN pattern" >&2
exit 1
fi
if echo "$OUTPUT" | grep -qE '\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b'; then # Email
echo "WARNING: Output may contain email addresses — verify before write" >&2
fi
fi
Regulatory Mapping
| Regulation | Claude Code Control | מיושם? |
|---|---|---|
| GDPR — Data Minimization | PII hooks, output review | ☐ |
| GDPR — Data Residency | Bedrock/Vertex EU region | ☐ |
| HIPAA — PHI Protection | Air-gapped VPC, no PHI in prompts policy | ☐ |
| SOC 2 — Audit Trail | Structured logging → SIEM | ☐ |
| SOC 2 — Access Control | SSO + managed policies | ☐ |
| PCI-DSS — Cardholder data | Block card patterns in hooks, manual flag | ☐ |
| FedRAMP | Bedrock GovCloud region | ☐ |
העתק את הטבלה Regulatory Mapping ל-document workspace שלך. סמן אילו regulations רלוונטיות לארגון שלך. לכל regulation רלוונטית — בדוק האם ה-control קיים כבר. כל ☐ שנשאר ריק = פעולה שצריך לתכנן לפני deployment.
יומי (1-3 משימות)
- בדוק Docker container health:
docker stats— memory, CPU, error rates (2 דקות) - בדוק audit log:
tail -20 /var/log/claude/audit.jsonl | jq .— anomalies, errors (3 דקות) - Pipeline logs מפרק 6: הצלחות, כישלונות, עלויות (2 דקות)
שבועי (3-5 משימות)
- הרץ cost-report.sh — בדוק cost per team ו-per developer, שלח לmanagers (10 דקות)
- סרוק Docker images:
trivy image your-claude-image:latest— טפל ב-HIGH/CRITICAL (15 דקות) - בדוק K8s pod restarts:
kubectl get pods -n claude-agents— investigate restarts (5 דקות) - עדכן CLAUDE.md policies: האם הכללים עדיין רלוונטיים? הוסף כללים חדשים שצצו (10 דקות)
חודשי (2-4 משימות)
- Rotate credentials: ANTHROPIC_API_KEY ו-SSH keys — update ב-Vault/AWS SM (20 דקות)
- Compliance review: בדוק audit logs — האם כל controls עובדים? הכן monthly compliance summary (30 דקות)
- Update base images: בדוק node:20-slim עדכנים, rebuild ו-test (20 דקות)
- Phase review: אם ב-Phase 1 או 2 — evaluate go/no-go ל-phase הבאה (30 דקות)
צור devcontainer מאובטח לפרויקט שלך. העתק את שלושת הקבצים: devcontainer.json, Dockerfile, init-firewall.sh. פתח ב-VS Code, הרץ claude -p "test from container" --bare, ובדוק ש-iptables active. זה הצעד הראשון שממנו כל השאר — Kubernetes, secrets management, enterprise policies — מתוסף בהדרגה בלי לשנות את הארכיטקטורה.
- למה
--dangerously-skip-permissionsסביר ב-Docker container אבל מסוכן על מכונה רגילה? (רמז: ה-container הוא ה-sandbox) - איזו שורה אחת ב-Dockerfile עלולה לחשוף את ה-API key לכל מי שמושך את ה-image? (רמז: ENV)
- מה ההבדל בין K8s ConfigMap ל-K8s Secret, ומה שומרים בכל אחד? (רמז: encryption at rest)
- מדוע WebSearch לא עובד דרך Bedrock/Vertex, ואיך מתכננים hybrid routing? (רמז: built-in tools vs model calls)
- מה settings cascade אומר בפועל — אם enterprise policy חוסמת פקודה, האם user allow rule יכולה לפתוח אותה? (רמז: לא)
- מה הסיבה שלא לשמור output ב-bind mount לhost path, אלא ב-named volume? (רמז: sandbox escape)
- בתוכנית 3-פאזות — למה go/no-go gate אחרי Phase 1 קריטי? (רמז: data before scale)
5 מתוך 7 נכונות — עברתם. 7 מתוך 7 — מוכנים לספר את זה ב-interview.
Docker ו-enterprise infrastructure הם מה שמפרידים בין proof-of-concept ל-production מוסדר. התחלנו מהיחידה הקטנה ביותר — devcontainer.json + Dockerfile + init-firewall.sh — שמספקת isolation, reproducibility ו-auditability בפחות מ-20 דקות הקמה. מכאן הרחבנו: volume mounts עם הרשאות מינימליות, secrets management שאף פעם לא שומר credentials ב-image, Kubernetes שמאפשר multi-session לצוות שלם עם resource quotas ו-RBAC, ו-cloud providers (Bedrock, Vertex) שמאפשרים air-gapped deployments לדרישות data residency.
Audit logging ו-cost allocation נותנים visibility מוחלטת — מי עשה מה, כמה זה עלה, לאיזה פרויקט. Enterprise Managed Policies ו-SSO הופכים compliance ל-enforcement: לא policy שמבקשים מאנשים לכבד, אלא technical control שלא ניתן לעקוף. הכלל: כל שכבת אבטחה מוסיפה overhead — התחל מהמינימום הנחוץ (Docker + firewall) ותוסיף שכבות רק כשיש דרישה ספציפית.
בפרק הבא: פרק 8 — פרק האחרון בקורס. נסתכל קדימה: לאן Claude Code הולך ב-12-18 החודשים הבאים, מה המיומנויות שישרדו שינויי מודלים, ואיך לבנות קריירה סביב AI-first development בעידן ש-MCP ו-multi-agent הם הנורמה.
- ☐ יצרתי .devcontainer/ עם devcontainer.json, Dockerfile, init-firewall.sh
- ☐ הרצתי Claude Code בתוך Docker container ב-VS Code בהצלחה
- ☐ בדקתי firewall פעיל:
iptables -L OUTPUT -nמציג rules - ☐ וידאתי שכל מounts ל-source code הם read-only
- ☐ אין API keys ב-Dockerfile (רק
remoteEnv) - ☐ הגדרתי resource limits: memory + CPU + pids-limit
- ☐ container רץ כ-non-root user
- ☐ הגדרתי docker-compose.yml לצוות (או K8s YAML לסביבת enterprise)
- ☐ בחרתי Vault / AWS SM / Docker Secrets לניהול credentials
- ☐ הגדרתי audit logging → /var/log/claude/audit.jsonl
- ☐ כתבתי Security Rules ב-CLAUDE.md
- ☐ הכנתי adoption plan 3-פאזות עם Phase 1 specifics ו-go/no-go gate
- ☐ מיפיתי regulations רלוונטיות ו-controls קיימים