<!-- 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 tags: [ai, security] ---
Install to Claude Code
npx -y skills add frank-luongt/faos-skills-marketplace --skill container-security-guide --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Container Security Guide?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/frank-luongt-container-security-guide)More formats (shields.io, HTML) on the badges page.
<!-- 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
tags: [ai, security]
---
# 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 | 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.
## When to Use This Skill
- You are writing or reviewing Dockerfiles for production services
- You are configuring Kubernetes security settings (PodSecurityStandards, NetworkPolicies, RBAC)
- You need to harden a container runtime environment against known attack vectors
- You are building a CI/CD pipeline and need image scanning and signing gates
- You are investigating a container security incident or preparing for an audit
- You want to implement defense-in-depth for containerized microservices
## How It Works
### Step 1: Scan Container Images
Scan images for known vulnerabilities before they reach production:
```bash
# 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:
```yaml
# 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
```
### Step 2: Harden Dockerfiles
Build minimal, secure container images following these principles:
- Use minimal base images (distroless, Alpine, or scratch)
- Run as non-root user
- Use multi-stage builds to exclude build tools from production images
- Never embed secrets, credentials, or private keys in images
- Pin base image versions with digest for reproducibility
- Set the filesystem to read-only where possible
- Include health checks for orchestrator integration
### Step 3: Apply PodSecurityStandards
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:
```bash
# 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
```
### Step 4: Configure NetworkPolicies
By default, all pods in a Kubernetes cluster can communicate with all other pods. NetworkPolicies implement microsegmentation:
- Start with a default-deny policy for all namespaces
- Explicitly allow only required communication paths
- Use label selectors for fine-grained pod-to-pod rules
- Allow DNS resolution (kube-dns) in every policy
### Step 5: Enable Runtime Monitoring
Runtime security tools detect anomalous container behavior:
```bash
# 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 |
## Examples
### Example 1: Secure Dockerfile for Python FastAPI App
```dockerfile
# ============================================
# 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 |
### Example 2: Kubernetes NetworkPolicy for Namespace Isolation
```yaml
# 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
```
### Example 3: PodSecurityStandard (Restricted) Configuration
```yaml
# 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
```
## Best Practices
### Do This
- Use distroless or slim base images to minimize the attack surface
- Scan images in CI/CD and block deployments with critical or high vulnerabilities
- Sign images with cosign or Notary and verify signatures with Binary Authorization
- Run all containers as non-root with `runAsNonRoot: true`
- Drop all Linux capabilities with `capabilities.drop: [ALL]`
- Set `readOnlyRootFilesystem: true` and mount writable directories as emptyDir volumes
- Apply PodSecurityStandards at `restricted` level for production namespaces
- Implement default-deny NetworkPolicies in every namespace
- Use external secret managers (GCP Secret Manager, HashiCorp Vault) instead of K8s Secrets
- Pin image references by digest (`@sha256:...`) rather than mutable tags
- Enable Seccomp profiles (at minimum `RuntimeDefault`) for all containers
- Implement pod disruption budgets alongside security to maintain availability
### Don't Do This
- Do not use `latest` tag for production images -- it is mutable and unpredictable
- Do not run containers as root or with `privileged: true`
- Do not embed secrets, API keys, or credentials in Docker images
- Do not expose the Docker socket (`/var/run/docker.sock`) to containers
- Do not use `hostPID`, `hostNetwork`, or `hostIPC` unless absolutely required
- Do not skip NetworkPolicies -- default Kubernetes networking allows unrestricted pod-to-pod traffic
- Do not grant `cluster-admin` ClusterRole to application service accounts
- Do not auto-mount service account tokens (`automountServiceAccountToken: false` by default)
- Do not install shells (bash, sh) in production images if they are not needed
- Do not use package managers (apt, apk) at runtime -- install everything at build time
## Security Checklist
### Image Security
- [ ] Base images are minimal (distroless, Alpine, or slim variants)
- [ ] Images are scanned for vulnerabilities in CI/CD with a blocking gate
- [ ] No secrets, credentials, or private keys are embedded in images
- [ ] Multi-stage builds exclude build tools from production images
- [ ] Images are signed and verified before deployment (cosign / Binary Authorization)
- [ ] Image references use digests (`@sha256:...`) not mutable tags
- [ ] Base images are regularly updated to include security patches
### Build Security
- [ ] Dockerfiles use a non-root USER directive
- [ ] `.dockerignore` excludes `.env`, `.git`, `node_modules`, and other sensitive files
- [ ] Build arguments do not contain secrets (use BuildKit secret mounts instead)
- [ ] Layer caching does not leak sensitive data between stages
- [ ] HEALTHCHECK is defined for orchestrator integration
### Runtime Security
- [ ] All containers run as non-root (`runAsNonRoot: true`)
- [ ] All capabilities are dropped (`capabilities.drop: [ALL]`)
- [ ] Root filesystem is read-only (`readOnlyRootFilesystem: true`)
- [ ] Seccomp profile is set to `RuntimeDefault` or a custom profile
- [ ] Resource requests and limits are defined for all containers
- [ ] Service account tokens are not auto-mounted unless required
### Kubernetes Security
- [ ] PodSecurityStandards are enforced at `restricted` or `baseline` level
- [ ] Default-deny NetworkPolicies are applied in every namespace
- [ ] RBAC follows least privilege -- no broad ClusterRole bindings
- [ ] Admission controllers validate configurations before deployment
- [ ] Secrets are managed externally (GCP Secret Manager, Vault, ExternalSecrets)
- [ ] Pod disruption budgets ensure availability during security updates
- [ ] Runtime monitoring (Falco or equivalent) is deployed
## Related Skills
- @cis-benchmarks -- CIS Docker and Kubernetes Benchmark automated scanning
- @cloud-security-patterns -- cloud-native security architectures for GCP, AWS, Azure
- @owasp-top10 -- application-layer security for containerized web applications
## Additional Resources
- [NIST SP 800-190](https://csrc.nist.gov/publications/detail/sp/800-190/final) -- Application Container Security Guide
- [Kubernetes Pod Security Standards](https://kubernetes.io/docs/concepts/security/pod-security-standards/) -- official PSS documentation
- [Docker Security Best Practices](https://docs.docker.com/develop/security-best-practices/) -- official Docker guidance
- [Kubernetes Network Policies](https://kubernetes.io/docs/concepts/services-networking/network-policies/) -- NetworkPolicy reference
- [Falco Runtime Security](https://falco.org/) -- open-source container runtime threat detection
- [cosign](https://github.com/sigstore/cosign) -- container image signing and verification
- [Trivy](https://github.com/aquasecurity/trivy) -- comprehensive container vulnerability scanner
- [GKE Security Overview](https://cloud.google.com/kubernetes-engine/docs/concepts/security-overview) -- GKE-specific security features
<!-- Source: .faos/custom/skills/security/container-security-guide/SKILL.md -->
Scanned 6/6/2026
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!