Docker & Containerization

Chapter 10
Container Security and Software Supply Chains

Certificate in DevOps
Docker & Containerization   •   Certificate

Container Security and Software Supply Chains

Introduction

Containers package an application with its runtime dependencies, but they do not automatically make software secure. A container shares the host kernel and depends on a chain of external components: base images, operating-system packages, language libraries, build tools, registries, deployment manifests, and the Docker daemon. A weakness in any link can affect the confidentiality, integrity, or availability of the application.

Container security therefore has two connected dimensions. Runtime security limits what a running container can do. Supply-chain security establishes confidence that the image and its dependencies are authentic, appropriate, and free from unacceptable known weaknesses. Effective practice combines both dimensions with secure configuration, continuous monitoring, and disciplined patching.

Learning Objectives

By the end of this chapter, you should be able to:

  • apply least privilege to containers and Docker hosts;
  • distinguish non-root containers from rootless Docker;
  • control Linux capabilities and system calls;
  • manage secrets without embedding them in images;
  • scan images and interpret vulnerability results;
  • explain SBOMs, image signing, trusted sources, and provenance;
  • design a practical image-patching workflow; and
  • identify secure Docker daemon and host configurations.

1. The Container Threat Model

A threat model identifies assets, actors, attack surfaces, and security controls. Important assets include source code, credentials, customer data, private images, build infrastructure, the host operating system, and the integrity of released software.

Typical threat actors include external attackers, malicious insiders, compromised dependencies, and attackers who exploit a vulnerable application to escape its container. The principal attack surfaces are:

  1. The image supply chain: Dockerfiles, build systems, base images, package repositories, and registries.
  2. The runtime: application processes, mounted filesystems, exposed ports, environment variables, and Linux kernel interfaces.
  3. The control plane: the Docker socket, daemon API, registry credentials, CI/CD permissions, and orchestration configuration.
  4. The host: the kernel, filesystem, users, networks, and other workloads.

Containers are a form of operating-system-level isolation, not a complete virtual machine boundary. A container process normally shares the host kernel. Consequently, a kernel vulnerability, excessive privilege, or access to the Docker socket may allow an attacker to affect the host or other containers.

A useful security objective is the principle of least privilege: each process, user, container, and build component receives only the permissions required for its legitimate function, for only as long as needed. Least privilege reduces both the probability and impact of compromise.

2. Non-Root and Rootless Execution

2.1 Running the application as a non-root user

Inside a conventional Docker installation, the container's process may run as the root user within the container's user namespace. This is not identical to unrestricted host root, because Linux namespaces, capabilities, and other controls may restrict it. Nevertheless, container root is a dangerous default: an application exploit may use retained capabilities, writable mounts, kernel vulnerabilities, or a misconfiguration to increase its impact.

A safer image creates a dedicated user and switches to it:

FROM python:3.12-slim
WORKDIR /app
RUN addgroup --system app && adduser --system --ingroup app app
COPY --chown=app:app requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY --chown=app:app . .
USER app
CMD ["python", "server.py"]

The user should not own unnecessary system directories, and application files should be read-only wherever possible. The container should also avoid running a package manager or development server in production.

2.2 Rootless Docker

Rootless Docker runs both the Docker daemon and containers as an unprivileged user. It reduces the consequences of a daemon or container compromise because the daemon does not require host-root privileges. It is distinct from a container that merely uses USER app in its Dockerfile: a non-root container may still be managed by a rootful daemon.

Rootless operation has practical constraints. Some networking modes, storage drivers, device access patterns, and performance characteristics differ from rootful Docker. Organizations must test application requirements rather than assume complete feature equivalence. Rootless mode is a valuable defence-in-depth measure, not a substitute for secure images and host patching.

2.3 User namespaces

User namespaces map container user IDs to different host IDs. A process can appear to be UID 0 inside the container while corresponding to an unprivileged host ID. User-namespace remapping reduces host impact, but it requires careful handling of file ownership, bind mounts, volumes, and operational tooling.

3. Capabilities, Privileged Mode, and System Calls

Linux capabilities divide traditional root powers into smaller permissions. Examples include NET_BIND_SERVICE, which permits binding to ports below 1024, and CHOWN, which permits changing file ownership. A container should retain only capabilities required by its function.

A strong baseline is:

docker run --rm \
  --cap-drop=ALL \
  --cap-add=NET_BIND_SERVICE \
  --read-only \
  --tmpfs /tmp:rw,noexec,nosuid,size=64m \
  --security-opt=no-new-privileges:true \
  myorg/web:1.4.2

