domains / security / container-hardening / container-hardening

container-hardening

Skill card

combined

The second copy is a direct adaptation of the first, but it changes the procedure in ways that conflict with the original rather than merely shortening it. The original Dockerfile installs and then removes build dependencies and adds NET_BIND_SERVICE at runtime; the adapted copy removes the build-dependency step entirely (and explicitly warns against it), drops NET_BIND_SERVICE, pins digests, and adds resource limits and tmpfs flags. Because the copies disagree on concrete steps, crowning one would hide a real alternative.

Repositories

RepositoryPath
BagelHole/DevOps-Security-Agent-Skillssecurity/hardening/container-hardening/SKILL.md
sickn33/agentic-awesome-skillsplugins/agentic-awesome-skills-claude/skills/container-hardening/SKILL.md

Other copies

RoleRepositoryPath
peerBagelHole/DevOps-Security-Agent-Skillssecurity/hardening/container-hardening/SKILL.md
peersickn33/agentic-awesome-skillsplugins/agentic-awesome-skills-claude/skills/container-hardening/SKILL.md
adaptersickn33/agentic-awesome-skillsplugins/agentic-awesome-skills/skills/container-hardening/SKILL.md
adaptersickn33/agentic-awesome-skillsskills/container-hardening/SKILL.md

Combined skill

# Container Hardening

Secure container images and runtime configurations.

## When to Use This Skill

Use this skill when:
- Building secure container images
- Hardening container deployments
- Meeting container security requirements
- Implementing defense in depth

## Dockerfile Security

Use a minimal base image and run as a non-root user. Pin an approved immutable digest for real builds and refresh supported base images.

```dockerfile
# Example for an application binary already built for this Alpine/musl runtime.
FROM alpine:3.24
RUN addgroup -g 1001 -S appgroup && \
    adduser -u 1001 -S appuser -G appgroup
WORKDIR /app
# Copy only the intended reviewed build artifact, not credentials or the entire repo.
COPY --chown=appuser:appgroup myapp /app/myapp
USER 1001:1001
ENTRYPOINT ["/app/myapp"]
```

If compilation is needed, prefer a separate builder stage. Do not run apk del against a nonexistent virtual group.

## Runtime Security

Run with security options. Add writable paths only where required.

```bash
docker run -d \
  --read-only \
  --tmpfs /tmp:rw,noexec,nosuid,size=64m \
  --security-opt=no-new-privileges:true \
  --cap-drop=ALL \
  --user 1001:1001 \
  myapp@sha256:<reviewed-image-digest>
```

Low ports do not justify NET_BIND_SERVICE by default; add capabilities only when required.

## Kubernetes Security Context

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: hardened-example
spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 1001
    fsGroup: 1001
  containers:
  - name: app
    image: myapp@sha256:<reviewed-image-digest>
    resources:
      requests: {cpu: "100m", memory: "64Mi"}
      limits: {cpu: "500m", memory: "256Mi"}
    securityContext:
      allowPrivilegeEscalation: false
      readOnlyRootFilesystem: true
      capabilities:
        drop: ["ALL"]
```

Tune actual resource budgets and approved volumes, network policy and workload permissions.

## Image Scanning

```bash
trivy image --severity HIGH,CRITICAL myapp@sha256:<reviewed-image-digest>
```

Consider a maintained distroless image only when the actual application is compatible. Scanning can disclose artifacts or use network databases, so review data paths and policies first.

## Best Practices

- Use minimal base images
- Run as non-root user
- Enable read-only filesystem
- Drop all capabilities
- Scan images regularly
- Sign and verify images
- Use secrets management

## Limitations

- The Dockerfile needs a reviewed executable built for the selected ABI; it is not bundled.
- Replace digest placeholders with verified image identities before execution.
- Read-only filesystems and dropped capabilities reduce privileges but are not a complete sandbox.
- No Docker build, cluster application or scanner execution is claimed.

### Example

```bash
# Read-only first: inventory before any active step.
command -v docker
docker --version
```