World map

 

BM: Baca dalam Bahasa Melayu

World D5: Ship & Shield

docker history tells secrets

You will learn: how secrets leak into image layers, and how build secrets keep them out.

Checked with Docker Engine 29 on 31 Oct 2026

The problem

docker history menu:1.0 lists every recipe line. Two rows show secrets: ENV API_KEY=kk_live_8f2a and ARG SHOP_TOKEN=tk_9b7c. Docker transcript: $ docker history menu:1.0 IMAGE CREATED CREATED BY SIZE COMMENT 66b12b488ce5 3 seconds ago CMD ["cat" "/app/menu.txt"] 0B buildkit.dockerfile.v0 <missing> 3 seconds ago COPY menu.txt /app/menu.txt # buildkit 12.3kB buildkit.dockerfile.v0 <missing> 3 seconds ago ENV API_KEY=kk_live_8f2a 0B buildkit.dockerfile.v0 <missing> 3 seconds ago RUN |1 SHOP_TOKEN=tk_9b7c /bin/sh -c echo "t… 4.1kB buildkit.dockerfile.v0 <missing> 3 seconds ago ARG SHOP_TOKEN=tk_9b7c 0B buildkit.dockerfile.v0 <missing> 9 days ago CMD ["/bin/sh"] 0B buildkit.dockerfile.v0 <missing> 9 days ago ADD alpine-minirootfs-3.22.7-x86_64.tar.gz /… 8.97MB buildkit.dockerfile.v0

Your laptop~/kedai

  • No open hatches

Lunchboxes (containers)

  • No containers yet

Frozen packs (images)

  • alpine:3.221 layers · 12.9MB
  • menu:1.03 layers · 12.8MB

0 containers (0 running), 2 images, 0 lockers.

Your recipe card is stuck to the pack. docker history shows every line, for anyone who pulls it. Spot the two secrets?

Predict

Line 3 of a recipe copies .env in. Line 4 runs rm .env. Is the secret in the image?

Pick one answer.

Try it

Be the detective. Show the full lines with --no-trunc, and find the token.

Your laptop~/kedai

  • No open hatches

Lunchboxes (containers)

  • No containers yet

Frozen packs (images)

  • alpine:3.221 layers · 12.9MB
  • menu:1.03 layers · 12.8MB

0 containers (0 running), 2 images, 0 lockers.

Watch

A build secret: A key lent to one RUN step only. It never lands in a layer. is lent to one RUN step, then taken back. It never lands in a layer.

Tap the line that borrows the secret.

0 of 1 found

Check

bash
docker build --secret id=shop_token,env=SHOP_TOKEN -t menu:1.1 .
…
docker history --no-trunc --format '{{.CreatedBy}}' menu:1.1
CMD ["cat" "/app/menu.txt"]
COPY menu.txt /app/menu.txt # buildkit
RUN /bin/sh -c test -n "$SHOP_TOKEN" # buildkit
CMD ["/bin/sh"]
ADD alpine-minirootfs-3.22.7-x86_64.tar.gz / # buildkit
Build with --secret id=shop_token,env=SHOP_TOKEN, then docker history: the RUN row shows test -n with no token value.

Real output. The RUN row names the variable, never its value. The token stayed in your locked spice box.

Check

Safe for a build, or a leak?

Drag a card into a box. Or tap the card, then tap the box.

      You did it!

      You can now find leaked secrets and keep them out of your images.

      Go deeper (optional)

      Leaked one? Cancel the token first: it is public now. Then fix the recipe, rebuild and delete the old tags. BuildKit warns you with SecretsUsedInArgOrEnv.

      Where the story breaks: a real freezer holds one pack. A registry hands out perfect copies forever, and they never thaw. But packs still go off: new holes are found in old images.

      Real mission

      1. docker history --no-trunc YOUR-IMAGE

      0 of 3 steps done · Your ticks are saved.