This example is illustrative. The application must be tested before deployment because dropping a required capability can cause failure. --privileged should almost never be used for ordinary applications: it grants broad access to devices and security mechanisms and substantially weakens isolation.

The no-new-privileges setting prevents a process and its descendants from gaining additional privileges through mechanisms such as set-user-ID binaries. It does not remove privileges already held, so it should be combined with a non-root user and capability reduction.

Docker and Linux security profiles can restrict system calls. seccomp filters system calls available to a container; AppArmor and SELinux apply mandatory access-control policies. The default profiles are useful starting points, but high-assurance environments should review and tailor them. Disabling security profiles for convenience should require explicit justification and approval.

4. Filesystems, Networks, and Secrets

4.1 Filesystem controls

A production container should generally use an immutable image and a read-only root filesystem. Writable storage should be limited to specific volumes or temporary filesystems. Bind mounts deserve special care: mounting the host's Docker socket, sensitive host directories, or the entire host filesystem can effectively grant control over the host.

Avoid embedding credentials in:

  • Dockerfile instructions such as ENV PASSWORD=...;
  • image layers created by RUN echo secret ...;
  • source repositories;
  • public image registries; or
  • unprotected build logs.

Deleting a secret in a later Dockerfile layer does not reliably remove it from earlier layers. Use BuildKit secret mounts for build-time credentials, for example:

docker build --secret id=pypi,src=$HOME/.config/pypi-token .

The Dockerfile must explicitly consume the secret through a secret mount; it should not copy the secret into the resulting image.

4.2 Runtime secret management

Runtime secrets should be supplied by an approved secret-management system, such as a cloud secret manager, Vault, or an orchestrator's protected secret facility. Access should be authenticated, authorized, logged, rotated, and scoped to the workload. Environment variables are convenient but may appear in process inspection, diagnostics, crash reports, or accidental logs. File-based secret mounts can reduce exposure, but their permissions and lifecycle must still be controlled.

A secret is not protected merely because it is encoded rather than encrypted. Base64 is an encoding, not a security control. Encryption in transit and at rest, key rotation, and emergency revocation are essential.

4.3 Network controls

Expose only necessary ports and avoid publishing services to all host interfaces by default. Apply network segmentation so that a compromised web container cannot freely reach databases, metadata services, or administrative interfaces. Use TLS for service communication where confidentiality or authentication is required. Egress controls can limit data exfiltration and prevent unauthorized downloads during runtime.

5. Secure Docker Daemon Configuration

The Docker daemon is a high-value control component. Access to the Docker socket is effectively highly privileged: a user or container that can instruct the daemon to create a container with host filesystem access may obtain control over the host.

Recommended controls include:

  • protect /var/run/docker.sock and restrict membership in the docker group;
  • do not expose the daemon API on an unauthenticated TCP socket;
  • if remote administration is necessary, use mutually authenticated TLS and network restrictions;
  • keep Docker Engine, the host kernel, and supporting packages patched;
  • use rootless Docker or user-namespace remapping where practical;
  • enable logging and monitor daemon configuration changes;
  • use trusted registries and restrict image-pull permissions;
  • separate build hosts from production hosts where feasible; and
  • apply host firewalling, disk encryption, secure boot, and endpoint monitoring according to organizational requirements.

The docker group is not a low-privilege application group. Membership should be treated as equivalent to administrative authority over the Docker host. A common error is granting developers unrestricted production socket access for convenience.

6. Image Construction and Trusted Sources

A secure image begins with a controlled base. Prefer official or organization-approved images with clear ownership, documented update practices, and verifiable provenance. Smaller images reduce attack surface and scanning noise, but minimal size alone does not prove security. A small image can still contain a critical vulnerability or malicious code.

Image-building practices include:

  • pin base images by immutable digest when reproducibility is important;
  • use multi-stage builds so compilers and test tools are excluded from production;
  • remove package-manager caches and unnecessary files;
  • avoid downloading scripts and executing them without verification;
  • use dependency lockfiles and trusted package repositories;
  • set explicit file ownership and permissions;
  • scan the final image, not only the source project; and
  • generate provenance and an SBOM during the build.

Tags such as latest are mutable references. A digest identifies image content, for example image@sha256:.... Digest pinning improves reproducibility, but it also creates a maintenance responsibility: the digest must be deliberately updated when security fixes are released.

7. Vulnerability Scanning and Patching

