skills/codex/container-security-guide/SKILL.md
<!-- AUTO-GENERATED by export-skills.py — DO NOT EDIT --> --- name: container-security-guide description: Docker and Kubernetes security hardening guide covering images, builds, runtime, and orchestration --- # Container Security Guide ## Overview Containers introduce a unique attack surface spanning the image build pipeline, container runtime, orchestration layer, and host OS. Security must be applied at every stage of the container lifecycle: | Stage | Threats
npx skillsauth add frank-luongt/faos-skills-marketplace skills/codex/container-security-guideInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Containers introduce a unique attack surface spanning the image build pipeline, container runtime, orchestration layer, and host OS. Security must be applied at every stage of the container lifecycle:
| Stage | Threats | Key Controls | |--------------|---------------------------------------------------|-------------------------------------| | Build | Malicious base images, embedded secrets, bloat | Minimal images, scanning, signing | | Registry | Image tampering, unauthorized access | Content trust, access control | | Deploy | Misconfigured pods, excessive privileges | Admission control, PodSecurity | | Runtime | Container escape, lateral movement, cryptomining | Seccomp, AppArmor, monitoring | | Orchestration| RBAC bypass, API server exposure, secret leaks | NetworkPolicy, RBAC, external secrets|
This guide covers Docker image and build security, Kubernetes-specific hardening, and runtime protection. It is tailored for teams running containerized workloads on GKE but applies broadly to any Kubernetes distribution.
Scan images for known vulnerabilities before they reach production:
# Trivy: comprehensive vulnerability scanner
trivy image --severity HIGH,CRITICAL faos-api:latest
# Grype: fast alternative scanner
grype faos-api:latest --only-fixed --fail-on high
# Snyk: SaaS scanner with fix suggestions
snyk container test faos-api:latest --severity-threshold=high
# GCP Artifact Registry: automatic scanning
gcloud artifacts docker images list-vulnerabilities \
REGION-docker.pkg.dev/PROJECT/REPO/my-app:latest \
--format=json | jq '.[] | select(.vulnerability.effectiveSeverity == "CRITICAL")'
Integrate scanning into CI/CD pipelines with a gate:
# GitHub Actions: scan and fail on critical vulnerabilities
- name: Scan container image
uses: aquasecurity/trivy-action@master
with:
image-ref: ${{ env.IMAGE }}
format: 'sarif'
output: 'trivy-results.sarif'
severity: 'CRITICAL,HIGH'
exit-code: '1' # Fail the build on findings
Build minimal, secure container images following these principles:
Kubernetes PodSecurityStandards (PSS) define three progressive security profiles:
| Profile | Level of Security | Use Case | |--------------|-------------------|------------------------------------| | Privileged | None | System-level workloads (kube-system)| | Baseline | Moderate | General workloads, prevents known escalations| | Restricted | Strict | Security-sensitive and multi-tenant workloads|
Apply PSS enforcement at the namespace level:
# Enforce restricted profile on production namespace
kubectl label namespace faos-api \
pod-security.kubernetes.io/enforce=restricted \
pod-security.kubernetes.io/enforce-version=latest \
pod-security.kubernetes.io/warn=restricted \
pod-security.kubernetes.io/audit=restricted
By default, all pods in a Kubernetes cluster can communicate with all other pods. NetworkPolicies implement microsegmentation:
Runtime security tools detect anomalous container behavior:
# Falco: runtime threat detection
helm repo add falcosecurity https://falcosecurity.github.io/charts
helm install falco falcosecurity/falco \
--namespace falco-system \
--create-namespace \
--set falcosidekick.enabled=true \
--set falcosidekick.config.slack.webhookurl=$SLACK_WEBHOOK
# Falco detects:
# - Shell spawned in container
# - Sensitive file access (/etc/shadow, /etc/passwd)
# - Unexpected network connections
# - Privilege escalation attempts
# - Cryptocurrency miner signatures
Runtime protection layers:
| Technology | Protection Level | Performance Impact | |-------------|-----------------------------------------|-------------------| | Seccomp | System call filtering | Minimal | | AppArmor | Mandatory access control profiles | Low | | SELinux | Type enforcement and RBAC | Low | | gVisor | User-space kernel (full syscall interception)| Moderate | | Kata | VM-level isolation per container | Higher |
# ============================================
# Stage 1: Build dependencies
# ============================================
FROM python:3.12-slim AS builder
# Install build dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
gcc \
libpq-dev \
&& rm -rf /var/lib/apt/lists/*
# Create virtual environment
RUN python -m venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
# Install Python dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir --upgrade pip && \
pip install --no-cache-dir -r requirements.txt
# ============================================
# Stage 2: Production image
# ============================================
FROM python:3.12-slim AS production
# Security: Create non-root user
RUN groupadd -r appuser && useradd -r -g appuser -d /app -s /sbin/nologin appuser
# Install only runtime dependencies (no gcc/build tools)
RUN apt-get update && apt-get install -y --no-install-recommends \
libpq5 \
curl \
&& rm -rf /var/lib/apt/lists/*
# Copy virtual environment from builder
COPY --from=builder /opt/venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
# Copy application code
WORKDIR /app
COPY --chown=appuser:appuser ./src ./src
# Security: No secrets in image (use env vars or mounted secrets)
# Security: Read-only filesystem compatible
# Security: Drop all capabilities in K8s securityContext
# Health check for Kubernetes probes
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
CMD curl -f http://localhost:8000/health || exit 1
# Security: Run as non-root user
USER appuser
# Security: Use exec form (no shell injection risk)
ENTRYPOINT ["uvicorn", "src.main:app"]
CMD ["--host", "0.0.0.0", "--port", "8000", "--workers", "4"]
Security features in this Dockerfile:
| Feature | Security Benefit |
|--------------------------|-----------------------------------------------------|
| Multi-stage build | Build tools not in production image (smaller attack surface)|
| python:3.12-slim | Minimal base image (fewer vulnerabilities) |
| Non-root user | Prevents container escape to host root |
| --no-cache-dir | No pip cache (smaller image, no cached credentials) |
| --no-install-recommends| Minimal OS packages |
| rm -rf /var/lib/apt | No package manager cache |
| Exec form ENTRYPOINT | No shell injection via CMD override |
| HEALTHCHECK | Enables K8s liveness/readiness probes |
# 1. Default deny all ingress and egress traffic
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: faos-api
spec:
podSelector: {} # Applies to all pods in namespace
policyTypes:
- Ingress
- Egress
---
# 2. Allow DNS resolution (required for service discovery)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-dns
namespace: faos-api
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
---
# 3. Allow ingress from gateway to API pods only
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-gateway-to-api
namespace: faos-api
spec:
podSelector:
matchLabels:
app: faos-api
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: faos-gateway
podSelector:
matchLabels:
app: gateway
ports:
- protocol: TCP
port: 8000
---
# 4. Allow API pods to reach database
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-api-to-database
namespace: faos-api
spec:
podSelector:
matchLabels:
app: faos-api
policyTypes:
- Egress
egress:
- to:
- ipBlock:
cidr: 10.0.0.0/8 # Cloud SQL private IP range
ports:
- protocol: TCP
port: 5432 # PostgreSQL
---
# 5. Allow API pods to reach Redis
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-api-to-redis
namespace: faos-api
spec:
podSelector:
matchLabels:
app: faos-api
policyTypes:
- Egress
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: faos-cache
podSelector:
matchLabels:
app: redis
ports:
- protocol: TCP
port: 6379
# Pod specification compliant with PSS restricted profile
apiVersion: apps/v1
kind: Deployment
metadata:
name: faos-api
namespace: faos-api
spec:
replicas: 3
selector:
matchLabels:
app: faos-api
template:
metadata:
labels:
app: faos-api
spec:
# Security: Use dedicated service account (not default)
serviceAccountName: my-app-sa
automountServiceAccountToken: false # Disable unless needed
# Security: Prevent privilege escalation via hostPID/hostNetwork
hostPID: false
hostNetwork: false
hostIPC: false
# Security: Set filesystem group for shared volumes
securityContext:
runAsNonRoot: true
runAsUser: 65534 # nobody user
runAsGroup: 65534
fsGroup: 65534
seccompProfile:
type: RuntimeDefault
containers:
- name: faos-api
image: REGION-docker.pkg.dev/PROJECT/REPO/my-app@sha256:abc123...
ports:
- containerPort: 8000
protocol: TCP
# Security: Container-level security context
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 65534
capabilities:
drop:
- ALL
seccompProfile:
type: RuntimeDefault
# Resource limits (prevent resource abuse)
resources:
requests:
cpu: 250m
memory: 256Mi
limits:
cpu: 1000m
memory: 512Mi
# Health probes
livenessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 10
periodSeconds: 30
readinessProbe:
httpGet:
path: /ready
port: 8000
initialDelaySeconds: 5
periodSeconds: 10
# Mount secrets from external secret manager (not K8s Secrets)
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: faos-api-secrets
key: database-url
# Writable directories for temp files (read-only root filesystem)
volumeMounts:
- name: tmp
mountPath: /tmp
- name: cache
mountPath: /app/.cache
volumes:
- name: tmp
emptyDir:
sizeLimit: 100Mi
- name: cache
emptyDir:
sizeLimit: 50Mi
runAsNonRoot: truecapabilities.drop: [ALL]readOnlyRootFilesystem: true and mount writable directories as emptyDir volumesrestricted level for production namespaces@sha256:...) rather than mutable tagsRuntimeDefault) for all containerslatest tag for production images -- it is mutable and unpredictableprivileged: true/var/run/docker.sock) to containershostPID, hostNetwork, or hostIPC unless absolutely requiredcluster-admin ClusterRole to application service accountsautomountServiceAccountToken: false by default)@sha256:...) not mutable tags.dockerignore excludes .env, .git, node_modules, and other sensitive filesrunAsNonRoot: true)capabilities.drop: [ALL])readOnlyRootFilesystem: true)RuntimeDefault or a custom profilerestricted or baseline leveldevelopment
<!-- AUTO-GENERATED by export-skills.py — DO NOT EDIT --> --- name: databricks-mlflow-evaluation --- # MLflow 3 GenAI Evaluation ## Before Writing Any Code 1. **Read GOTCHAS.md** - 15+ common mistakes that cause failures 2. **Read CRITICAL-interfaces.md** - Exact API signatures and data schemas ## End-to-End Workflows Follow these workflows based on your goal. Each step indicates which reference files to read. ### Workflow 1: First-Time Evaluation Setup For users new to MLflow GenAI evalu
development
<!-- AUTO-GENERATED by export-skills.py — DO NOT EDIT --> --- name: databricks-lakebase-provisioned --- # Lakebase Provisioned Patterns and best practices for using Lakebase Provisioned (Databricks managed PostgreSQL) for OLTP workloads. ## When to Use Use this skill when: - Building applications that need a PostgreSQL database for transactional workloads - Adding persistent state to Databricks Apps - Implementing reverse ETL from Delta Lake to an operational database - Storing chat/agent m
tools
<!-- AUTO-GENERATED by export-skills.py — DO NOT EDIT --> --- name: databricks-jobs --- # Databricks Lakeflow Jobs ## Overview Databricks Jobs orchestrate data workflows with multi-task DAGs, flexible triggers, and comprehensive monitoring. Jobs support diverse task types and can be managed via Python SDK, CLI, or Asset Bundles. ## Reference Files | Use Case | Reference File | | ----------------------
development
<!-- AUTO-GENERATED by export-skills.py — DO NOT EDIT --> --- name: databricks-genie --- # Databricks Genie Create and query Databricks Genie Spaces - natural language interfaces for SQL-based data exploration. ## Overview Genie Spaces allow users to ask natural language questions about structured data in Unity Catalog. The system translates questions into SQL queries, executes them on a SQL warehouse, and presents results conversationally. ## When to Use This Skill Use this skill when: -