How do you pass secrets to a container securely?
Learn to pass secrets to containers safely using Docker secrets, BuildKit build secrets, and secrets managers — without leaking them in image layers or env.
Expected Interview Answer
Pass secrets at runtime through mechanisms that keep them out of the image and off the process command line — Docker/Swarm secrets mounted as files, a dedicated secret manager (Vault, AWS/GCP Secrets Manager), or BuildKit build secrets for build-time credentials — never baked into ENV in the Dockerfile or passed as build args.
The core rule is that secrets must not persist in image layers, appear in `docker history`, or leak through inspect. In Swarm/Kubernetes, secrets are mounted read-only at /run/secrets and stored encrypted at rest. For builds, `RUN --mount=type=secret` exposes a credential only for that step without writing it to a layer. Environment variables are convenient but weaker: they show up in `docker inspect`, child processes, and logs, so prefer file-based mounts and rotate secrets regularly. For production, integrate a secrets manager so credentials are fetched at startup, scoped, and auditable.
- Keeps credentials out of image layers and docker history
- File-based secrets avoid exposure via docker inspect and env leaks
- Secrets managers add rotation, scoping, and audit trails
- BuildKit secrets protect build-time credentials without persisting them
- Encrypted-at-rest storage in Swarm/Kubernetes reduces breach impact
AI Mentor Explanation
Baking a secret into an image is like writing the team's strategy on the back of every player's shirt for the whole stadium to read. Passing it securely is like sealing the plan in the coach's briefcase and handing it only to the captain in the dressing room at match time — Docker secrets mount the credential privately at runtime and it never appears on the public scoreboard of docker history.
Step-by-Step Explanation
Step 1
Keep secrets out of the image
Never use ENV or ARG for secrets in a Dockerfile — they persist in layers and appear in docker history and inspect.
Step 2
Use build secrets for build time
With BuildKit, mount credentials via RUN --mount=type=secret so they're available only during that build step and not written to a layer.
Step 3
Mount runtime secrets as files
In Swarm/Kubernetes, define secrets and mount them read-only at /run/secrets, stored encrypted at rest.
Step 4
Integrate a secrets manager
For production, fetch credentials at startup from Vault or a cloud secrets manager so they're scoped, audited, and rotatable.
Step 5
Rotate and least-privilege
Grant each service only the secrets it needs and rotate them regularly to limit blast radius if one leaks.
What Interviewer Expects
- Knowing that ENV/ARG secrets leak via docker history and inspect
- Familiarity with Docker/Swarm secrets mounted at /run/secrets
- Awareness of BuildKit RUN --mount=type=secret for build-time secrets
- Understanding the role of a secrets manager (Vault, cloud managers)
- Grasp of rotation, least privilege, and encryption at rest
Common Mistakes
- Putting secrets in ENV in the Dockerfile, leaving them in image layers
- Passing secrets via --build-arg, which appears in docker history
- Committing .env files or secrets into the image or source control
- Assuming environment variables are secure (visible in docker inspect)
- Never rotating credentials or over-scoping access to all services
Best Answer (HR Friendly)
“You keep passwords and keys out of the image itself and instead hand them to the container only when it runs — through Docker's secrets feature or a dedicated secrets vault. That way the sensitive values aren't stored where anyone inspecting the image could read them, and they can be rotated safely.”
Code Example
# syntax=docker/dockerfile:1
FROM alpine
# Secret is mounted only for this RUN and never stored in the image
RUN --mount=type=secret,id=npm_token \
NPM_TOKEN=$(cat /run/secrets/npm_token) && \
echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc && \
npm ci && rm ~/.npmrcservices:
app:
image: my-app
secrets:
- db_password
secrets:
db_password:
file: ./db_password.txtDOCKER_BUILDKIT=1 docker build --secret id=npm_token,src=./npm_token.txt -t my-app .Follow-up Questions
- Why do secrets passed as --build-arg leak, and where do they appear?
- How does Docker Swarm store and distribute secrets securely?
- When would you choose HashiCorp Vault over native Docker secrets?
- How do you rotate a database password used by running containers?
- Why are environment-variable secrets considered weaker than file mounts?
MCQ Practice
1. Why should you avoid passing secrets with --build-arg?
Build args are recorded and can be seen via docker history, exposing the secret in the image.
2. Where are Docker/Swarm secrets mounted inside a container?
Secrets are mounted read-only at /run/secrets, kept out of the image and off environment variables.
3. Which BuildKit feature exposes a credential only during a build step?
RUN --mount=type=secret provides the secret for that step only and never writes it into an image layer.
Flash Cards
Why not put secrets in ENV/ARG in a Dockerfile? — They persist in image layers and are visible via docker history and docker inspect.
Where are Docker secrets mounted? — Read-only at /run/secrets, stored encrypted at rest in Swarm/Kubernetes.
How do you pass a build-time secret safely? — Use BuildKit's RUN --mount=type=secret with --secret on docker build.
Role of a secrets manager? — Provides scoped, audited, rotatable credentials fetched at startup (e.g., Vault, cloud managers).
Two key secret-hygiene practices? — Least-privilege scoping per service and regular rotation to limit leak blast radius.
Continue Learning
Related Interview Questions
What are GitHub Actions secrets and how do you manage them securely?
medium
What is a multi-stage build and why does it matter for image size?
medium
How do you reduce Docker image size and why does it matter?
medium
How does the Docker layer cache get invalidated and how do you order instructions to exploit it?
medium