A vulnerability scanner compares packages and sometimes application dependencies against vulnerability databases. Results commonly include an identifier, affected version range, severity, fixed version, and evidence. Severity is not the same as actual risk. Exploitability, network exposure, privileges required, data sensitivity, compensating controls, and whether the vulnerable code path is reachable all matter.

Scanning should occur at multiple points:

  1. when a base image is selected;
  2. during pull-request and image-build workflows;
  3. before promotion to a registry or production;
  4. continuously for images stored in registries; and
  5. on running hosts and workloads.

A practical policy can block releases for critical exploitable findings, require review for high findings, and record accepted risks with an owner and expiry date. Policies must distinguish false positives from accepted risk. Suppression without documented reasoning merely hides risk.

Patching is a lifecycle, not a one-time scan. A useful workflow is: identify the affected component, determine reachability and exposure, select a fixed version, rebuild from a current base, test the application, rescan, sign the resulting image, deploy progressively, and retain rollback capability. Rebuilding rather than modifying a running container preserves immutability and auditability.

8. SBOMs and Software Provenance

A software bill of materials (SBOM) is an inventory of software components and their relationships. It may include package names, versions, supplier, licenses, hashes, and dependency relationships. Common machine-readable formats include SPDX and CycloneDX.

An SBOM supports vulnerability response, license review, asset inventory, and rapid identification of affected products. It is not itself a security guarantee. An incomplete or stale SBOM can create false confidence, and an SBOM does not prove that a component is benign.

Provenance describes how an artifact was produced: source revision, builder identity, build parameters, dependencies, and timestamps. Reproducible or independently verifiable builds strengthen confidence that the released image corresponds to reviewed source. Build systems should be isolated, access-controlled, and monitored because compromise of the builder can contaminate every output.

9. Image Signing and Admission Decisions

Image signing binds an identity to an image digest. A verifier can check that an image was signed by an approved key or identity and that its content has not changed since signing. Modern keyless approaches may use short-lived identities and a transparency service; traditional approaches may use managed keys. Both require sound identity governance and protection of signing authority.

Signing does not mean that an image is vulnerability-free. It means that an authorized party attested to a particular artifact or statement. Verification should therefore be combined with policy checks such as:

  • Is the image from an approved registry?
  • Is the signature valid and unexpired according to policy?
  • Was it built by an approved workflow?
  • Does its digest match the deployment manifest?
  • Does it have a current SBOM and acceptable scan result?
  • Is the image allowed in this environment?

Admission controls can prevent unsigned or unapproved images from running. The policy should provide an emergency process without creating a permanent bypass. Private keys, identity providers, and policy engines must be protected and audited.

10. An Integrated Secure Supply-Chain Model

A mature workflow connects source control, build, analysis, registry, deployment, and monitoring. Source changes are reviewed and tested. A controlled builder creates an image from approved dependencies, generates an SBOM and provenance statement, scans the artifact, and signs the digest. A registry enforces access control and retention. Deployment verifies signature, provenance, vulnerability policy, and configuration before admission. Runtime monitoring detects drift, suspicious behavior, and newly disclosed vulnerabilities.

Security controls are strongest when they are automated but not unquestioned. Automation should produce evidence, alerts, and repeatable decisions. Human review remains necessary for risk acceptance, exceptional access, and interpretation of context.

Applied Case: Illustrative Online Retail Service

Background

An online retailer runs a web API, a payment adapter, and a reporting service in Docker. Developers previously used a public base image tagged latest. Production containers ran as root, the CI system stored a registry password in a build variable, and the Docker socket was mounted into a build container.

Problem

A scan identified an outdated cryptographic library. Investigation also found that an old image layer contained a database credential. Although the credential had been removed in a later commit, it remained recoverable from image history. The socket mount meant a compromised build step could potentially control the host daemon.

Analysis

The retailer's immediate vulnerability was not only the outdated library. The broader risk arose from mutable inputs, excessive build privilege, poor secret handling, and absent artifact verification. A critical image finding could recur because the base image and dependency versions were not governed.

Approach and Solution

The team adopted an approved minimal base image pinned by digest and rebuilt it through a protected CI runner. BuildKit secret mounts replaced persistent password variables. The Dockerfile created a dedicated non-root user, used a multi-stage build, and excluded compilers from the runtime image. Production containers used a read-only root filesystem, a small temporary filesystem, dropped capabilities, and a custom seccomp profile.

