Deliver tong secrets over docker exec stdin - #45
Merged
Conversation
Docker Desktop runs containers in a VM; a host FIFO bind-mounted across that boundary loses its pipe semantics (virtiofs shares file data, not kernel pipe objects), so secret delivery only worked on native Linux. Move the rendezvous inside the container: the tong's /bin/sh wrapper now creates the FIFO itself on a launcher-mounted tmpfs at /run/swarmforge, and the launcher streams the export script through `docker exec -i ... cat > <fifo>` fed on stdin. Every hop -- the exec stream, the tmpfs, the FIFO -- is served by the container's own kernel, so the transport behaves the same on Linux, macOS, and Windows. The handshake keeps its shape: the wrapper blocks reading the FIFO, the writer blocks until the read side opens, EOF marks the payload complete, and the secret still never appears in `docker inspect`, an argv, or a file. The deliver script refuses to run before the FIFO exists (a reserved exit code, retried under the same 30s deadline), so a too-early `cat` cannot leave the secret in a regular file. The tmpfs options are pinned (mode=1777) so a non-root image user can mkfifo even where the engine would inherit a stricter mode from a directory the image ships. A secret-bearing tong's image now needs mkfifo and rm alongside /bin/sh and cat. The host-side FIFO machinery -- temp dir, uid chown, and the image-user lookup that fed it -- is gone: the exec runs as the same user as the wrapper, so permissions agree by construction. Fatal delivery failures now carry docker's own stderr, distinguishing a crashed tong from a daemon problem.
The secret channel now occupies all of /run/swarmforge, not just the FIFO inside it: the tmpfs shadows anything the image ships there, and a mount landing inside it would sit on launcher wiring. Refuse a secret-bearing tong's mounts anywhere under the directory instead of only on the FIFO path.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Secret delivery to tongs relied on a host FIFO bind-mounted into the container, which breaks under Docker Desktop: containers run in a VM, and virtiofs shares file data across that boundary, not kernel pipe semantics. Delivery therefore only worked on native Linux.
The rendezvous now lives inside the container. The tong's
/bin/shwrapper creates the FIFO itself on a launcher-mounted tmpfs at/run/swarmforge, and the launcher streams the export script throughdocker exec -i ... cat > <fifo>on stdin. Every hop — the exec stream, the tmpfs, the FIFO — is served by the container's own kernel, so the transport behaves the same on Linux, macOS, and Windows.Properties preserved:
docker inspect(container or exec instance), an argv, or a file; the bytes live only in docker's API stream and the container kernel's pipe buffer.The deliver script guards with
[ -p ]and a reserved retry exit code so a too-earlycatcannot leave the secret in a regular file. Tmpfs options are pinned (mode=1777) so a non-root image user canmkfiforegardless of what the engine would inherit. Because the tmpfs occupies all of/run/swarmforge, a secret-bearing tong's mounts are now refused anywhere under that directory, not just on the FIFO path (second commit).Contract change: a secret-bearing tong's image needs
mkfifoandrmalongside/bin/shandcat. The host-side FIFO machinery (temp dir, uid chown, image-user lookup) is gone — the exec runs as the same user as the wrapper.Tested with the full unit suite (533 tests), including a real-shell round-trip of the wrapper and deliver scripts against an actual FIFO, a 100KB payload exceeding the pipe buffer, and the premature-delivery guard. The docker transport itself (exec stdin EOF through Docker Desktop's VM proxy) still needs a smoke test on a real Mac: launching any secret-bearing tong exercises it end to end.