By NHI Mgmt Group Editorial TeamBased on Truffle Security: “How Secrets Leak out of Docker Images” (September 11, 2023)

TL;DR: Truffle Security shows how Docker image layers can preserve secrets long after files are deleted, and how COPY, hardcoded Dockerfile values, and build arguments expose API secrets and private keys even when the final image looks clean. The governance problem is not just leakage, but the false assumption that deletion inside a build equals revocation.


At a glance

What this is: This article explains how Docker image layering, cached build steps, and unsafe secret handling let credentials survive inside images even after files are deleted or hidden.

Why it matters: It matters because teams that treat build-time cleanup as revocation can ship recoverable NHI secrets, leaving cloud, registry, and CI/CD access exposed.

👉 Read Truffle Security's analysis of how Docker images leak secrets through layers


Context

Docker image builds are not neutral packaging steps. They create layered artifacts that can retain files, command history, and build arguments long after the final container appears clean, which means secret handling in build pipelines is also an identity governance problem.

The security gap is the assumption that deleting a file, or moving a secret out of the final runtime image, removes the credential from the supply chain. In practice, Docker layers, build metadata, and ignored files can preserve NHI secrets in places operators do not inspect.

That makes Docker image hygiene part of CI/CD pipeline identity security as much as it is a developer workflow issue. If the build process can still reveal a token, the organisation has not actually revoked access to that secret.


Key questions

Q: What breaks when Docker secrets are copied into image layers or environment files?

A: Secrets can persist long after a container is deleted because they may remain in image layers, registries, or build history. That means API keys, passwords, and private keys can be recovered by anyone with access to the image. The practical failure is exposure of sensitive credentials across environments, not just inside a running container.

Q: Why do Docker build arguments create more risk for secrets than many teams expect?

A: Build arguments feel temporary, but Docker records them in build metadata and image layers. That means anyone with access to the image can inspect history, caches, or metadata and recover exposed values. The risk is not only disclosure at build time, but long lived persistence across environments, which makes secret removal much harder after publication.

Q: How do security teams know whether developer endpoints are leaking NHI secrets?

A: Look for unexpected token use, unusual outbound connections, unexplained browser profile access, and persistence mechanisms on workstations and build runners. If a compromised package executed on the machine, assume cloud keys, CI secrets, and other non-human credentials may already be exposed and rotate them before restoring trust.

Q: What is the difference between BuildKit secrets and multi-stage builds for protecting credentials in Docker?

A: BuildKit secrets mount sensitive material only during a build step, while multi-stage builds isolate entire stages and copy only selected outputs into the final image. BuildKit is useful for temporary access, but it can still leak if a command writes the secret into a file that survives. Multi-stage builds provide stronger containment when the secret must never reach the final stage.


Technical breakdown

Why Docker layers preserve deleted secrets

Docker builds create immutable layers, and each instruction adds a new layer on top of the previous state. If a secret enters the image during COPY ., it may remain recoverable from the earlier layer even if a later RUN rm command deletes the visible file. The final image does not show the file, but the layer history still contains the bytes. That is why image inspection tools can recover credentials from artifacts that appear removed. Practical implication: treat layer history as part of the secret exposure surface, not just the running container file system. Read Guide to the Secret Sprawl Challenge.

Practical implication: review layer contents and remove secrets before they ever enter the build context.

Why hardcoded Dockerfile values and build arguments leak credentials

A Dockerfile instruction such as RUN npm set ..._authToken=... embeds the secret in the build recipe, and docker image history --no-trunc can expose that command later. Build arguments are not a safe substitute if the value is written into a layer command or persisted by the build system, because the history still records the argument value in context. This creates a credential persistence problem, not just a code-quality issue. Practical implication: secrets used during image creation need a delivery path that avoids command history and layer persistence entirely. See the API Key Management Guide.

Practical implication: keep build-time credentials out of Dockerfile instructions and image history.

How multi-stage builds and BuildKit change secret exposure

Multi-stage builds isolate temporary build dependencies from the final runtime image, so the last stage can exclude source files, build artifacts, and temporary secrets that were needed earlier. BuildKit secrets improve on plain build arguments because they mount sensitive material for a command without baking it into the image by default. But that protection is conditional. If the application copies the secret into another file, such as an npmrc, the secret can still survive in the resulting artifact. Practical implication: use ephemeral secret injection only when the consuming process does not persist the credential elsewhere. Read the Ultimate Guide to NHIs: Static vs Dynamic Secrets.

Practical implication: use multi-stage builds and BuildKit only when the secret cannot be written back into the image.


Threat narrative

Attacker objective: The attacker wants a recoverable build-time credential that can be reused to access dependent systems, not just the image artifact itself.

  1. Entry occurs when a secret is introduced into the Docker build context through COPY ., a hardcoded Dockerfile value, or a build argument.
  2. Credential access follows when an attacker inspects image layers or history and extracts the preserved secret from a recoverable layer or command record.
  3. Impact occurs when the recovered credential is reused against private registries, cloud services, or CI/CD resources, extending the blast radius beyond the image itself.

Read and download The State of NHI & AI Agent Breach Report 2026, covering 200+ breaches impacting Non-Human Identities including AI Agents.


NHI Mgmt Group analysis

Layer retention is the real secret-zero problem: Docker does not just package applications, it preserves the evidence of how they were built. A secret that exists in an earlier layer, build command, or cached instruction is still an authentic credential event even if the final image looks clean. That means the security boundary is not the container runtime alone but the full build artifact chain, and practitioners need to treat image provenance as part of secret governance.

Build-time deletion is not revocation: Removing a file from the final image does not remove the access it granted during the build or the bytes preserved in prior layers. That distinction matters because many governance workflows assume a credential is gone once it is no longer visible. In reality, the deleted file can remain recoverable, so the control failure is not visibility but lifecycle closure.

Dockerfile secret handling exposes an identity blast radius: The same credential can surface through file copy, layer cache, command history, or a downstream file written by the process that consumed it. That makes the concept of a single secret across the build chain misleading; the secret exists in multiple recoverable forms. The practitioner conclusion is to govern build artifacts as identity-bearing objects, not just deployable code.

Static build credentials create avoidable NHI reuse: When the same token is reused across build, publish, and runtime steps, the image becomes a persistence mechanism for the credential itself. That is a lifecycle failure, not just a configuration mistake. Treat each credential as belonging to a specific build boundary and expect that any reuse expands the exposure window beyond the intended task.

Secret leakage in containers is usually governance debt, not tooling debt: The article shows several distinct leak paths, but they all stem from one assumption that build systems can safely carry credentials without formal lifecycle controls. That assumption fails when the build pipeline itself becomes part of the attack surface. The implication is that image creation needs the same governance discipline as any other privileged identity path.

From our research library:

What this signals

Secret leakage in container builds is a lifecycle problem, not a file-visibility problem: The file can disappear from the final image and still survive in the build chain. That means governance has to move left into image construction, with controls that prevent secrets from ever entering immutable layers.

Identity blast radius now includes build artifacts: A token used during packaging can become a long-lived access path if it appears in history, cache, or a downstream file written by the build step. Practitioners should treat every build artifact as part of the credential estate, not as a neutral by-product.

If a pipeline relies on manual review of the final image, it will miss the exact place where secret exposure happens. The control point is before layer creation, where build context, history, and temporary mounts decide whether the secret is transient or recoverable.


For practitioners

  • Map build-secret exposure paths Inventory where credentials enter Docker builds, including COPY ., hardcoded Dockerfile values, and build arguments, then classify each path by whether it leaves recoverable material in layers or history.
  • Replace persistent build secrets with isolated stages Move authentication and dependency fetch steps into a dedicated build stage so the final runtime image excludes source files, temporary credentials, and layer history that are not needed to run the application.
  • Use BuildKit only when the consumer does not persist the secret Mount credentials for the specific command that needs them, and verify that the application does not write the secret into files such as npmrc or logs that survive into the image.
  • Audit image history and extracted layers Review docker image history and saved layer contents for any credential that should have been transient, then treat any recovered token as exposed and unsuitable for continued use.
  • Limit build-context content before image creation Exclude .env, .git, and other sensitive files from the build context so they never enter the image layers in the first place, even temporarily.

