<p>There is another option only using pipe:</p>

<pre><code>docker run -d -i --name $n alpine sh -c 'read A; echo "[$A]"; exec some-server'
docker exec -i $n sh -c 'cat &gt; /proc/1/fd/0' &lt;&lt;&lt; _a_secret_
</code></pre>

<p>First, create the docker daemon with <code>-i</code>, the command <code>read A</code> will hang waiting for the input from <code>/proc/1/fd/0</code>;
Then run the second docker command, reading the secret from stdin and redirect to the last hanging process.</p>

CC BY-SA 4.0
2019-03-07T13:05:51.817Z
2019-03-07T13:05:51.817Z
James Z.M. Gao
<p>You have 3 methods to get secrets to an app inside a docker container. The first 2 involve docker configuration. The last one is to have your apps directly fetch secrets from a secret store.</p>

<h1>1 - Environment variables</h1>

<p>According to <a href="https://12factor.net/config" rel="noreferrer">"The 12 Factor App" guide</a>, secrets are merely config, and they should always be set in the environment. You could set your secrets as environment variables during the docker run, and your app accesses them from there.</p>

<h1>2 - Mounted volumes</h1>

<p>You could have your secrets all within a particular configuration/secrets file, then mount that to your instance as a <a href="https://docs.docker.com/storage/volumes/" rel="noreferrer">mounted volume</a>. </p>

<h1>3 - Fetch from secret store</h1>

<p>As @030 mentioned, you can use Hashicorp Vault (or "Amazon Secrets Manager", or any service like that).<br>
Your app, or a sidecar app can fetch the secrets it needs directly, without having to deal with any configuration on the Docker container. This method would allow you to use Dynamically created secrets (a very appealing feature of such systems) and without having to worry about the secrets being view-able from the file system or from inspecting the env variables of the docker container.</p>

<h2>Personal Opinion</h2>

<p>I believe env variables is the way to go. It's easier to manage, and you can still pull from a secret store like Hashicorp Vault, if you have you CI build system pull the secrets during the build and set them when you deploy. You get the best of both worlds, and the added benefit of your developers not needing to write application code to fetch secrets. <s>Devs should be focused on their code functionality, and not dealing with admin tasks like fetching passwords.</s></p>

<p>Your application's code should be focused on it's own app functionality itself, and not dealing with backend tasks like fetching passwords. Just like the 12 Factor App states.</p>

<p><em>Edit:</em> changed last sentence to remove implication of Developer vs SysAdmin silo-ing. The tasks themselves should be separate from a code perspective, but DevOps is about the same persons keeping both in mind and not be limited.</p>

<h2>Personal Opinion (Update)</h2>

<p>Per @Dirk's excellent comment (<a href="https://devops.stackexchange.com/questions/3902/passing-secrets-to-a-docker-container/3904#comment8152_3904">Passing secrets to a Docker container</a>), there is a <em>very</em> strong argument to prioritize a secret store over ENV vars, due to not wanting to leak them.</p>

