Skip to content
Skills Library
Security · Review & audit

container-security

/container-security

Container and Kubernetes security: hardening images, runtime configuration and deployment manifests. USE WHEN: securing Docker containers, Kubernetes deployments, or reviewing container configurations DO NOT USE FOR: general Docker usage (use the `docker` skill), Kubernetes architecture (use the `kubernetes` skill)

Licence
MIT
Last repository change
21.10.2026

Assessment and security

100/ 100Class: good
Format25 / 25
Frontmatter with name and description, valid name, description up to 1,024 characters, name matching the folder.
Discoverability25 / 25
Description explains when to use the skill, has a reasonable length and uses third person.
Content35 / 35
At least 150 words and at most 500 lines, headings, step lists, examples or code.
Hygiene15 / 15
No placeholders such as TODO, no Windows paths, with a licence.
Riskno signals detected in the scan
Files in this package
1
Scripts
0
HTML comments
0
URLs in SKILL.md
2
Deprecation

No signals detected. Repository changed on 21.10.2026, without references to retired models or APIs.

Licence

MIT, open: use and modify while retaining author attribution.

What it does and when to use it

Container and Kubernetes security: hardening images, runtime configuration and deployment manifests. USE WHEN: securing Docker containers, Kubernetes deployments, or reviewing container configurations DO NOT USE FOR: general Docker usage (use the `docker` skill), Kubernetes architecture (use the `kubernetes` skill)

Original author description

Container and Kubernetes security: hardening images, runtime configuration and deployment manifests. USE WHEN: securing Docker containers, Kubernetes deployments, or reviewing container configurations DO NOT USE FOR: general Docker usage (use the `docker` skill), Kubernetes architecture (use the `kubernetes` skill)

How it works

  1. Docker Security Best Practices
  2. Container Runtime Security
  3. Kubernetes Security
  4. Container Scanning in CI/CD
  5. Security Scanning Tools Comparison
  6. Quick Reference Commands
Original SKILL.md headings · 444 lines, 1,025 words
SKILL.md preview
---
name: container-security
description: |
  Container and Kubernetes security: hardening images, runtime configuration and
  deployment manifests.

  USE WHEN: securing Docker containers, Kubernetes deployments, or reviewing container configurations

  DO NOT USE FOR: general Docker usage (use the `docker` skill), Kubernetes architecture (use the `kubernetes` skill)
allowed-tools: Read, Grep, Glob, Bash
---
# Container Security Skill

> **USE WHEN:** Securing Docker containers, Kubernetes deployments, or reviewing container configurations.
> **DO NOT USE FOR:** General Docker usage (use docker skill), Kubernetes architecture (use kubernetes skill).

## Docker Security Best Practices

### Dockerfile Hardening

```dockerfile
# Bad: Running as root
FROM node:20
WORKDIR /app
COPY . .
RUN npm install
CMD ["node", "server.js"]

# Good: Non-root user, minimal image, multi-stage
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build

FROM node:20-alpine
WORKDIR /app

# Create non-root user
RUN addgroup -g 1001 -S nodejs && \
    adduser -S nodejs -u 1001 -G nodejs

# Copy only necessary files
COPY --from=builder --chown=nodejs:nodejs /app/dist ./dist
COPY --from=builder --chown=nodejs:nodejs /app/node_modules ./node_modules
COPY --from=builder --chown=nodejs:nodejs /app/package.json ./

USER nodejs
EXPOSE 3000

# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1

CMD ["node", "dist/server.js"]
```

### Minimal Base Images

| Image Type | Security Level | Use Case |
|------------|----------------|----------|
| `scratch` | Highest | Go/Rust static binaries |
| `distroless` | Very High | Java, Node.js, Python |
| `alpine` | High | General purpose |
| `slim` | Medium | Debian minimal |
| `full` | Low | Development only |

```dockerfile
# Distroless for Java
FROM gcr.io/distroless/java21-debian12
COPY --chown=nonroot:nonroot target/app.jar /app.jar
USER nonroot
CMD ["app.jar"]

# Distroless for Node.js
FROM gcr.io/distroless/nodejs20-debian12
COPY --chown=nonroot:nonroot dist/ /app/
WORKDIR /app
USER nonroot
CMD ["server.js"]
```

### Image Scanning

```bash
# Trivy (comprehensive)
trivy image myapp:latest
trivy image --severity HIGH,CRITICAL myapp:latest
trivy image --ignore-unfixed myapp:latest

# Docker Scout
docker scout cves myapp:latest
docker scout recommendations myapp:latest

# Grype
grype myapp:latest

# Snyk
snyk container test myapp:latest
```