The Docker socket was removed from the build container. CI generated an SBOM, scanned the final digest, and signed it through a protected identity. Deployment required a valid signature, an approved registry, a recent scan, and a recorded SBOM. Secrets moved to a managed service with rotation. The host and Docker Engine were patched, and daemon access was restricted to administrators.

Outcome

The retailer reduced the number of production packages, eliminated the credential from newly built artifacts, and gained an auditable release trail. The old credential was revoked and replaced. A staged deployment process allowed the team to test the patched cryptographic library before full rollout.

Learning Points

The case demonstrates that security is a chain rather than a single scanner or setting. Non-root execution limits runtime privilege, but it does not replace image provenance. Signing establishes origin and integrity, but it does not replace vulnerability analysis. Secret rotation is necessary after exposure, even if the visible source file has been corrected.

Challenges and Limitations

No control is perfect. Vulnerability databases may contain incomplete information, scanners may miss malicious logic or vulnerabilities in proprietary code, and SBOM formats may differ in completeness. Digest pinning can delay security updates if teams fail to refresh pinned references. Rootless mode may complicate device access and networking. Strict admission policies can interrupt delivery if exception processes are poorly designed.

Security controls also create operational costs: build time, storage, review effort, key management, and testing. These costs should be managed through automation and risk-based prioritization, not by abandoning controls. Organizations must maintain accurate inventories, assign owners, define service-level expectations for remediation, and rehearse incident response.

Governance, Ethics, and Contemporary Practice

Organizations should protect customer and employee data, minimize unnecessary collection, and maintain evidence for regulatory and contractual obligations. License information in SBOMs supports responsible use of open-source software. Security teams should avoid blaming individual developers for systemic weaknesses; secure defaults, training, and clear ownership are more effective than punishment alone.

Contemporary supply-chain security increasingly uses signed attestations, transparency logs, automated policy enforcement, dependency review, and behavioral runtime detection. Artificial intelligence may assist with vulnerability prioritization or anomaly detection, but its recommendations require human validation. AI-generated Dockerfiles and dependencies must undergo the same review, testing, scanning, and provenance controls as human-authored artifacts.

Best-Practice Checklist

  • Build from approved, maintained, preferably digest-pinned bases.
  • Use multi-stage builds and remove unnecessary tools.
  • Run applications as non-root; evaluate rootless Docker.
  • Drop all unnecessary capabilities and use no-new-privileges.
  • Prefer read-only filesystems and narrowly scoped mounts.
  • Never place long-lived secrets in images, source, or logs.
  • Generate and retain an SBOM and provenance record.
  • Scan, patch, rebuild, rescan, and document exceptions.
  • Sign release images and verify them at deployment.
  • Restrict Docker daemon and socket access.
  • Patch the host kernel, Docker Engine, and dependencies.
  • Monitor runtime behavior, configuration drift, and newly disclosed vulnerabilities.

Chapter Summary

Container security requires defence in depth across the image lifecycle and runtime environment. Least privilege is implemented through non-root users, rootless execution where suitable, capability reduction, system-call controls, read-only filesystems, and restricted network access. Secrets must be supplied through controlled mechanisms rather than embedded in image layers. Secure supply chains use trusted and maintained bases, reproducible builds, vulnerability scanning, patching, SBOMs, provenance, image signing, and admission policies. The Docker daemon and host are critical assets because excessive socket or API access can defeat container isolation. No individual control proves security; confidence comes from combining preventive, detective, and governance controls with continuous maintenance.

Key Terms

Least privilege: Giving a subject only the permissions required for its legitimate task.

Non-root container: A container whose application process runs as an unprivileged user.

Rootless Docker: Docker daemon and containers operated without host-root privileges.

User namespace: A Linux isolation mechanism that maps container identities to different host identities.

Linux capability: A discrete portion of the powers traditionally associated with root.

Privileged container: A container granted unusually broad access to host devices and kernel features.

Seccomp: A Linux mechanism for filtering permitted system calls.

AppArmor: A Linux mandatory access-control system based on application profiles.

Secret: Sensitive authentication or encryption material requiring controlled storage and access.

Digest: A cryptographic identifier of exact image content.

Trusted registry: An approved image repository with controlled ownership, access, and governance.

Vulnerability scanner: A tool that compares components with vulnerability knowledge bases.

SBOM: A machine-readable inventory of software components and relationships.

Provenance: Evidence describing how and by whom an artifact was built.

Image signing: Binding an identity or attestation to an image digest.

Admission control: A policy decision that permits or rejects deployment of an artifact.

