Token Leakage on Docker
Docker-Specific Remediation
Fixing token leakage in Docker involves ensuring that secrets never become part of an immutable image layer and are only made available at runtime through controlled channels. The following Docker‑native practices address the most common leakage vectors:
- Use multi‑stage builds to keep secrets out of the final image: Perform any step that requires a token in an intermediate stage, then copy only the needed artifacts to the final stage.
- Leverage BuildKit secrets (
--secret) : Pass tokens as secret files that are mounted during the build and automatically removed afterward. - Avoid
ENVorARGfor secrets: If you must use anARG, ensure it is not used in anyENVorRUNcommand that creates a layer; better yet, pass the value only at container runtime. - Use Docker secrets (Swarm) or configs for runtime injection: Store the token outside the image and make it available as a tmpfs‑mounted file or an environment variable that is not logged.
- Add a
.dockerignorefile: Exclude.env,id_*,*.jsoncontaining credentials from the build context. - Restrict access to the Docker daemon: Bind the daemon to a Unix socket or enable TLS authentication; never expose the TCP socket without mutual TLS.
- Sanitize logs and error messages: Ensure application code never prints tokens; use logging frameworks that redact known secret patterns.
- Scan images regularly: Tools like
docker scanor third‑party scanners can detect leftover secrets in layers; integrate scanning into CI pipelines.
Example Dockerfile using BuildKit secrets (requires DOCKER_BUILDKIT=1):
# syntax = docker/dockerfile:1.4
FROM alpine:3.19 AS builder
# Install curl for demo
RUN apk add --no-cache curl
# Secret file is mounted at /run/secrets/api_token
RUN --mount=type=secret,id=api_token \
TOKEN=$(cat /run/secrets/api_token) \
&& echo "Token length: ${#TOKEN}" \
&& curl -s -H "Authorization: Bearer $TOKEN" https://api.example.com/ping
FROM alpine:3.19
COPY --from=builder /app /app
# No secret remains in the final image
CMD ["/app/start.sh"]
When building, provide the secret via:
DOCKER_BUILDKIT=1 docker build \ --secret id=api_token,src=./api_token.txt \ -t myapp:latest .At runtime, inject the token as an environment variable or Docker secret, never bake it into the image. By combining these practices with regular scanning (e.g., via middleBrick’s CLI or GitHub Action), you can ensure that tokens stay confined to the intended trust boundary and are not inadvertently exposed through Docker‑related surfaces.
Docker-Specific Remediation
Fixing token leakage in Docker involves ensuring that secrets never become part of an immutable image layer and are only made available at runtime through controlled channels. The following Docker‑native practices address the most common leakage vectors:
- Use multi‑stage builds to keep secrets out of the final image: Perform any step that requires a token in an intermediate stage, then copy only the needed artifacts to the final stage.
- Leverage BuildKit secrets (
--secret) : Pass tokens as secret files that are mounted during the build and automatically removed afterward. - Avoid
ENVorARGfor secrets: If you must use anARG, ensure it is not used in anyENVorRUNcommand that creates a layer; better yet, pass the value only at container runtime. - Use Docker secrets (Swarm) or configs for runtime injection: Store the token outside the image and make it available as a tmpfs‑mounted file or an environment variable that is not logged.
- Add a
.dockerignorefile: Exclude.env,id_*,*.jsoncontaining credentials from the build context. - Restrict access to the Docker daemon: Bind the daemon to a Unix socket or enable TLS authentication; never expose the TCP socket without mutual TLS.
- Sanitize logs and error messages: Ensure application code never prints tokens; use logging frameworks that redact known secret patterns.
- Scan images regularly: Tools like
docker scanor third‑party scanners can detect leftover secrets in layers; integrate scanning into CI pipelines.
Example Dockerfile using BuildKit secrets (requires DOCKER_BUILDKIT=1):
# syntax = docker/dockerfile:1.4
FROM alpine:3.19 AS builder
# Install curl for demo
RUN apk add --no-cache curl
# Secret file is mounted at /run/secrets/api_token
RUN --mount=type=secret,id=api_token \
TOKEN=$(cat /run/secrets/api_token) \
&& echo "Token length: ${#TOKEN}" \
&& curl -s -H "Authorization: Bearer $TOKEN" https://api.example.com/ping
FROM alpine:3.19
COPY --from=builder /app /app
# No secret remains in the final image
CMD ["/app/start.sh"]
When building, provide the secret via:
DOCKER_BUILDKIT=1 docker build \ --secret id=api_token,src=./api_token.txt \ -t myapp:latest .At runtime, inject the token as an environment variable or Docker secret, never bake it into the image. By combining these practices with regular scanning (e.g., via middleBrick’s CLI or GitHub Action), you can ensure that tokens stay confined to the intended trust boundary and are not inadvertently exposed through Docker‑related surfaces.