### Docker Daemon Security

```json
// /etc/docker/daemon.json
{
  "icc": false,
  "userns-remap": "default",
  "no-new-privileges": true,
  "live-restore": true,
  "userland-proxy": false,
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}
```

## Container Runtime Security

### Docker Run Security Options

```bash
# Bad: Full privileges
docker run --privileged myapp

# Good: Minimal privileges
docker run \
  --security-opt=no-new-privileges:true \
  --cap-drop=ALL \
  --cap-add=NET_BIND_SERVICE \
  --read-only \
  --tmpfs /tmp:rw,noexec,nosuid \
  --user 1001:1001 \
  --memory=512m \
  --cpu-shares=512 \
  --pids-limit=100 \
  myapp
```

### Capabilities Reference

| Capability | Purpose | Usually Needed |
|------------|---------|----------------|
| `NET_BIND_SERVICE` | Bind ports < 1024 | Sometimes |
| `CHOWN` | Change file ownership | Rarely |
| `SETUID/SETGID` | Change UID/GID | Rarely |
| `SYS_ADMIN` | Admin operations | Never in prod |
| `SYS_PTRACE` | Debugging | Never in prod |

### Docker Compose Security

```yaml
version: '3.8'

services:
  app:
    image: myapp:latest
    user: "1001:1001"
    read_only: true
    security_opt:
      - no-new-privileges:true
    cap_drop:
      - ALL
    cap_add:
      - NET_BIND_SERVICE
    tmpfs:
      - /tmp:rw,noexec,nosuid,size=64m
    deploy:
      resources:
        limits:
          cpus: '0.5'
          memory: 512M
          pids: 100
        reservations:
          memory: 256M
    healthcheck:
      test: ["CMD", "wget", "--spider", "-q", "http://localhost:3000/health"]
      interval: 30s
      timeout: 5s
      retries: 3
    networks:
      - internal
    secrets:
      - db_password

  db:
    image: postgres:16-alpine
    user: "70:70"  # postgres user
    volumes:
      - db_data:/var/lib/postgresql/data:rw
    environment:
      POSTGRES_PASSWORD_FILE: /run/secrets/db_password
    networks:
      - internal

networks:
  internal:
    driver: bridge
    internal: true

secrets:
  db_password:
    file: ./secrets/db_password.txt

volumes:
  db_data:
```

## Kubernetes Security

### Pod Security Standards

```yaml
# Restricted Pod (highest security)
apiVersion: v1
kind: Pod
metadata:
  name: secure-app
spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 1001
    runAsGroup: 1001
    fsGroup: 1001
    seccompProfile:
      type: RuntimeDefault
  containers:
    - name: app
      image: myapp:latest
      securityContext:
        allowPrivilegeEscalation: false
        readOnlyRootFilesystem: true
        capabilities:
          drop:
            - ALL
      resources:
        limits:
          cpu: "500m"
          memory: "512Mi"
          ephemeral-storage: "1Gi"
        requests:
          cpu: "100m"
          memory: "256Mi"
      volumeMounts:
        - name: tmp
          mountPath: /tmp
        - name: cache
          mountPath: /app/.cache
  volumes:
    - name: tmp
      emptyDir:
        medium: Memory
        sizeLimit: 64Mi
    - name: cache
      emptyDir:
        sizeLimit: 128Mi
  automountServiceAccountToken: false
```

### Pod Security Admission

```yaml
# Namespace with enforced security
apiVersion: v1
kind: Namespace
metadata:
  name: production
  labels:
    pod-security.kubernetes.io/enforce: restricted
    pod-security.kubernetes.io/enforce-version: latest
    pod-security.kubernetes.io/audit: restricted
    pod-security.kubernetes.io/warn: restricted
```

### Network Policies

```yaml
# Deny all by default
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
  namespace: production
spec:
  podSelector: {}
  policyTypes:
    - Ingress
    - Egress

---
# Allow specific traffic
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-app-to-db
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: myapp
  policyTypes:
    - Egress
  egress:
    - to:
        - podSelector:
            matchLabels:
              app: postgres
      ports:
        - protocol: TCP
          port: 5432
```

### RBAC Best Practices

```yaml
# Minimal ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
  name: myapp
  namespace: production
automountServiceAccountToken: false

---
# Minimal Role
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: myapp-role
  namespace: production
rules:
  - apiGroups: [""]
    resources: ["configmaps"]
    resourceNames: ["myapp-config"]
    verbs: ["get"]

---
# RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: myapp-binding
  namespace: production
subjects:
  - kind: ServiceAccount
    name: myapp
    namespace: production
roleRef:
  kind: Role
  name: myapp-role
  apiGroup: rbac.authorization.k8s.io
```