Key takeaways

  • Docker layer caching can preserve credentials even after the visible file is deleted, so the final image is not proof that a secret is gone.
  • The article shows multiple exposure paths, including copied files, hardcoded Dockerfile values, and build arguments that remain recoverable through image inspection.
  • Preventing this class of leak requires build-time governance that keeps secrets out of immutable layers and out of command history in the first place.

Related NHI Mgmt Group resources: Guide to the Secret Sprawl Challenge · Ultimate Guide to NHIs: Static vs Dynamic Secrets · API Key Management Guide · CI/CD Pipeline Identity Security Guide


Standards & Framework Alignment

This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.

OWASP Non-Human Identity Top 10 and MITRE ATT&CK address the attack and risk surface, while NIST CSF 2.0 and CIS Controls v8 set the governance and control requirements practitioners need to meet.

FrameworkControl / ReferenceRelevance
OWASP Non-Human Identity Top 10NHI-02 — Secret LeakageThe article is centered on secrets exposed in Docker layers, history, and build arguments.
NHI-07 — Long-Lived SecretsHardcoded values and build arguments keep secrets alive beyond the intended build step.
Recommendation — Scan image layers and build history for exposed secrets, then revoke any credential that can still be recovered. Replace long-lived build credentials with ephemeral injection methods that do not survive into the final image.
MITRE ATT&CKTA0006 — Credential AccessThe attack pattern is credential recovery from image artifacts and history.
Recommendation — Hunt for exposed credentials in build artifacts and treat recovered secrets as credential-access indicators.
NIST CSF 2.0PR.AA-05 — Access Permissions, Entitlements and AuthorizationsThe post is about overexposed build credentials and their authorization scope.
Recommendation — Restrict build-time entitlements so packaging workflows cannot persist or reuse credentials beyond their task.
CIS Controls v8CIS-5 — Account ManagementSecrets inside build artifacts extend account lifecycle risk beyond intended use.
Recommendation — Manage build identities and secrets as accounts with scoped lifecycle and immediate revocation when exposed.

Key terms

  • Docker Image Layer: A Docker image layer is a permanent record of one build step. Each layer is stored immutably, so content introduced during build can remain recoverable even if later steps try to remove it. This is why secrets added too early can survive in history, caches, or exported image artifacts.
  • Build History: Build history is the record of commands and arguments used to create an image. It can expose tokens, passwords, and other secrets if those values are written into Dockerfile instructions or preserved by the build system.
  • Creation Context: The surrounding provenance of an identity, including who created it, from where, and in what project or platform it was attached. For agents, creation context is often the earliest reliable signal that an identity exists at all.
  • Multi-Stage Build: A multi-stage build separates build time dependencies from the final runtime image. Teams use it to keep private tooling, intermediate files, and sensitive build artifacts out of the final image, reducing the chance that credentials or other unwanted data survive into production.

What's in the full article

Truffle Security's full post covers the operational detail this post intentionally leaves for the source:

  • Step-by-step demonstrations of how layer inspection can recover a deleted .env file from a Docker image
  • Exact command sequences for extracting secrets from image layers and history using common Docker tooling
  • Concrete examples of multi-stage build patterns that keep build-only credentials out of the final image
  • BuildKit secret-mount behaviour and the specific failure mode when a command writes the secret back to disk

👉 Truffle Security's full post shows the Docker layer examples, extraction steps, and secure build patterns in detail.

Deepen your knowledge

NHI governance, secret management, and workload identity security are core topics in our NHI Foundation Level course, the industry's only accredited NHI security programme. If you are responsible for identity security strategy or NHI governance in your organisation, it is worth exploring.
NHIMG Editorial Note
Published by the NHIMG editorial team on October 19, 2026.
NHI Mgmt Group, the independent authority on Non-Human Identity, IAM, and Agentic AI security. nhimg.org