Why is ARG in a DOCKERFILE not recommended for passing secrets?

Roger Lam picture Roger Lam · Nov 10, 2015 · Viewed 26.4k times · Source

In http://docs.docker.com/engine/reference/builder/#arg , It recommendeds secrets are not passed through ARGS.

Note: It is not recommended to use build-time variables for passing secrets like github keys, user credentials etc.

At what point are secrets passed through build-time variables in danger?

Answer

VonC picture VonC · Nov 10, 2015

Update August 2018:

You now have docker build --secret id=mysecret,src=/secret/file.
See "safe way to use build-time argument in Docker".

Update January 2017:

Docker (swarm) 1.13 has docker secret.

However, as commented by Steve Hoffman (bacoboy):

[...]The secret command only helps swarm users is not a more general solution (like they did with attaching persistent volumes).
How you manage your secrets (what they are and who has access to them) is very system dependent and depends on which bits of paid and/or OSS you cobble together to make your "platform".
With Docker the company moving into providing a platform, I'm not surprised that their first implementation is swarm based just as Hashicorp is integrating Vault into Atlas -- it makes sense.

Really how the secrets are passed falls outside the space of docker run.
AWS does this kind of thing with roles and policies to grant/deny permissions plus an SDK.
Chef does it using encrypted databags and crypto "bootstrapping" to auth.
K8S has their own version of what just got released in 1.13.
I'm sure mesos will add a similar implementation in time.

These implementations seem to fall into 2 camps.

  • pass the secret via volume mount that the "platform" provides or (chef/docker secret/k8s
  • pass credentials to talk to an external service to get things at boot (iam/credstash/etc)

Original answer: Nov. 2015

This was introduced in commit 54240f8 (docker 1.9, Nov 2015), from PR 15182,

The build environment is prepended to the intermediate continer's command string for aiding cache lookups.
It also helps with build traceability. But this also makes the feature less secure from point of view of passing build time secrets.

issue 13490 reiterates:

Build-time environment variables: The build-time environment variables were not designed to handle secrets. By lack of other options, people are planning to use them for this. To prevent giving the impression that they are suitable for secrets, it's been decided to deliberately not encrypt those variables in the process.

As mentioned in 9176 comments:

env variables are the wrong way to pass secrets around. We shouldn't be trying to reinvent the wheel and provide a crippled security distribution mechanism right out of the box.

When you store your secret keys in the environment, you are prone to accidentally expose them -- exactly what we want to avoid:

  • Given that the environment is implicitly available to the process, it's incredibly hard, if not impossible, to track access and how the contents get exposed
  • It is incredibly common having applications grabbing the whole environment and print it out, since it can be useful for debugging, or even send it as part of an error report. So many secrets get leaked to PagerDuty that they have a well-greased internal process to scrub them from their infrastructure.
  • Environment variables are passed down to child processes, which allows unintended access and breaks the principle of least privilege. Imagine that as part of your application you call to third-party tool to perform some action, all of a sudden that third-party tool has access to your environment, and god knows what it will do with it.
  • It is very common for applications that crash to store the environment variables in log-files for later debugging. This means secrets in plain-text on disk.
  • Putting secrets in env variables quickly turns into tribal knowledge. New engineers don't know they are there, and are not aware they should be careful when handling environment variables (filtering them to sub-processes, etc).

Overall, secrets in env variables break the principle of least surprise, are a bad practice and will lead to the eventual leak of secrets.