Secrets: write-up best practices, do's and don'ts, roadmap #13490
Comments
|
ping @ewindisch @diogomonica @NathanMcCauley This is just a quick write-up. Feel free to modify/update the description if you think that's nescessary :) |
|
This is useful infos: As is this: |
|
@dreamcat4 there are some plans to implement a generic "secrets API", which would allow you to use either Vault, or Keywiz or you-name-it with Docker, but all in the same way. It's just an early thought, so it will require additional research. |
|
@thaJeztah Yep Sorry I don't want to detract from those efforts / discussion in any way. I am more thinking maybe it's a useful exercise also (as part of that longer process and while we are waiting) to see how far we can get right now. Then it shows up more clearly to others the limits and deficiencies in current process. What underlying is missing and needed the most to be added to improve the secrets. Also it's worth considering about the different situations of run-time secrets VS build-time secrets. For which there is also an area overlap area. And perhaps also (for docker) we may also be worth to consider limitations (pros/cons) between solutions that provide a mechanism to handle the secrets "in-memory". As opposed to a more heavily file-based secrets methods or network based ones e.g. local secrets server. Which are the current hacks on the table (until proper secrets API). This can help us to understand some of the unique value (for example of stronger security) added by a docker secrets API which could not otherwise be achieved by using hacks on top of the current docker feature set. However I am not a security expert. So I cannot really comment on those things with such a great certainty. |
|
@dreamcat4 yes, you're right; for the short term, those links are indeed useful.
Thanks! I think I had that in my original description, must have gotten lost in the process. I will add a bullet
Neither am I, that's why I "pinged" the security maintainers; IMO, this should be something written by them |
|
@thaJeztah great summary. I'll try to poke at this whenever I find some time. |
|
@diogomonica although not directly related, there a long open feature request for forwarding SSH key agent during build; #6396 given the number of comments, it would be good to give that some thinking too. (If even to take a decision on it whether or not it can/should be implemented) |
|
Assuming you could mount volumes as user other than root (I know it's impossible, but humour me), would that be a favourable approach to getting secrets into containers? If so, I'd advocate for an alternative to We could then emphasize a |
|
I've recently read a good article about that from @jrslv where he propose to build a special docker image with secrets just to build your app, and than build another image for distribution using results from running build image. So you have two Dockerfiles:
Now we can build our distribution like that: # !/bin/sh
docker build -t hello-world-build -f Dockerfile.build .
docker run hello-world-build >build.tar.gz
docker build -t hello-world -f Dockerfile.dist ^Your secrets are safe, as you never push I recommend to read @jrslv article for more details http://resources.codeship.com/ebooks/continuous-integration-continuous-delivery-with-docker |
|
Thanks for sharing @kepkin ! I like the idea of exporting the files and loading them in through a separate Dockerfile. It feels like squashing without the "intermediate layers being in the build cache" issue. However, I'm nervous that it'll complicate development and might require a third Dockerfile for simplicity. |
|
@kepkin no offense but that doesn't make any sense. Secrets are definitely not safe, since they are in the tarball and the tarball is being |
|
@TomasTomecek if I understand the example correctly, the tarball is not the image-layers, but just the binary that was built inside the build container. See for example; https://github.com/docker-library/hello-world/blob/master/update.sh (no secrets involved here, but just a simple example of a build container) |
|
@TomasTomecek I'm talking about secrets for building Docker image. For instance, you need to pass ssh key to checkout source code from your private GitHub repository. And the tarball contains only build artifacts but doesn't contain GitHub key. |
|
@kepkin right, now I read your post again and can see it. Sorry about that. Unfortunately it doesn't solve the issue when you need secrets during deployment/building the distribution image (e.g. fetching artifacts and authenticating with artifact service). But it's definitely a good solution for separation between build process and release process. |
|
@TomasTomecek that's exactly how I fetch artifacts actually. In Docker.build image I download some binary dependencies from Amazon S3 image which require AWS key & secret. After retrieving and building, I create a tarball with everything I need. |
|
@darmbrust Yes, that did the trick. |
|
It's probably not as smelly as exposing your ssh-agent credentials over tcp
via socat for any local process to steal, but indeed, as with anything
related to secrets, 'docker build' is pretty smelly indeed.
Actually, I'd forgotten that Docker for Mac can't expose Unix domain
sockets on the osx host to the containers, so that opens up even more of a
can of worms.
My current solution, run a Centos VM, GitHub machine user account
credentials go into it, build using the "Rocker" (deprecated) tool.
…On Thu, 26 Jul 2018, 21:49 Sameer Kumar, ***@***.***> wrote:
@darmbrust <https://github.com/darmbrust> Yes, that did the trick.
However, don't you think its smelly? Any better recommendations?
Thanks!
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#13490 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAZk5iz1kvCpZ0s65ng4TwL7LmHa9zZvks5uKitDgaJpZM4Eq021>
.
|
|
This entire bug is smelly. I haven't found a better way... there are several other approaches above, but I think all of the other secure ones require standing up a little http server to feed the information into the image. maybe less smelly, but more complexity, more tools, more moving parts. Not sure that anyone has found a "good" solution... we are all stuck waiting on the docker people to do something about it... don't hold your breath, since this bug was written in 2015, and they haven't even proposed a roadmap yet, much less a solution. |
|
It's so simple and obvious, allow the mounting of volumes, (files or
directories) into the container during the build.
This is not a technical limitation, it's a decision to not allow secrets in
order to preserve the behaviour of - check out, run build, same inputs, same
output, change a build arg if you want to invalidate the cache...
The problem is, the abstraction has becoming increasingly leaky
with people using all sorts of kludgy, insecure hacks to get a "secret"
into a container.
Newsflash, exposing your SSH keyring via TCP, even on localhost is not
secure, neither is passing credentials via environment variables (hint, run
ps, or peek in the /proc filesystem), command arguments, and environmental variables are all there, naked, for the world to see.
For developers of golang code this traditionally hasn't been an issue as they copy-and-paste
their dependencies into their projects rather than using a dependency management tool, golang developers call this practice, 'vendoring'.
For anyone working in other ecosystems where the build system
fetches dependencies from Git, or repositories that require authentication, it's a big problem.
I'm pretty sure there is some startup rule somewhere along the lines of,
"don't presume you know, how, or why, your users use the product".
…On Thu, 26 Jul 2018, 22:00 Dan Armbrust, ***@***.***> wrote:
This entire bug is smelly. I haven't found a better way... there are
several other approaches above, but I think all of the other secure ones
require standing up a little http server to feed the information into the
image. maybe less smelly, but more complexity, more tools, more moving
parts.
Not sure that anyone has found a "good" solution... we are all stuck
waiting on the docker people to do something about it... don't hold your
breath, since this bug was written in 2015, and they haven't even proposed
a roadmap yet, much less a solution.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#13490 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAZk5nvbBTj4BAv5TtELNIHhJN8mU0Ctks5uKi38gaJpZM4Eq021>
.
|
|
@binarytemple Everyone who has ever worked on Docker/moby (as in the engineers behind it) know exactly what the problem is and have even run up against it. Volumes is a solution that is itself incredibly leaky. The main thing here is providing the "right" abstraction rather than "any abstraction that happens to work"... we of course know this is painful for many in more than just this case. Lots of work has been done on the builder lately which isn't necessarily visible yet, but the fruits of this effort will begin to show up in coming months. If you really want to see something right now, you can take buildkit itself and run with it today, it sits on top of containerd, you can build a custom integration pretty quickly. |
|
Secret mounts support was added to buildkit in moby/buildkit#522 . They appear strictly on tmpfs, are excluded from build cache and can use a configurable data source. No PR yet that exposes it in a dockerfile syntax but should be a simple addition. |
|
There are 2 solutions to build images with secrets. Multi-stage build : FROM ubuntu as intermediate
ARG USERNAME
ARG PASSWORD
RUN git clone https://${USERNAME}:${PASSWORD}@github.com/username/repository.git
FROM ubuntu
# copy the repository form the previous image
COPY --from=intermediate /your-repo /srv/your-repoThen : Using a image builder : docker-build-with-secrets |
|
@BenoitNorrin sorry, but you've exposed that password to every process on the host system. Unix security 101 - don't put secrets as command arguments. |
|
Yes but there are some usages where security matters a little less:
|
|
If that's the only problem, @binarytemple, then simply adding the flag |
|
@Yajo could be, yes it's at least a workaround until buildkit ships with secrets mount. Good suggestion. Thanks. B |
|
Unfortunately most of the workarounds mentioned in these and the many other tickets still expose the secrets to the resulting image, or only works with specific languages where you only need dependencies during compile time and not during installation. @binarytemple that will never happen, the docker maintainers have already killed at least one PR fully documented and fully implemented of a safe secret feature. Given the rest of history (this 3 year old ticket isn't the oldest and definitely not the only ticket/PR on this topic) I think it's safe to say the docker maintainers don't understand the need for security, which is a big problem. |
|
The biggest pain point is secret rotations for me you've to maintain a graph of secret to services dependencies, and update twice each service (to get back to original secret name) listing secrets from services doesn't seem to be easy (I gave up after some attempts around You also have to specify the secret destination, when it's not the default I just hope for a simpler way to rotate secrets |
|
@caub here's some CLI help: Docker docs for formatting help come up with the rest of your inspect format:
That'll list all secret names in a service. If you wanted both name and ID, you could:
I always have my CI/CD (service update commands) or stack files hardcode the path so you don't have that issue on rotation. With labels you can have CI/CD automation identify the right secret if you're not using stack files (without needing the secret name, which would be different each time). |
|
@thaJeztah Are we ready to close this issue? |
|
For older versions of docker, using multistage build with copying secrets before build command is viable option, right?
|
|
@andriy-f yes, that works, as long as you;
|
|
build time secrets are now possible when using buildkit as builder; see the blog post here https://medium.com/@tonistiigi/build-secrets-and-ssh-forwarding-in-docker-18-09-ae8161d066 and the documentation; https://docs.docker.com/develop/develop-images/build_enhancements/ the |
|
Thank you @thaJeztah I did just a little more digging and found that article shortly after posting (previous post is now deleted). Thanks again! |
|
Cool. That closes the build time secrets question. Anything for runtime/devtime (ssh in OS X)? |
|
What is the current best-practice for run-time secrets to pass e.g. to an entrypoint script, without the need to set up some external service? Right now, it seems the build-time secret solution is easier than run-time. I could just mount a local |
|
Best practice is to encrypt secrets with a public key and allow only your runtime controller to decrypt and mount them. Encrypted secrets can be stored in a Git repository. For Kubernetes there is https://github.com/bitnami-labs/sealed-secrets |
Nice. What about in a simple setup that is not a cluster? Just a single Dockerfile..? |
|
There are basic tools to store secrets in a repository like https://git-secret.io/ Possible workflow:
|
|
I’ve seen this pattern many times and wondered to myself, “why would the software development team (who are busy installing npm and god knows what on their machines)“, be entrusted with runtime secrets such as the magic key that allows you to run up a $50k google bill overnight?
Surely this is a problem for the operations/security teams? Do they really need the application software developers handling this stuff?
|
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment has been hidden.
This comment has been hidden.
Yes. They need the tools and documentation the most. When they deploy with docker, they need to inject a lot of secrets in them. And they often version the compose files, kubernetes manifests, helm charts, terraform manifests, ansible playbooks or whatever they use to deploy the containers in git, so storing encrypted bundles there is useful to them too.
Operations don't need them to, but developers themselves do. The build and test infrastructure also involves a bunch of secrets. |
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
curl-ing the secrets and remove them afterwards, all in a single layer. (also see https://github.com/dockito/vault)So, what's needed?
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
In good tradition, here are some older proposals for handling secrets;
docker secretstorage feature" #6697The text was updated successfully, but these errors were encountered: