Container security
π Professional Multi-Agent Skills
npx -y skills add kinhluan/skills --skill container-securityAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Container and Kubernetes security hardening, image scanning, runtime protection, and supply chain security. Use when securing Docker containers, Kubernetes clusters, scanning images for vulnerabilities, or implementing runtime security controls.
SKILL.md
11.4 KB, as published. Nobody here has run it
Container Security
Comprehensive container and Kubernetes security: image hardening, runtime protection, supply chain security, and cluster hardening.
"Containers are only as secure as the images they run and the clusters that orchestrate them."
π― When to Use
- Securing Docker containers and images
- Hardening Kubernetes clusters
- Scanning container images for vulnerabilities
- Implementing runtime security (Falco, Sysdig)
- Supply chain security (Sigstore, SLSA)
- Pod Security Standards enforcement
- Network policies for microservices
π³ Docker Security
Image Hardening
# Multi-stage build for minimal attack surface
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o main .
# Distroless final image
FROM gcr.io/distroless/static:nonroot
COPY --from=builder /app/main /main
USER nonroot:nonroot
EXPOSE 8080
ENTRYPOINT ["/main"]
# Security best practices
FROM node:20-alpine
# Run as non-root
RUN addgroup -g 1001 -S nodejs && \
adduser -S nodejs -u 1001
# Install only production dependencies
COPY package*.json ./
RUN npm ci --only=production && npm cache clean --force
# Copy application with correct ownership
COPY --chown=nodejs:nodejs . /app
WORKDIR /app
USER nodejs
# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD node healthcheck.js || exit 1
EXPOSE 3000
CMD ["node", "server.js"]
Docker Security Options
# Run with security options
docker run \
--read-only \
--security-opt=no-new-privileges:true \
--cap-drop=ALL \
--cap-add=NET_BIND_SERVICE \
--memory=512m \
--memory-swap=512m \
--cpus=1.0 \
--pids-limit=100 \
--user 1000:1000 \
myapp:latest
# Disable inter-container communication
docker network create --internal --subnet 172.18.0.0/16 isolated-network
Image Scanning
# Trivy
trivy image myapp:latest
trivy image --severity HIGH,CRITICAL myapp:latest
trivy image --format sarif -o report.sarif myapp:latest
# Snyk
snyk container test myapp:latest
snyk container test --severity-threshold=high myapp:latest
# Clair
clairctl report myapp:latest
# Grype
grype myapp:latest
grype myapp:latest -o sarif > grype-report.sarif
Dockerfile Security Audit
# Check for common issues
dockerfilelint Dockerfile
# Hadolint
hadolint Dockerfile
# Checkov for Docker
checkov -f Dockerfile --framework dockerfile
βΈοΈ Kubernetes Security
RBAC Configuration
# Least-privilege ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
name: app-sa
namespace: production
automountServiceAccountToken: false
---
# Role with minimal permissions
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: app-role
namespace: production
rules:
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "list"]
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get"]
resourceNames: ["app-config"]
---
# RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: app-rolebinding
namespace: production
subjects:
- kind: ServiceAccount
name: app-sa
namespace: production
roleRef:
kind: Role
name: app-role
apiGroup: rbac.authorization.k8s.io
Pod Security Standards
# Restricted Pod Security Standard
apiVersion: v1
kind: Pod
metadata:
name: secure-app
namespace: production
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
seccompProfile:
type: RuntimeDefault
containers:
- name: app
image: myapp:latest
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
resources:
limits:
memory: "256Mi"
cpu: "500m"
requests:
memory: "128Mi"
cpu: "250m"
volumeMounts:
- name: tmp
mountPath: /tmp
- name: cache
mountPath: /cache
volumes:
- name: tmp
emptyDir: {}
- name: cache
emptyDir: {}
Network Policies
# Deny all by default
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
---
# Allow frontend to backend
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: frontend-to-backend
namespace: production
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
---
# Allow backend to database only
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: backend-to-db
namespace: production
spec:
podSelector:
matchLabels:
app: database
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: backend
ports:
- protocol: TCP
port: 5432
Secrets Management
# External Secrets Operator (recommended)
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: app-secrets
namespace: production
spec:
refreshInterval: 1h
secretStoreRef:
kind: ClusterSecretStore
name: aws-secrets-manager
target:
name: app-secrets
creationPolicy: Owner
data:
- secretKey: DATABASE_URL
remoteRef:
key: production/app
property: database_url
- secretKey: API_KEY
remoteRef:
key: production/app
property: api_key
# Never store secrets in plain text
# Check for secrets in manifests
grep -r "password:" ./k8s/
grep -r "secret:" ./k8s/
grep -r "token:" ./k8s/
# Use sealed secrets for GitOps
kubeseal --format=yaml < secret.yaml > sealed-secret.yaml
π Supply Chain Security
Image Signing & Verification
# Cosign (Sigstore)
cosign generate-key-pair
cosign sign --key cosign.key myregistry/myapp:latest
cosign verify --key cosign.pub myregistry/myapp:latest
# SLSA provenance
cosign attest --predicate slsa-provenance.json --type slsaprovenance myregistry/myapp:latest
# Verify SLSA
slsa-verifier verify-image myregistry/myapp:latest \
--source-uri github.com/myorg/myrepo \
--print-provenance
SBOM Generation
# Syft
syft myapp:latest -o spdx-json > sbom.spdx.json
syft myapp:latest -o cyclonedx-json > sbom.cyclonedx.json
# Trivy SBOM
trivy image --format cyclonedx -o sbom.cyclonedx.json myapp:latest
# Grype SBOM
grype myapp:latest -o cyclonedx-json > sbom.cyclonedx.json
Admission Controllers
# Kyverno policy: require labels
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-labels
spec:
validationFailureAction: enforce
rules:
- name: check-for-labels
match:
resources:
kinds:
- Pod
validate:
message: "All pods must have app and version labels"
pattern:
metadata:
labels:
app: "?*"
version: "?*"
---
# OPA Gatekeeper: disallow privileged containers
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
name: k8spspprivilegedcontainer
spec:
crd:
spec:
names:
kind: K8sPSPPrivilegedContainer
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8spspprivilegedcontainer
violation[{"msg": msg}] {
c := input.review.object.spec.containers[_]
c.securityContext.privileged
msg := sprintf("Privileged container is not allowed: %v", [c.name])
}
π‘οΈ Runtime Security
Falco
# Falco rule: detect shell in container
- rule: Terminal Shell in Container
desc: Detect shell execution inside a container
condition: spawned_process and container and shell_procs
output: "Shell spawned in container (user=%user.name container=%container.name)"
priority: WARNING
# Falco rule: detect privilege escalation
- rule: Privilege Escalation
desc: Detect privilege escalation via setuid/setgid
condition: spawned_process and (setuid or setgid)
output: "Privilege escalation detected (user=%user.name command=%proc.cmdline)"
priority: CRITICAL
# Install Falco
helm repo add falcosecurity https://falcosecurity.github.io/charts
helm install falco falcosecurity/falco \
--set driver.kind=modern_ebpf \
--set tty=true
# Check Falco alerts
kubectl logs -l app=falco -n falco | grep "Warning\|Critical"
Runtime Monitoring
# Sysdig
sysdig -p"%evt.time %proc.name %fd.name" evt.type=open
# Check for suspicious processes in containers
kubectl get pods --all-namespaces -o json | jq '.items[].spec.containers[].securityContext'
# Audit pod security contexts
kubectl get pods -o json | jq '.items[] | {name: .metadata.name, securityContext: .spec.securityContext, containers: [.spec.containers[] | {name: .name, securityContext: .securityContext}]}'
π Security Checklist
Image Security
- Use minimal base images (distroless, alpine, scratch)
- Run as non-root user
- Scan images for CVEs before deployment
- Sign images with Cosign
- Generate and store SBOMs
- Use multi-stage builds
- Pin base image versions (no
latest) - Remove unnecessary packages and tools
Kubernetes Security
- Enable Pod Security Standards (Restricted)
- Implement Network Policies (deny-all default)
- Use RBAC with least privilege
- Disable automountServiceAccountToken where not needed
- Enable audit logging
- Use external secrets management (not plain YAML)
- Enable admission controllers (Kyverno/OPA)
- Regular cluster security scanning (kube-bench, kube-hunter)
Runtime Security
- Deploy Falco for runtime threat detection
- Monitor for privilege escalation
- Alert on unexpected network connections
- Track container drift (file changes)
- Monitor resource usage anomalies
π οΈ Tools Reference
| Tool | Purpose |
|---|---|
| Trivy | Container image & filesystem scanning |
| Grype | Vulnerability scanner for containers |
| Snyk | Container & dependency scanning |
| Clair | Static vulnerability analysis |
| Cosign | Container image signing (Sigstore) |
| Syft | SBOM generation |
| Falco | Runtime threat detection |
| Sysdig | Container monitoring & forensics |
| kube-bench | CIS Kubernetes benchmark |
| kube-hunter | Kubernetes penetration testing |
| Kyverno | Kubernetes policy engine |
| OPA Gatekeeper | Policy enforcement |
| Sealed Secrets | Encrypt secrets for GitOps |
| External Secrets Operator | Sync secrets from external providers |