Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ENV variables in Configs/Secrets #37377

Closed
ajardan opened this issue Jul 2, 2018 · 4 comments
Closed

ENV variables in Configs/Secrets #37377

ajardan opened this issue Jul 2, 2018 · 4 comments

Comments

@ajardan
Copy link

ajardan commented Jul 2, 2018

Description

Since configs are the recommended way of providing configuration files for services, would be great to be able to specify environment variables or use some sort of templating, so plain text secrets don't have to be used in a config. Now is impossible to provide a secret into a config/secret file in a secure way.

Steps to reproduce the issue:

  1. Create a config with an environment variable in it
    echo The path is $PATH | docker config create test-config
  2. Check the content of the config

Describe the results you received:

The string "The path is $PATH" is in the config

Describe the results you expected:

See the actual value of the $PATH environment variable instead of "$PATH"

Output of docker version:

$ docker version
Client:
 Version:	18.03.0-ce
 API version:	1.37
 Go version:	go1.9.4
 Git commit:	0520e24
 Built:	Wed Mar 21 23:06:22 2018
 OS/Arch:	darwin/amd64
 Experimental:	false
 Orchestrator:	swarm

Server:
 Engine:
  Version:	18.03.0-ce
  API version:	1.37 (minimum version 1.12)
  Go version:	go1.9.4
  Git commit:	0520e24
  Built:	Wed Mar 21 23:14:32 2018
  OS/Arch:	linux/amd64
  Experimental:	true
@cpuguy83
Copy link
Member

cpuguy83 commented Jul 2, 2018

Not sure that environment variables are any more secure, but this substitution should be taken care of by the shell and not the CLI.

This should be in https://github.com/docker/cli in any case, so closing here.
Thanks! 😇 🙇

@cpuguy83 cpuguy83 closed this as completed Jul 2, 2018
@thaJeztah
Copy link
Member

thaJeztah commented Jul 2, 2018

Configs are actually stored using the same mechanisms as secrets in Swarm; both are stored encrypted, and mount as RAMfs in the running container (so that they won't be stored on-disk).

If I understand your use-case correctly, the $PATH env-var is just for illustration, but your goal is to use an environment variable to store your secret, and use the value of that secret in a configuration file?

Docker 18.03 and up supports "templated" configs and secrets (implemented through #33702 and docker/cli#896), which allow you to use placeholders in your configs that are replaced at runtime by their actual value; this way, you're able to separate (reusable) configurations, and insert the secret (or environment variables, or other properties) in the configuration at runtime.

Having said the above; when designing the secrets (and configs) feature, one goal was to implement these to avoid the use of environment variables. Environment variables are notioriously insecure because they can leak in many places, so if possible, try to use "secrets" in your templates, instead of environment variables;

Documentation is lagging behind on this feature (docker/docs#6207), but below is an example;

Create a (non-templated) "secret" and "config";

printf 'This is secret mysecret' | docker secret create mysecret -
printf 'Hello, this is foobar' | docker config create foobar -

Create a templated config (--template-driver=golang) that;

  • Shows the name of the service it's used in
  • Shows the Node-ID that the container is running on
  • Shows the content of the $HELLO environment variable
  • Shows the content of the secret that's attached to the service as secret1
  • Shows the content of the config that's attached to the service as config1
docker config create --template-driver=golang example -<<'EOF'
This template is used on service: {{.Service.Name}}
This container is running on node with ID: {{.Node.ID}}
HELLO environment variable is: {{env "HELLO"}}
Secret "secret1" contains: {{secret "secret1"}}
Some other config ("config1") contains: {{config "config1"}}
EOF

Create a service named myservice that;

  • Has an environment variable $HELLO
  • Uses secret mysecret (with target/known) as secret1 inside the container
  • Uses config foobar as config1 inside the container
  • Uses the templated example config, at /myconfig
docker service create \
  --name myservice \
  --env HELLO=world \
  --secret src=mysecret,target=secret1 \
  --config src=foobar,target=config1 \
  --config src=example,target=/myconfig \
  nginx:alpine

When the service is deployed, exec into a container backing the service, and check the content of /myconfig in a container backing the service;

docker exec myservice.1.oszp02hc0wllxf6m2uqj02imk cat /myconfig

This template is used on service: myservice
This container is running on node with ID: oifk2p0hd4tvlb62uf76womx0
HELLO environment variable is: world
Secret "secret1" contains: This is secret mysecret
Some other config ("config1") contains: Hello, this is foobar

@ajardan
Copy link
Author

ajardan commented Jul 2, 2018

@thaJeztah this is EXACTLY the functionality I was looking for, thanks a lot for the explanation and link to future docs :)!

@thaJeztah
Copy link
Member

Great!!

Contributions are welcome on those docs 😇 I know the team has been very busy, so this likely fell into their backlog 😅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants