Description
openedon May 26, 2015
Handling secrets (passwords, keys and related) in Docker is a recurring topic. Many pull-requests have been 'hijacked' by people wanting to (mis)use a specific feature for handling secrets.
So far, we only discourage people to use those features, because they're either provenly insecure, or not designed for handling secrets, hence "possibly" insecure. We don't offer them real alternatives, at least, not for all situations and if, then without a practical example.
I just think "secrets" is something that has been left lingering for too long. This results in users (mis)using features that are not designed for this (with the side effect that discussions get polluted with feature requests in this area) and making them jump through hoops just to be able to work with secrets.
Features / hacks that are (mis)used for secrets
This list is probably incomplete, but worth a mention
- Environment Variables. Probably the most used, because it's part of the "12 factor app". Environment variables are discouraged, because they are;
- Accessible by any proces in the container, thus easily "leaked"
- Preserved in intermediate layers of an image, and visible in docker inspect
- Shared with any container linked to the container
- Build-time environment variables (Proposal: Add support for build-time environment variables to the 'build' API #9176, Support for passing build-time variables in build context #15182). 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.
- Mark .. Squash / Flatten layers. (flatten images - merge multiple layers into a single one #332, Add MARK and SQUASH builder instructions #12198, Add docker squash command #4232, Adds build option to squash newly built layers #9591). Squashing layers will remove the intermediate layers from the final image, however, secrets used in those intermediate layers will still end up in the build cache.
- Volumes. IIRC some people were able to use the fact that volumes are re-created for each build-step, allowing them to store secrets. I'm not sure this actually works, and can't find the reference to how that's done.
- Manually building containers. Skip using a Dockerfile and manually build a container, commiting the results to an image
- Custom Hacks. For example, hosting secrets on a server,
curl-ing the secrets and remove them afterwards, all in a single layer. (also see https://github.com/dockito/vault)
So, what's needed?
- Add documentation on "do's" and "don'ts" when dealing with secrets; @diogomonica made some excellent points in Proposal: Add support for build-time environment variables to the 'build' API #9176 (comment)
- Describe the officially "endorsed" / approved way to handle secrets, if possible, using the current features
- Provide roadmap / design for officially handling secrets, we may want to make this pluggable, so that we don't have to re-invent the wheel and use existing offerings in this area, for example, Vault, Keywiz, Sneaker
The above should be written / designed with both build-time and run-time secrets in mind
@calavera created a quick-and-dirty proof-of-concept on how the new Volume-Drivers (#13161) could be used for this; https://github.com/calavera/docker-volume-keywhiz-fs
Note: Environment variables are used as the de-facto standard to pass configuration/settings, including secrets to containers. This includes official images on Docker Hub (e.g. MySQL, WordPress, PostgreSQL). These images should adopt the new 'best practices' when written/implemented.
In good tradition, here are some older proposals for handling secrets;
- "Add private files support" Add private files support #5836
- "Add secret store" Add Secret store #6075
- "Continuation of the
docker secretstorage feature" Continuation of thedocker secretstorage feature #6697 - "Proposal: The Docker Vault" Proposal: The Docker Vault #10310