Back to skills
SKILL.md
Container Security Guide
CSecurity<!-- 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 ---
- 31 stars
- 0 votes
- 0 copies
- 1 view
- Added September 6, 2026
Works with
Security analysis
60/100- Uses curl or wget to download content
- Accesses sensitive system or user directories
- Performs destructive filesystem operations
- Exfiltrates credentials via HTTP — exact pattern from Snyk ToxicSkills study
- Installs packages at runtime which could introduce malicious dependencies
Pro scans all 2 files and shows the line behind each finding
npx -y skills add frank-luongt/faos-skills-marketplace --skill container-security-guide --agent claude-codeAre you the author of Container Security Guide?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/frank-luongt-container-security-guide-b197f209)<!-- 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 | 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 -->
Files in this skill
- SKILL.md
- agents/openai.yaml
Attribution
Comments
Loading comments…