A token in the environment
Reported by name only, and readable by anybody who can pull the image
{
"config": {
"User": "app",
"Env": ["PATH=/usr/bin", "NPM_TOKEN=REPLACE_ME"]
},
"rootfs": { "diff_ids": ["sha256:aaa"] }
}Read what is in an image without running it. Everything here is visible to anybody who can pull the image, which is the point of looking.
Or drop a file anywhere on this panel. Nothing is uploaded: the analysis runs in this tab.
The answer appears here
Paste on the left and press Read. Nothing leaves this tab.
Nothing else to flag.
No formatting problems, and nothing the rules object to. Worth remembering what that covers: this reads the file you pasted, not the account or cluster it will be applied to.
No finding matches that filter.
Real input you can load into the tool above. Each one shows a different thing going wrong, because that is what the tool is for.
Reported by name only, and readable by anybody who can pull the image
{
"config": {
"User": "app",
"Env": ["PATH=/usr/bin", "NPM_TOKEN=REPLACE_ME"]
},
"rootfs": { "diff_ids": ["sha256:aaa"] }
}Which means root, not a default user
{
"config": { "User": "", "Env": [] },
"rootfs": { "diff_ids": ["sha256:aaa"] }
}These are the ones that fail silently. The config is accepted, nothing raises an error, and the consequence arrives later.
Private means fewer people can pull it, not none. Everybody who can pull can read the config, and the value is also in every container's environment.
Instead:Pass it at run time, or use a build secret mount if it is only needed during the build.
One is uncompressed and the other compressed, so they never match. It looks exactly like a tampered image.
Instead:Compare diff_ids with diff_ids and manifest digests with manifest digests.
An unset User is root. The container runs as root whether or not the application wants to.
Instead:Add a USER instruction after the steps that need write access to system paths.
docker inspect shows it without starting a container, and a plain registry GET of the config blob shows it to anybody with pull access. There is no such thing as a secret in here.
Every variable and every value. There is no instruction that removes one, because the config records the final state rather than the sequence. A credential in an ENV is a published credential, and rebuilding does not un-publish an image already pushed.
A diff_id is the digest of the uncompressed layer tar; a manifest layer digest is the digest of the compressed blob. They describe the same layer through different bytes. Comparing them to verify an image always fails and always looks like tampering, which is a very convincing false alarm.
Not a default user, not nobody: root. Anything the process can reach on a mounted volume it reaches as root on the host's filesystem, and a container escape starts from a much better position.
docker history reads exactly this array. A build argument's value is recorded here whether or not the file it wrote survived, which is why deleting the file in a later layer does not help.
ENV, LABEL, EXPOSE and similar change the config without producing a layer. They still appear in the history, so the number of history entries is not the number of layers.
The layer contents. It reads the config, in your browser, and prints environment NAMES only, never values.