Closed sanchitbapat closed 11 months ago
Same thing happens to me. I'm trying to use secrets to workaround having to set the permissions on the host file, by setting the mode in the secret, but it end up with the exact same permissions of the host.
This issues comes up for me when using a keyfile for MongoDB replica authentication. The keyfile must not be world-readable, and in *nix this is easy to fix, in Windows (docker-desktop) it's not, so I was hoping that using secrets might fix the problem. It seems not
As bind mounts do not support different permissions (uid, gid and mode), I suspect that in order to support this, the content of such secrets must be copied into the container (as in #9553), or, use POSIX ACLs (more complex). Am I right @ndeloof? But why does the compose documentation mention such options if they are not supported in the first place?
well secrets and configs arent writeable (as per specification) so no reason why the implementation cant actually be a copy. unless the idea is that they can change during runtime...
I'm using a secret for a SSH Private Key that must have a 0400 mode. Setting the uid, gid and mode is a requirement.
secrets:
- source: ssh_host_ecdsa_key
target: /etc/ssh/ssh_host_ecdsa_key
mode: 0400
2022-12-14 20:41:23 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
2022-12-14 20:41:23 @ WARNING: UNPROTECTED PRIVATE KEY FILE! @
2022-12-14 20:41:23 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
2022-12-14 20:41:23 Permissions 0777 for '/etc/ssh/ssh_host_ed25519_key' are too open.
2022-12-14 20:41:23 It is required that your private key files are NOT accessible by others.
2022-12-14 20:41:23 This private key will be ignored.
2022-12-14 20:41:23 sshd: no hostkeys available -- exiting.
Same issue applies both to Compose v1 and v2 the root cause is that both use a bind mount to "inject" secret inside container, but bind mount doesn't allow a distinct UID/GID/mode to be exposed inside container.
A possible alternative I can imagine is to replace this approach with a copy
(just like we do with support for secret set by environment
). The sole drawback is that, doing so, changes to secret on host won't apply to secret inside container. Doesn't seem to be a major issue to me, but let me know if this would be a blocker for your usage.
In my own opinion, having to rebuild the image to change a secret isn't an option. Major issue? Not now because we haven't reach the production, we're still developing. But once in production, it will be a security concern.
The access to the container repository isn't as secure as the access to the production host. Somebody pulling the image will have access to the private keys. Not a good thing at all !
There must be control over the uid, gid and mode for a secret file.
having to rebuild the image to change a secret isn't an option
This is not my proposal: compose would copy the secret into the container (not image) after creation, and before start. This is how secret based on environment is implemented already.
Oh, my bad ! Sorry 'bout that !
So if a secret change, we need to restart the container. Am I right ?
yes indeed
Does it implies a redeploy of the container or just the starting phase will be enough ?
It would be great if a refresh can be triggered manually (ex: docker compose refresh-secrets) to redo the copy in the container. Having a watchdog to do this automatically may consume resources unnecessary. Secrets don't change often but being able to update them without a restart can be a good solution.
we could copy secret again at any time, or have a dedicated command for this purpose, but the more obvious one would be to trigger a container restart
As long as the secret file can be updated on the fly and still have the good uid
, gid
and mode
, I'm good !
I agree with the suggestion on a copy implementation, my use case is local development since I want to align local dev with a production swarm and a quick restart on local is totally acceptable to me.
On Thu, Dec 15, 2022, 16:14 Mario Gravel @.***> wrote:
As long as the secret file can be updated on the fly and still have the good uid, gid and mode, I'm good !
— Reply to this email directly, view it on GitHub https://github.com/docker/compose/issues/9648#issuecomment-1353160053, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABAXP2FJAB2TJB5D2UDM2BDWNMRVRANCNFSM53PZWJBQ . You are receiving this because you commented.Message ID: @.***>
I was testing out the secrets functionality using docker compose version 2.14.1 today and was surprised to learn that they don't work the way the docs say they should.
$ cat docker-compose.yaml
services:
bb:
image: busybox
command: sleep infinity
secrets:
- source: my_secret
target: /secret_file_target
uid: "1234"
gid: "5678"
mode: 0400
secrets:
my_secret:
file: ./secret_file_source
$ echo "this is my secret file" > secret_file_source
$ docker compose up -d
$ docker compose exec bb ls -l secret_file_target
-rw-rw-r-- 1 1000 1000 23 Jan 11 22:38 secret_file_target
This also seems to affect configs
as well.
Marking this issue as "kind/enhancement" as secrets never have supported having uid/gid set by compose (v1 or v2), this feature was introduced and only supported by docker swarm
I'm using a secret for a SSH Private Key that must have a 0400 mode. Setting the uid, gid and mode is a requirement.
secrets: - source: ssh_host_ecdsa_key target: /etc/ssh/ssh_host_ecdsa_key mode: 0400
2022-12-14 20:41:23 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2022-12-14 20:41:23 @ WARNING: UNPROTECTED PRIVATE KEY FILE! @ 2022-12-14 20:41:23 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2022-12-14 20:41:23 Permissions 0777 for '/etc/ssh/ssh_host_ed25519_key' are too open. 2022-12-14 20:41:23 It is required that your private key files are NOT accessible by others. 2022-12-14 20:41:23 This private key will be ignored. 2022-12-14 20:41:23 sshd: no hostkeys available -- exiting.
Can confirm this failing behavior (setting mode, uid & gid) which is not working for me too.
$ docker --version
Docker version 20.10.23, build 7155243
$ docker compose version
Docker Compose version v2.15.1
I came across this when I wanted to mount a private ssh key to the checkmk/check-mk-raw container via docker compose secrets and specify uid, gid & mode for the key, when I got the same UNPOTECTED KEY warning when executing ssh manually. According to the docs, this should be possible but did not work for me too.
@peterge1998 the key thing about the docs is the explicit wording
uid and gid: The numeric UID or GID that owns the file within /run/secrets/ in the service’s task containers. Default value is USER running container.
a service task
explictly refers to swarm containers
It would be nice if this was supported when using docker compose
I run the a container where the process runs as nobody
.
So o give it access to the secret I have to give nobody
read access to it on the host.
So if anyone gains access they can read the secrets in question without gaining root access.
A possible alternative I can imagine is to replace this approach with a
copy
(just like we do with support for secret set byenvironment
). The sole drawback is that, doing so, changes to secret on host won't apply to secret inside container. Doesn't seem to be a major issue to me, but let me know if this would be a blocker for your usage.
A regular Dockerfile COPY
directive for secrets is a bad idea, because the secret ends up in the image. It is not localized to the running container. The second someone accidentally uploads the image to a public docker repository, the secret is public knowledge.
I know https://github.com/docker/compose/pull/10498 is fine, because it does the copy at container-runtime, just wanted to state that copying a secret via COPY
in a dockerfile is dangerous.
@con-f-use I'm not talking about a Dockerfile COPY
but about using docker cp
after the container has been created. It won't be stored inside an image
Yes, I know. I wrote that, just wanted to be abundantly clear, so that inexperienced folk stumbling upon this issue don't do something they'll regret.
Will this allow us to use file-based secrets with a remote docker host, which is not currently possible with the bind-mount implementation?
@ianhinder yes indeed
Could this also be extended to configs? Currently I have to build a new image with the config files baked in, as docker configs in compose don't work with a remote docker host. If they were copied, similar to the secrets here, this would enable the use of local config files which appeared as standard configs on a remote host.
as docker configs in compose don't work with a remote docker host
What are you refering to here, can you give an example? (also I wish github issues had threads, as this is kinda offtopic to the original issue)
using bind mount for local files indeed doesn't work with a remote docker host, and is a significant limitation for this use-case
Ah, now I get it, yes especially if you need the files on container startup, because then you can't docker copy
or scp
them.
actually you can docker cp
into a container before after it has been created and before it get started
Indeed - you can copy, but then your project configuration can't be expressed purely from a declarative compose file, and needs to be "booted" from a shell script or equivalent. This makes it less easy to transfer it between environments.
sure, I'm not suggesting here to write your own hack-ish script to use docker cp
, just saying we have an opportunity here to replace bind mounts for secrets/config with copy to better control permissions and ownership within container's filesystem
Exactly, my hope as well!
unfortunately this approach is currently blocked by https://github.com/moby/moby/issues/34142
I assume the cp
work around will not work for build-time secrets…?
@nicholastulach exact, build time secrets are implemented by buildkit
@peterge1998 the key thing about the docs is the explicit wording
uid and gid: The numeric UID or GID that owns the file within /run/secrets/ in the service’s task containers. Default value is USER running container.
a
service task
explictly refers to swarm containers
That was totally unclear to me. Can we make more explicit which features are only supported with docker swarm?
@peterge1998 the key thing about the docs is the explicit wording
uid and gid: The numeric UID or GID that owns the file within /run/secrets/ in the service’s task containers. Default value is USER running container.
a service task explictly refers to swarm containers
@noahehall The docs quoted is present in Services top-level element where clearly the word services
refers to the children of services
root element in the compose file, as stated in second paragraph of "Services top-level element" page.
Therefore, I would argue that service's task
in that document naturally refers to a service in a compose file rather than a swarm container.
As @bodograumann says, if this is really a feature exclusive to docker swarm, it should be stated explicitly, or even removed from the document "Services top-level element" until it is actually something supported by docker compose
.
@marcpa00 the compose specification is not intended to only cover docker compose features, that's fine some feature only apply to an alternative tool (whenever docker swarm doesn't use the compose specification) as long as docker compose warn users about unsupported features. Also, docker compose may be able to implement this feature once docker engine allows setting uid/gid on mounts, which has been discussed already. In the meantime, this is already available for environment-based secrets.
unfortunately this approach is currently blocked by moby/moby#34142
@ndeloof Would it be possible to utilize a tmpfs mount, which allows some control of the mountpoint ownership (https://github.com/docker/compose/issues/3425#issuecomment-423091370), in conjunction with the "volume with some initial content" idea that was mentioned for configs (https://github.com/docker/compose/issues/8707#issuecomment-1049919868)?
Somewhat of a naive question, as I'm not familiar with how Docker Compose is implemented at a systems level, or if a tmpfs would cause issues with scenarios like, e.g., host/container restarts.
Any updates? I am running into this issue with Docker version 24.0.6, build ed223bc. compose.yml
services:
dev:
secrets:
- source: ssh_key
mode: 0400
secrets:
ssh_key:
file: ~/.ssh/id_ed25519
Executing commands within container
root@a0b9f2920f01:/usr/local/proj# ssh-add /run/secrets/ssh_key
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: UNPROTECTED PRIVATE KEY FILE! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0777 for '/run/secrets/ssh_key' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
The permissions of the initial file are used in the container.
So changing the permissions of the ~/.ssh/id_ed25519
would do the trick.
The problem is when you need to mount the secret in two container which want non compatible permissions eg. 400 in one and 440 in the other.
latest docker compose release warn you about this feature not being supported
WARN[0000] secrets `uid`, `gid` and `mode` are not supported, they will be ignored
the reason is that secrets are implemented as bind mounts, which comes with this limlitation.
The documentation says mode, uid, and gid all work for compose services for both configs and secrets: https://docs.docker.com/compose/compose-file/05-services/#long-syntax and https://docs.docker.com/compose/compose-file/05-services/#long-syntax-4
Why is this issue being closed as "not planned". It is critical that files be loaded into the container with controlled / explicit permissions. Go try running filebeat with a custom filebeat.yml file loaded in without setting the permissions on the file correctly and see how far you get.
What possible excuse can there be for this commitment to be backed out on?
Loading files into the service without control of permissions is absurd.
@quarky42 compose specification is a vendor-neutral definition of the compose file format, it doesn't define implementation details and limitation by Docker Compose. This feature can't be implemented by Docker Compose as the docker engine has no support for config or secret (only when ran in swarm mode), and it uses a bind mount hack as a workaround, which can't offer such options.
@quarky42 compose specification is a vendor-neutral definition of the compose file format, it doesn't define implementation details and limitation by Docker Compose. This feature can't be implemented by Docker Compose as the docker engine has no support for config or secret (only when ran in swarm mode), and it uses a bind mount hack as a workaround, which can't offer such options.
I feel like the confusion around this is warranted. The documentation that one would use for building a docker-compose.yaml doesn't indicate anywhere that there's a split in how secrets work when you use docker compose vs swarm. It's defined in the specification, and seemingly works partially in docker compose because of the aforementioned "bind mount hack"....though there's no indication via the documentation that any such hack is why it works in docker compose.
That's indeed a major challenge we have to address regarding inclusion of the Compose Specification in Docker docs, as then we miss "implementation details"
I'm using a secret for a SSH Private Key that must have a 0400 mode. Setting the uid, gid and mode is a requirement.
secrets: - source: ssh_host_ecdsa_key target: /etc/ssh/ssh_host_ecdsa_key mode: 0400
2022-12-14 20:41:23 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2022-12-14 20:41:23 @ WARNING: UNPROTECTED PRIVATE KEY FILE! @ 2022-12-14 20:41:23 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2022-12-14 20:41:23 Permissions 0777 for '/etc/ssh/ssh_host_ed25519_key' are too open. 2022-12-14 20:41:23 It is required that your private key files are NOT accessible by others. 2022-12-14 20:41:23 This private key will be ignored. 2022-12-14 20:41:23 sshd: no hostkeys available -- exiting.
I'm found solution:
services:
test:
container_name: test
image: busybox
volumes:
- ./source/.ssh:/root/ssh-copy
tmpfs:
- /root/.ssh
command: sh -c "cp /root/ssh-copy/* /root/.ssh/ && chmod 0400 /root/.ssh/* && ls -la /root/.ssh"
Dirty hack, but acceptable for me.
Is there any roadmap for this feature (I needed this with configs, not secrets)? Just wondering: why is it not in the docs, that this is actually not supported?
@ndeloof
latest docker compose release warn you about this feature not being supported
WARN[0000] secrets `uid`, `gid` and `mode` are not supported, they will be ignored
the reason is that secrets are implemented as bind mounts, which comes with this limlitation.
This error actually was more confusing than helpful to me, and is what led me to finding this discussion. It is seemingly counter to the Compose documentation, which makes it seem like they are supported.
Only reading through this entire discucssion did I learn that the Docker team uses the term service
as both a swarm-only term and as a top-level mapping in the Compose documentation. There's no way users are just going to "know" that this is the case, and, at minimum, warrants an asterisk on the documentation explaining so. Requiring your users to understand how Swarm works should not be a dependency for being successful with Compose.
I'll add my $0.02 that this seems to be a severe limitation to Docker Compose Secrets and implementation should be reconsidered. This leaves the use of secrets at the whim of the image maintainer as to whether they build in a fashion that allows for access or not.
For example, in the formal Postgres docker container, they run all entrypoints as a 999:999
(postgres
) user, meaning secrets become inaccessible during entrypoint and beyond. This severely limits the ability to extend that image's functionality with any use of secrets or add any dynamic capabilities through a Docker Compose configuration.
I’m frustrated with the inadequate documentation and inconsistent support between Docker Swarm and Compose. This is the seventh instance I’ve encountered where Swarm lacks support for a feature that Compose offers, or vice versa.
It feels misleading to promote the capability of managing both environments with a single unified configuration in the documentation when, in reality, the latest version of Docker CE does not support the new Compose specification in Swarm. Unfortunately, Swarm lacks dedicated documentation that clearly delineates supported and unsupported features. This time, I’m struggling to mount secrets or configurations in a Compose environment because the application in the container expects specific file permissions, which necessitates a workaround. This issue likely stems from the decision to share a specification across two distinct tools with different levels of support for this spec, both of which are provided by the same vendor.
If the intention is for this to be a standalone specification, it should be renamed from “Compose File” to a more tool-agnostic term. The documentation should explicitly state when a feature is not supported by these tools—before developers encounter errors during the transition from development to a small production environment, not after, and certainly not through a GitHub Issue due to an unhelpful error message.
I can foresee further confusion with the introduction of Compose Bridge, particularly if it lacks comprehensive documentation. This oversight leads to significant time wasted especially when designing around functionality provided by these tools.
Description
Docker secrets specified using the long syntax for the
docker-compose.yml
file fail to set the specifieduid
,gid
andmode
.Also, from the docs, the default value of the
uid
andgid
fields should be the user that runs the container however the value remains whatever was set on the host machine.Steps to reproduce the issue:
Dockerfile
RUN adduser tester -u 1005 --disabled-password CMD ["/bin/bash", "-c", "ls -al /run/secrets/target_secret_file.txt"]
❯ cat docker-compose.yml services: secrets-tester: build: . secrets:
secrets: some_secret_file: file: somefile.txt
❯ cat somefile.txt Text from a secret file
❯ docker compose run secrets-tester -rw-r--r-- 1 1000 1000 24 Jul 13 16:47 /run/secrets/target_secret_file.txt
❯ docker compose run secrets-tester -r--r----- 1 1005 1005 24 Jul 13 16:47 /run/secrets/target_secret_file.txt
❯ docker --version Docker version 20.10.17, build 100c701
❯ docker compose version Docker Compose version v2.6.0
❯ docker info Client: Context: default Debug Mode: false Plugins: app: Docker App (Docker Inc., v0.9.1-beta3) buildx: Docker Buildx (Docker Inc., v0.8.2-docker) compose: Docker Compose (Docker Inc., v2.6.0) scan: Docker Scan (Docker Inc., v0.17.0)
Server: Containers: 2 Running: 0 Paused: 0 Stopped: 2 Images: 1 Server Version: 20.10.14 Storage Driver: overlay2 Backing Filesystem: extfs Supports d_type: true Native Overlay Diff: true userxattr: false Logging Driver: json-file Cgroup Driver: cgroupfs Cgroup Version: 1 Plugins: Volume: local Network: bridge host ipvlan macvlan null overlay Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog Swarm: inactive Runtimes: runc io.containerd.runc.v2 io.containerd.runtime.v1.linux Default Runtime: runc Init Binary: docker-init containerd version: 3df54a852345ae127d1fa3092b95168e4a88e2f8 runc version: v1.1.2-0-ga916309 init version: de40ad0 Security Options: seccomp Profile: default Kernel Version: 5.10.102.1-microsoft-standard-WSL2 Operating System: Ubuntu 20.04.4 LTS OSType: linux Architecture: x86_64 CPUs: 8 Total Memory: 7.763GiB Name: DESKTOP-IGS6AOM ID: MBVL:76QX:UWDQ:AK7Z:BNGW:PYGL:EXFG:ZHGD:JM53:RBFZ:4SQV:5I7Z Docker Root Dir: /var/lib/docker Debug Mode: false Registry: https://index.docker.io/v1/ Labels: Experimental: false Insecure Registries: 127.0.0.0/8 Live Restore Enabled: false
WARNING: No blkio throttle.read_bps_device support WARNING: No blkio throttle.write_bps_device support WARNING: No blkio throttle.read_iops_device support WARNING: No blkio throttle.write_iops_device support