CC BY-SA 3.0
2018-04-18T16:12:03.487Z
What are admin tasks? Devs are responsible for secure apps as well. Apart from that, +1.
030
CC BY-SA 3.0
2018-04-19T01:15:22.837Z
Definitely. I tend towards step 1, and in general the 12 factor app. Thanks for putting this together!
Preston Martin
CC BY-SA 3.0
2018-04-19T15:05:11.407Z
@030 admin tasks would be infrastructure and config shipping. Fetching passwords for the config is not what I would consider 'code functionality'. Those are tasks to enable the app to run. That can be passed to an automation system that is separate from the code base of the app itself. That app should just assume it has what it needs, and not worry about gathering the info as well.
BoomShadow
CC BY-SA 3.0
2018-04-19T15:24:46.537Z
This promotes silos. DevOps is doing things together instead of throwing things over the wall.
030
CC BY-SA 3.0
2018-04-20T15:03:32.883Z
The code _should_ be silo'd off from the infrastructure components. The actual people could code both the infrastructure automation and the app code base, but the tasks themselves should be separate. I see the last sentence of my original answer was silo-ing off the devs, the people. That _is_ a mistake. I'll edit that to be clearer.
BoomShadow
CC BY-SA 4.0
2019-02-01T17:03:44.413Z
Putting secrets into environment variables offers various possibilities for them to be leaked. A few examples: Everybody with access to the Docker daemon on the machine running the container can see them using the `inspect` or `exec` commands. Environment variables often get dumped to `stdout` or into logfiles when running in some debug mode. All spawned child processes can read and expose them which might be out of your control. More information e.g. here:  https://diogomonica.com/2017/03/27/why-you-shouldnt-use-env-variables-for-secret-data/
Dirk
CC BY-SA 4.0
2019-02-04T01:29:56.937Z
Thanks for the link @Dirk. I've never seen that so well put. I've known that something like Vault or Keywhiz is the ideal place to put secrets in the long run, but that's the most succinct argument I've ever read. Def swayed my opinion about prioritizing secret store sooner rather than later.
BoomShadow
CC BY-SA 4.0
2019-03-08T17:43:10.590Z
I am also grappling with this question. The thing I don't understand is, even if you use a credentials vault to secure your secrets, you still must authenticate to gain access to that vault, and that presumably requires some secret.  The same concern applies to using a password-protected KeyStore file.  Are we always stuck with passing at least the "meta credential" in the environment?
Wheezil
CC BY-SA 4.0
2019-03-09T06:15:37.037Z
@Wheezil a meta-credential is easier to secure than many specific credentials. you can frequently and automatically rotate the meta credential. the meta credential can go to a vault that is on a secured host and can have things like ip whitelisting so that it only accepts connections from your production subnets. you can also ensure that the vault uses encryption at rest and encryption in flight and mutual tsl and certificate pinning and all the other best practices that make things more secure.
simbo1905
CC BY-SA 4.0
2019-03-09T14:11:01.490Z
@simbo1905 thanks for the clarification!  What would you say is a good mechanism to secure the meta-credential?  My current thinking is just a file on disk with restrictive permissions, but is there a better way?
Wheezil
CC BY-SA 4.0
2019-03-09T18:32:01.013Z
k8s has the concept of secrets that you create then mount as volumes into the containers. the link above by Dirk shows the same thing with Swarm. so yes a simple file with restricted permissions visible to the container seems the standard practice. with k8s I can public key encrypt the file holding the secret and use an init container (a startup container that runs to completion before my webapp starts) that has the private key to decrypt the secret file so that my webapp all can see the decrypted secret.
simbo1905
CC BY-SA 4.0
2019-04-05T07:01:23.340Z
@Dirk (1) anyone with authenticated network access to the Docker daemon has full control over the containers, including RCE; there's no defense against that privilege level anyway (2) you can selectively restrict child processes from having access to env vars (3) spawned child process by default execute under the same user and have similar file access anyway. In any modern Linux distro, env vars are just as secret as the file system or remote file systems.
Paul Draper
CC BY-SA 4.0
2021-02-26T16:59:27.100Z
@Wheezil A practical example of what @simbo1905 described: in AWS you can provide permissions using Roles. You can for example create a role that has `read only` permission to a certain secret. You can assign that role to the docker server (or if possible to the docker container) so that the app can access that secret. This doesn't involve any permanent token exchange as it's all handled by the interna IAM mechanisms, and the permission is easiliy revoked from the role if needed (or the role unassigned).
Marcello Romani
CC BY-SA 4.0
2021-02-27T20:01:33.713Z
Ah, good point.  Managed identities are available on all cloud platforms and can be used to gain access to the secret store.
Wheezil
CC BY-SA 4.0
2018-04-18T15:15:53.920Z
2019-02-04T01:32:44.323Z
2019-02-04T01:32:44.323Z
BoomShadow
<p>I have a base docker image which is used to run image analysis software. For each container created from the image, there are a set of configuration settings, some of which are secrets (encryption keys, customer information, etc.), that are used by the software to analyze and distribute the processed images. How can I safely pass these secrets to a container? </p>

CC BY-SA 3.0
2018-04-18T14:38:33.493Z
Hashicorp vault
030
<docker><secret-management>
Passing secrets to a Docker container
Preston Martin
# Passing secrets to a Docker container

(Asked by: username_0 on 2018-04-18)

I have a base docker image which is used to run image analysis software. For each container created from the image, there are a set of configuration settings, some of which are secrets (encryption keys, customer information, etc.), that are used by the software to analyze and distribute the processed images. How can I safely pass these secrets to a container?

**Tags:** docker, secret-management

> **Comments:**
> **username_1**: Hashicorp vault  

---

## 2 answers

### Answer by username_3 on 2018-04-18. Score: 43 | Accepted answer

You have 3 methods to get secrets to an app inside a docker container. The first 2 involve docker configuration. The last one is to have your apps directly fetch secrets from a secret store.

# 1 - Environment variables

