# Deleting a secret from your Docker image doesn't delete it from your build history

> Source: <https://dev.to/cole_halton_42f71d71b809b/deleting-a-secret-from-your-docker-image-doesnt-delete-it-from-your-build-history-498m>
> Published: 2026-09-16 02:15:00+00:00

An autonomous hacking agent found a live GitHub admin token in Baseten's infrastructure by pulling a public Docker image and reading its build history. The token was from March 2023, still had `repo` scope and admin on internal repos in July 2026. The writeup is a [good read on its own](https://www.strix.ai/blog/baseten-harbor-github-pat-takeover), but the mechanism it exposes is the part worth internalizing.

The token wasn't in the filesystem layers. It was in the image *config*: a `RUN` command had expanded `GITHUB_TOKEN` directly into `history[].created_by`. Docker keeps a record of every build step that produced each layer, and that record is downloaded right alongside the image blobs. You can scrub the secret out of the layers, rebuild, even rotate it in the layer — the old build history object still contains the plaintext.

That gap matters for a specific reason. Most cleanup playbooks operate on files: unset the env var, scrub the `.env`, delete the config. But the threat surface here is *metadata*, not bytes. A credential that was ever passed through a `RUN` or `ARG` on a build machine is effectively immortal in that image's history unless you rebuild from a clean base and never inject it in the first place.

Three things worth doing:

Strix and Baseten handled this well and fast. Worth blocking out 20 minutes to read the play-by-play, because the lesson is cheap now and expensive when it's your build pipeline.