Supply chain: The people, processes, tools, and components involved in producing software.

No-new-privileges: A control preventing processes from acquiring additional privileges.

Review Questions

Short Answer Questions

  1. Why is running an application as root inside a container risky?
  2. What is the difference between a non-root container and rootless Docker?
  3. Why is Base64 not an acceptable method for protecting secrets?
  4. What information does an SBOM provide?
  5. Why should access to the Docker socket be restricted?

Long Answer Questions

  1. Explain how least privilege can be implemented using users, capabilities, filesystem controls, and security profiles.
  2. Describe a secure image-build and release workflow from source change through deployment.
  3. Compare vulnerability scanning, SBOM generation, provenance, and image signing. Explain why none is sufficient alone.
  4. Discuss the advantages and limitations of rootless Docker and user-namespace remapping.
  5. Design a patch-management policy for production container images, including prioritization, testing, exceptions, and rollback.

Analytical / Application Questions

  1. A container requires a writable log directory, access to port 443, and no host-device access. Propose a secure runtime configuration and justify each major control.
  2. A signed image contains a critical vulnerability, while an unsigned image has no known vulnerabilities. Which should a production admission policy accept, and what additional evidence should be required?
  3. A CI job has access to the Docker socket and pulls an unpinned public base image. Identify the principal risks and propose a prioritized remediation plan.

Multiple Choice Questions with Answers

Question 1

Which statement best distinguishes rootless Docker from a non-root container?

A. Rootless Docker runs the daemon without host-root privileges, while a non-root container changes the application user.

B. Rootless Docker encrypts all container traffic, while a non-root container does not.

C. Rootless Docker requires privileged mode, while a non-root container always uses it.

D. There is no difference between the two concepts.

Correct Answer: A. Rootless Docker runs the daemon without host-root privileges, while a non-root container changes the application user.

Question 2

What is the primary security concern with mounting the Docker socket into a container?

A. It prevents the container from communicating with the network.

B. It may allow the container to control the Docker daemon and potentially the host.

C. It automatically deletes all image layers.

D. It forces the application to run as a non-root user.

Correct Answer: B. It may allow the container to control the Docker daemon and potentially the host.

Question 3

Which control removes unnecessary Linux privileges from a container?

A. Using the latest tag

B. Adding more environment variables

C. Dropping capabilities

D. Publishing additional ports

Correct Answer: C. Dropping capabilities

Question 4

Why should secrets not be deleted only in a later Dockerfile layer?

A. Dockerfiles cannot contain deletion commands.

B. Earlier layers may still preserve the secret.

C. Deletion makes the image impossible to scan.

D. Later layers always become executable.

Correct Answer: B. Earlier layers may still preserve the secret.

Question 5

What is the principal purpose of an SBOM?

A. To provide an inventory of software components and their relationships

B. To replace all vulnerability testing

C. To encrypt container filesystems

D. To create a network firewall policy

Correct Answer: A. To provide an inventory of software components and their relationships

Question 6

What does image signing primarily establish?

A. That an image contains no vulnerabilities

B. That an image was authorized or attested by a particular identity and has not changed

C. That an image uses the smallest possible base

D. That an image runs without a kernel

Correct Answer: B. That an image was authorized or attested by a particular identity and has not changed

Question 7

Which image reference provides the strongest content immutability?

A. app:latest

B. app:stable

C. app:2025

D. An image reference using a cryptographic digest

Correct Answer: D. An image reference using a cryptographic digest

Question 8

Which practice best supports secure image patching?

A. Modify the running container manually and never rebuild it.

B. Rebuild from an updated base, test, rescan, and redeploy.

C. Ignore scanner results if the application appears to work.

D. Use a mutable tag without recording its value.

Correct Answer: B. Rebuild from an updated base, test, rescan, and redeploy.

Question 9

What does no-new-privileges help prevent?

A. A process gaining additional privileges through mechanisms such as set-user-ID binaries

B. All network traffic leaving the container

C. All package updates inside an image

D. Creation of an SBOM

Correct Answer: A. A process gaining additional privileges through mechanisms such as set-user-ID binaries

Question 10

Which statement about vulnerability severity is most accurate?

A. Severity alone always determines remediation priority.

B. A low-severity issue is always irrelevant.

C. Risk also depends on exploitability, exposure, reachability, and compensating controls.

D. A signed image cannot contain a vulnerability.

Correct Answer: C. Risk also depends on exploitability, exposure, reachability, and compensating controls.

Docker & Containerization
Chapter 10 of 13