According to ["The 12 Factor App" guide](https://12factor.net/config), secrets are merely config, and they should always be set in the environment. You could set your secrets as environment variables during the docker run, and your app accesses them from there.

# 2 - Mounted volumes

You could have your secrets all within a particular configuration/secrets file, then mount that to your instance as a [mounted volume](https://docs.docker.com/storage/volumes/).

# 3 - Fetch from secret store

As @username_1 mentioned, you can use Hashicorp Vault (or "Amazon Secrets Manager", or any service like that).  
Your app, or a sidecar app can fetch the secrets it needs directly, without having to deal with any configuration on the Docker container. This method would allow you to use Dynamically created secrets (a very appealing feature of such systems) and without having to worry about the secrets being view-able from the file system or from inspecting the env variables of the docker container.

## Personal Opinion

I believe env variables is the way to go. It's easier to manage, and you can still pull from a secret store like Hashicorp Vault, if you have you CI build system pull the secrets during the build and set them when you deploy. You get the best of both worlds, and the added benefit of your developers not needing to write application code to fetch secrets. ~~Devs should be focused on their code functionality, and not dealing with admin tasks like fetching passwords.~~

Your application's code should be focused on it's own app functionality itself, and not dealing with backend tasks like fetching passwords. Just like the 12 Factor App states.

*Edit:* changed last sentence to remove implication of Developer vs SysAdmin silo-ing. The tasks themselves should be separate from a code perspective, but DevOps is about the same persons keeping both in mind and not be limited.

## Personal Opinion (Update)

Per @username_4's excellent comment ([Passing secrets to a Docker container](https://devops.stackexchange.com/questions/3902/passing-secrets-to-a-docker-container/3904#comment8152_3904)), there is a *very* strong argument to prioritize a secret store over ENV vars, due to not wanting to leak them.

> **Comments:**
> **username_1**: What are admin tasks? Devs are responsible for secure apps as well. Apart from that, +1.  
> **username_0**: Definitely. I tend towards step 1, and in general the 12 factor app. Thanks for putting this together!  
> **username_3**: @username_1 admin tasks would be infrastructure and config shipping. Fetching passwords for the config is not what I would consider 'code functionality'. Those are tasks to enable the app to run. That can be passed to an automation system that is separate from the code base of the app itself. That app should just assume it has what it needs, and not worry about gathering the info as well.  
> **username_1**: This promotes silos. DevOps is doing things together instead of throwing things over the wall.  
> **username_3**: The code _should_ be silo'd off from the infrastructure components. The actual people could code both the infrastructure automation and the app code base, but the tasks themselves should be separate. I see the last sentence of my original answer was silo-ing off the devs, the people. That _is_ a mistake. I'll edit that to be clearer.  
> **username_4**: Putting secrets into environment variables offers various possibilities for them to be leaked. A few examples: Everybody with access to the Docker daemon on the machine running the container can see them using the `inspect` or `exec` commands. Environment variables often get dumped to `stdout` or into logfiles when running in some debug mode. All spawned child processes can read and expose them which might be out of your control. More information e.g. here:  https://diogomonica.com/2017/03/27/why-you-shouldnt-use-env-variables-for-secret-data/  
> **username_3**: Thanks for the link @username_4. I've never seen that so well put. I've known that something like Vault or Keywhiz is the ideal place to put secrets in the long run, but that's the most succinct argument I've ever read. Def swayed my opinion about prioritizing secret store sooner rather than later.  
> **username_5**: I am also grappling with this question. The thing I don't understand is, even if you use a credentials vault to secure your secrets, you still must authenticate to gain access to that vault, and that presumably requires some secret.  The same concern applies to using a password-protected KeyStore file.  Are we always stuck with passing at least the "meta credential" in the environment?  
> **username_6**: @username_5 a meta-credential is easier to secure than many specific credentials. you can frequently and automatically rotate the meta credential. the meta credential can go to a vault that is on a secured host and can have things like ip whitelisting so that it only accepts connections from your production subnets. you can also ensure that the vault uses encryption at rest and encryption in flight and mutual tsl and certificate pinning and all the other best practices that make things more secure.  
> **username_5**: @username_6 thanks for the clarification!  What would you say is a good mechanism to secure the meta-credential?  My current thinking is just a file on disk with restrictive permissions, but is there a better way?  
> **username_6**: k8s has the concept of secrets that you create then mount as volumes into the containers. the link above by username_4 shows the same thing with Swarm. so yes a simple file with restricted permissions visible to the container seems the standard practice. with k8s I can public key encrypt the file holding the secret and use an init container (a startup container that runs to completion before my webapp starts) that has the private key to decrypt the secret file so that my webapp all can see the decrypted secret.  
> **username_7**: @username_4 (1) anyone with authenticated network access to the Docker daemon has full control over the containers, including RCE; there's no defense against that privilege level anyway (2) you can selectively restrict child processes from having access to env vars (3) spawned child process by default execute under the same user and have similar file access anyway. In any modern Linux distro, env vars are just as secret as the file system or remote file systems.  
> **username_8**: @username_5 A practical example of what @username_6 described: in AWS you can provide permissions using Roles. You can for example create a role that has `read only` permission to a certain secret. You can assign that role to the docker server (or if possible to the docker container) so that the app can access that secret. This doesn't involve any permanent token exchange as it's all handled by the interna IAM mechanisms, and the permission is easiliy revoked from the role if needed (or the role unassigned).  
> **username_5**: Ah, good point.  Managed identities are available on all cloud platforms and can be used to gain access to the secret store.  

---

### Answer by username_2 on 2019-03-07. Score: 4

There is another option only using pipe:
docker run -d -i --name $n alpine sh -c 'read A; echo "[$A]"; exec some-server'
docker exec -i $n sh -c 'cat > /proc/1/fd/0' <<< _a_secret_

First, create the docker daemon with -i, the command read A will hang waiting for the input from /proc/1/fd/0;
Then run the second docker command, reading the secret from stdin and redirect to the last hanging process.


---

