Skip to content
Back to skills

Container Security

CSecurity

Container security — image hardening, vulnerability scanning, runtime security, secrets management, and compliance.

  • 6 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added June 1, 2026
ai-agentsshellbashnodedockerawsgitapisecurity

Works with

  • vscode
  • api

Security analysis

C68/100
  • criticalAccesses sensitive system or user directories
  • highPerforms destructive filesystem operations
  • criticalExfiltrates credentials via HTTP — exact pattern from Snyk ToxicSkills study

Pro shows the line behind each finding and how to fix it

Scanned June 1, 2026

npx -y skills add KevinZai/commander --skill container-security --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Container Security?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Container Security
[![Security: C — Skills Directory](https://www.skillsdirectory.com/api/skills/kevinzai-container-security/badge)](https://www.skillsdirectory.com/skills/kevinzai-container-security)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: container-security
description: "Container security — image hardening, vulnerability scanning, runtime security, secrets management, and compliance."
risk: low
source: custom
date_added: '2026-03-20'
---

# Container Security

Expert guide to securing Docker containers from build to runtime.

## Use this skill when

- Hardening Docker images and Dockerfiles
- Scanning for vulnerabilities in images and dependencies
- Implementing runtime security policies
- Managing secrets in containerized environments
- Meeting compliance requirements (SOC2, PCI, HIPAA)

## Do not use this skill when

- Securing non-containerized applications
- Network security outside container scope

## Instructions

1. Secure the build (minimal base, non-root, no secrets in layers).
2. Scan images for vulnerabilities.
3. Configure runtime security (read-only FS, capabilities, seccomp).
4. Manage secrets properly.
5. Monitor and audit.

---

## Secure Dockerfile

```dockerfile
# Use specific tag, never :latest in production
FROM node:20.11-alpine3.19 AS base

# Install security updates
RUN apk update && apk upgrade --no-cache

# Create non-root user EARLY
RUN addgroup -g 1001 -S appgroup && \
    adduser -S appuser -u 1001 -G appgroup -h /app -s /sbin/nologin

WORKDIR /app

# Dependencies in separate layer (cached)
FROM base AS deps
COPY package.json package-lock.json ./
RUN npm ci --omit=dev --ignore-scripts && npm cache clean --force

# Build stage
FROM base AS build
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build

# Production — minimal final image
FROM base AS production

# Copy only what's needed
COPY --from=build --chown=appuser:appgroup /app/dist ./dist
COPY --from=build --chown=appuser:appgroup /app/node_modules ./node_modules
COPY --from=build --chown=appuser:appgroup /app/package.json ./

# Remove unnecessary tools
RUN apk del --purge apk-tools && \
    rm -rf /var/cache/apk/* /tmp/* /root/.npm

# Switch to non-root
USER appuser

# Read-only filesystem compatible
ENV NODE_ENV=production
EXPOSE 3000

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

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

## Image Scanning

```bash
# Docker Scout (built-in)
docker scout cves myapp:latest
docker scout quickview myapp:latest

# Trivy (open source, comprehensive)
trivy image --severity HIGH,CRITICAL myapp:latest
trivy image --exit-code 1 --severity CRITICAL myapp:latest  # Fail CI on critical

# Grype
grype myapp:latest

# Snyk
snyk container test myapp:latest --severity-threshold=high
```

### CI Integration

```yaml
# GitHub Actions
- name: Scan image with Trivy
  uses: aquasecurity/trivy-action@master
  with:
    image-ref: ${{ env.IMAGE }}
    format: 'sarif'
    output: 'trivy-results.sarif'
    severity: 'CRITICAL,HIGH'
    exit-code: '1'

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

## Runtime Security

### Docker Run Security Options

```bash
docker run \
  --read-only \                          # Read-only root filesystem
  --tmpfs /tmp:rw,noexec,nosuid \        # Writable tmp without exec
  --cap-drop ALL \                       # Drop all Linux capabilities
  --cap-add NET_BIND_SERVICE \           # Add only what's needed
  --security-opt no-new-privileges \     # Prevent privilege escalation
  --security-opt seccomp=default.json \  # Seccomp profile
  --pids-limit 100 \                     # Prevent fork bombs
  --memory 512m \                        # Memory limit
  --cpus 1.0 \                           # CPU limit
  --user 1001:1001 \                     # Non-root user
  myapp:latest
```

### Compose Security

```yaml
services:
  app:
    image: myapp:latest
    read_only: true
    tmpfs:
      - /tmp:rw,noexec,nosuid,size=64m
    security_opt:
      - no-new-privileges:true
    cap_drop:
      - ALL
    cap_add:
      - NET_BIND_SERVICE
    deploy:
      resources:
        limits:
          cpus: "1.0"
          memory: 512M
          pids: 100
    user: "1001:1001"
```

## Secrets Management

```yaml
# Docker secrets (Swarm mode or compose)
services:
  app:
    secrets:
      - db_password
      - api_key
    environment:
      - DB_PASSWORD_FILE=/run/secrets/db_password

secrets:
  db_password:
    external: true  # Created via `docker secret create`
  api_key:
    file: ./secrets/api_key.txt  # Local file (dev only)
```

### AWS ECS Secrets

```json
{
  "containerDefinitions": [{
    "secrets": [
      {
        "name": "DB_PASSWORD",
        "valueFrom": "arn:aws:secretsmanager:us-east-1:123456789:secret:prod/db-password"
      },
      {
        "name": "API_KEY",
        "valueFrom": "arn:aws:ssm:us-east-1:123456789:parameter/prod/api-key"
      }
    ]
  }]
}
```

## .dockerignore

```
.git
.gitignore
.env*
node_modules
npm-debug.log
Dockerfile*
docker-compose*
compose*
.dockerignore
tests
coverage
docs
*.md
.vscode
.idea
.DS_Store
```

## Security Checklist

- [ ] Base image pinned to specific version (not `:latest`)
- [ ] Multi-stage build (build tools not in final image)
- [ ] Non-root user in final stage
- [ ] No secrets in image layers (use build secrets or runtime injection)
- [ ] `.dockerignore` excludes sensitive files
- [ ] Image scanned for CVEs (Trivy/Scout in CI)
- [ ] Read-only root filesystem
- [ ] Linux capabilities dropped (cap_drop ALL, add only needed)
- [ ] Resource limits set (memory, CPU, pids)
- [ ] Health check defined
- [ ] No unnecessary packages (no curl/wget/shell if not needed)
- [ ] Secrets injected at runtime, not baked into image

## Common Pitfalls

1. **Secrets in build args** — `ARG` values are visible in image history. Use `--mount=type=secret` instead.
2. **Running as root** — Default. Always add `USER` instruction.
3. **Using `:latest` tag** — Not reproducible. Pin to specific version or digest.
4. **Large attack surface** — Use Alpine or distroless. Remove build tools from final image.
5. **Writable root FS** — Use `--read-only` with explicit `tmpfs` for writable dirs.
6. **No resource limits** — Container can consume all host resources without limits.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…