### Secrets Management

```yaml
# Bad: Plain secret in manifest
apiVersion: v1
kind: Secret
metadata:
  name: db-credentials
stringData:
  password: "mysecretpassword"  # Don't commit this!

# Good: External Secrets Operator
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: db-credentials
spec:
  refreshInterval: 1h
  secretStoreRef:
    name: vault-backend
    kind: ClusterSecretStore
  target:
    name: db-credentials
  data:
    - secretKey: password
      remoteRef:
        key: secret/data/production/db
        property: password
```

## Container Scanning in CI/CD

```yaml
# GitHub Actions
name: Container Security
on:
  push:
    branches: [main]

jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Build image
        run: docker build -t myapp:${{ github.sha }} .

      - name: Trivy scan
        uses: aquasecurity/trivy-action@master
        with:
          image-ref: myapp:${{ github.sha }}
          format: 'sarif'
          output: 'trivy-results.sarif'
          severity: 'CRITICAL,HIGH'
          exit-code: '1'

      - name: Upload Trivy results
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: 'trivy-results.sarif'

      - name: Dockle lint
        uses: erzz/dockle-action@v1
        with:
          image: myapp:${{ github.sha }}
          failure-threshold: high
```

## Security Scanning Tools Comparison

| Tool | Focus | OSS | Enterprise |
|------|-------|-----|------------|
| **Trivy** | Vulnerabilities, misconfig, secrets | Yes | Aqua |
| **Grype** | Vulnerabilities | Yes | Anchore |
| **Snyk** | Vulnerabilities, license | Partial | Yes |
| **Docker Scout** | Vulnerabilities, SBOM | Partial | Yes |
| **Dockle** | Best practices | Yes | - |
| **Hadolint** | Dockerfile linting | Yes | - |

## Quick Reference Commands

```bash
# Scan image for vulnerabilities
trivy image --severity HIGH,CRITICAL myapp:latest

# Lint Dockerfile
hadolint Dockerfile

# Check running container security
docker inspect --format='{{.HostConfig.Privileged}}' container_id

# Audit Kubernetes cluster
kubectl get pods --all-namespaces -o jsonpath='{range .items[*]}{.metadata.namespace}/{.metadata.name}: privileged={.spec.containers[*].securityContext.privileged}{"\n"}{end}'

# Check for root containers
kubectl get pods -A -o jsonpath='{range .items[*]}{.metadata.name}: runAsNonRoot={.spec.securityContext.runAsNonRoot}{"\n"}{end}'
```

Versions

RepositoryScoreLicence
This page · claude-dev-suite/claude-dev-suite100MIT
thisiskurubaran/DevSecOps100MIT
snyk/studio-recipes100Apache-2.0
uw-ssec/rse-plugins100BSD-3-Clause
chrishuffman5/domain-expert100MIT
kyleoliveiro/sg-gov-skills90MIT
susorov/agent-skills90MIT
Amey-Thakur/AI-SKILLS90MIT

Database snapshot: 13.11.2026 · package version 0841c986aefc (SHA-256 digest of the entire package)

Downloads in the last 30 days: 0 · ranking

Report a problem with this skill: harmful content, incorrect descriptions or an author’s removal request.

Similar skills

  • 100container-hardening
    Harden container images and runtime configuration. Use when building, reviewing, or auditing Containerfiles, Dockerfiles, container compose files, or Kubernetes pod security settings.
  • 100container-hardening
    Harden container images and runtime configuration. Use when building, reviewing, or auditing Containerfiles, Dockerfiles, container compose files, or Kubernetes pod security settings.
  • 100container-hardening
    Secure Docker images and container runtime configurations. Implement non-root users, read-only filesystems, and security contexts. Use when building secure container images or hardening container deployments.
  • 100container-audit
    Audit container images, Dockerfiles, and Kubernetes manifests for misconfigurations, excessive privileges, exposed secrets, and runtime risks. Use when the user mentions 'container security,' 'Docker security,' 'Dockerfile audit,' 'Kubernetes security,' 'K8s security,' 'pod…
  • 100kubernetes-manifests
    Use when writing and deploying Kubernetes manifests for container orchestration.
  • 100container-security-hardening
    Harden Docker/container images and runtime deployments with secure base images, non-root users, CVE scanning, SBOM/signing, seccomp/AppArmor, and Kubernetes pod security controls. Use for Dockerfile security reviews, container CVEs, image scanning, distroless images, or production hardening.

Feedback and reports

Your message goes to Bartosz Sokoliński. An email address is needed only for a reply. See the privacy policy.