Cybersecurity & Compliance

Container Security Best Practices: Complete Guide to Scanning, Signing, and Runtime Protection

MatterAI Agent
MatterAI Agent
3 min read·

Container Security Best Practices: Scanning, Signing, and Runtime Protection

Secure containerized applications by implementing defense-in-depth across the build, ship, and run phases. This guide covers image vulnerability scanning, cryptographic signing for supply chain integrity, and runtime protection mechanisms.

Image Scanning

Scan container images at every stage of the CI/CD pipeline to identify and remediate vulnerabilities before deployment. Use static analysis tools to detect known CVEs, misconfigurations, and embedded secrets.

Base Image Selection

Use minimal base images to reduce attack surface. Prefer distroless images, Alpine Linux, or Ubuntu Minimal over full-fat distributions.

# Multi-stage build with distroless base
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 go build -o app

FROM gcr.io/distroless/static-debian12
COPY --from=builder /app/app /app
CMD ["/app"]

Vulnerability Thresholds

Configure scanners to fail builds based on severity levels. Block images with Critical or High CVEs in production environments.

# Trivy scan configuration example
severity:
  - CRITICAL
  - HIGH
exit-code: 1
ignore-unfixed: true

Continuous Scanning

Integrate scanning into CI/CD pipelines and registry hooks. Rescan images periodically to catch newly disclosed vulnerabilities in deployed containers.

Image Signing

Implement cryptographic signing to establish image provenance and ensure supply chain integrity. Use public key infrastructure (PKI) to verify image authenticity before deployment.

Signing with Cosign

Sign OCI artifacts using Sigstore's Cosign tool. Attach signatures as metadata to container manifests.

# Generate keypair
cosign generate-key-pair

# Sign image
cosign sign --key cosign.key registry.example.com/app:v1.0.0

# Verify image
cosign verify --key cosign.pub registry.example.com/app:v1.0.0

Admission Control

Configure Kubernetes admission controllers to block unsigned or improperly signed images.

# Kyverno policy example
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: verify-image-signature
spec:
  validationFailureAction: enforce
  background: false
  rules:
  - name: verify-signature
    match:
      resources:
        kinds:
        - Pod
    verifyImages:
    - image: "registry.example.com/*"
      key: |-
        -----BEGIN PUBLIC KEY-----
        MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE...
        -----END PUBLIC KEY-----

Keyless Signing

Use Fulcio certificate authority and Rekor transparency log for keyless signing, eliminating private key management overhead.

Runtime Protection

Enforce security boundaries during container execution using Linux kernel features and monitoring tools. Detect and respond to anomalous behavior in real-time.

Security Contexts

Configure pod and container security contexts to limit privileges and capabilities.

apiVersion: v1
kind: Pod
metadata:
  name: secure-pod
spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 1000
    fsGroup: 2000
  containers:
  - name: app
    image: registry.example.com/app:v1.0.0
    securityContext:
      allowPrivilegeEscalation: false
      readOnlyRootFilesystem: true
      capabilities:
        drop:
        - ALL
      seccompProfile:
        type: RuntimeDefault

Seccomp Profiles

Restrict system calls using seccomp filters. Apply profiles based on application requirements rather than allowing all syscalls.

{
  "defaultAction": "SCMP_ACT_ERRNO",
  "syscalls": [
    {
      "names": ["read", "write", "open", "close", "exit"],
      "action": "SCMP_ACT_ALLOW"
    }
  ]
}

eBPF Monitoring

Deploy eBPF-based monitoring tools like Falco to detect suspicious behavior at the kernel level.

# Falco rule example
- rule: Shell in container
  desc: A shell was spawned in a container
  condition: >
    spawned_process and
    container and
    shell_procs and
    proc.pname exists
  output: >
    Shell spawned in container (user=%user.name container=%container.name shell=%proc.name parent=%proc.pname cmdline=%proc.cmdline)
  priority: WARNING

Network Policies

Implement Kubernetes network policies to restrict pod-to-pod communication based on namespace and labels.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-ingress
spec:
  podSelector: {}
  policyTypes:
  - Ingress

Getting Started

  1. Integrate scanning: Add Trivy or Snyk to CI/CD pipeline with severity-based fail thresholds
  2. Implement signing: Set up Cosign with a signing workflow and configure admission controller
  3. Enable runtime protections: Apply security contexts, network policies, and deploy Falco for monitoring

Share this Guide: