Repository navigation
feat(image): read an SSH catalog with a deploy key - #254
Merged
Merged
Conversation
The runtime stage adds openssh-client-default and installs GitHub's pinned SSH host keys (deploy/github_known_hosts) as /etc/ssh/ssh_known_hosts, so an ssh --catalog-repo can be read with a deploy key passed through GIT_SSH_COMMAND. deploy/poc documents the deploy-key option next to the App one, and serve's usage says an ssh --catalog-repo takes no App flags. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
gusfcarvalho
left a comment
Contributor
There was a problem hiding this comment.
ccf-review: COMMENT
no findings.
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.
Task: IMPROVEMENTS item 8, deploy-key follow-up (A4): fx/cat-a4-deploy-key-image on main.
Summary
A private catalog repo could already be read with an App installation token (#250) or, on a workstation, over SSH with a deploy key. The image had no SSH client, so the deploy-key path didn't work there. This PR adds the client and pins GitHub's host keys, and documents both ways.
apk addgainsopenssh-client-default. That package exists on Alpine 3.23 (openssh-client-default-10.2_p1-r0, which pulls inopenssh-client-commonandopenssh-keygen), so theopenssh-clientfallback wasn't needed. GitHub's host keys get copied from the newdeploy/github_known_hoststo/etc/ssh/ssh_known_hosts(COPY --chmod=0644). The image still holds no secrets and fetches nothing at build time.deploy/github_known_hosts: GitHub's ed25519, ECDSA and RSA host keys forgithub.com, taken fromhttps://api.github.com/meta(ssh_keys) on 2026-10-29. A header comment gives the date and the steps to refresh the file.GIT_SSH_COMMAND. The documented form isssh -i /run/secrets/catalog-deploy-key -o IdentitiesOnly=yes -o BatchMode=yes -o StrictHostKeyChecking=yes.deploy/poc/README.md:Hostalias orGIT_SSH_COMMANDon a workstation,known_hosts, a key with no passphrase or loaded in the agent, and the App-vs-deploy-key trade-off./run/secrets/catalog-deploy-keyand passes-e GIT_SSH_COMMAND=…, with the key owned by uid 65532 and mode 0600 (install -o 65532 -m 0600, or a Swarm secret'suid/mode).deploy/poc/.env.example: a commented SSH form ofFACTORY_CATALOG_REPOand a commentedGIT_SSH_COMMAND=…line.run.shis unchanged: it already passes anyFACTORY_CATALOG_REPO, and it sources.envwith allexport, soGIT_SSH_COMMANDreaches serve.--catalog-repotakes no App flags and is read with git's own SSH configuration.Does serve log the environment? GIT_SSH_COMMAND
No. Serve never logs its environment.
gitsource.git(internal/catalog/gitsource/gitsource.go:301) passesos.Environ()to git and never logs it. The key's path, which is not a secret, can still reach logs through ssh's stderr. When the key is missing or unreadable, ssh printsWarning: Identity file /run/secrets/catalog-deploy-key not accessible: …(checked in the image), and git's stderr becomes the error message (gitsource.go:308-312). That error then reaches:catalog source unreadable; keeping the live catalogwarn line (internal/controllers/catalogsync.go:261);CatalogStatus.SourceError(catalogsync.go:257);reconcile failed; retryingwarn line (internal/controllers/controller.go:234).The README says so. The key itself is never in any of them.
Host-key fingerprint cross-check
ssh-keygen -lf deploy/github_known_hosts, compared with GitHub's docs page "GitHub's SSH key fingerprints" (docs.github.com/…/githubs-ssh-key-fingerprints) and withapi.github.com/metassh_key_fingerprints:ssh-keygen -lfSHA256:+DiY3wvvV6TuJJhbpZisF/zLDA0zPMSvHdkr4UvCOqUSHA256:p2QAMXNIC1TJYWeIOttrVc98/R1BUFWu3/LiyKgUfQMSHA256:uNiVztksCsDhcc0u9e8BujQXVUpKZIDTMczCvj3tD2sThe docs page also lists
SHA256:br9IjFspm1vxR3iA35FWE+4VTyz1hYVLIE2t1/CeyWQas "DSA - closing down". It is left out on purpose: the meta API doesn't publish it, and OpenSSH 10 doesn't support DSA.Verification
make reviewable: passes (generated-code check, lint,go test -race,rules test66/66, vacuum 100/100).cmd/factory/deploykit_test.gopasses, since only commented lines were added to.env.example.gofmt -lon the Go files: clean.docker build -t factory:a4 .: builds.docker run --rm --entrypoint sh factory:a4 -c …):ssh -VprintsOpenSSH_10.2p1, OpenSSL 3.5.9;ssh-keygen -F github.com -f /etc/ssh/ssh_known_hostsfinds all three keys (file-rw-r--r-- root root), andssh-keygen -lfthere gives the fingerprints in the table above;timeout 60 … GIT_SSH_COMMAND='ssh -o BatchMode=yes -o StrictHostKeyChecking=yes' git ls-remote git@github.com:ContainerSolutions/factory.gitfails in about 1 s withgit@github.com: Permission denied (publickey).(exit 128). There is no host-key error and no hang. No key was used, read or printed;factory serve --helpshows the new usage sentence.compliance-framework/factory-catalog, read by the image. That means mounting the key at/run/secrets/catalog-deploy-key(uid 65532, 0600), passingGIT_SSH_COMMANDas documented and--catalog-repo git@github.com:compliance-framework/factory-catalog.gitwith no App flags, then confirming that catalog-sync loads it. A workstation run throughrun.shwith the SSHFACTORY_CATALOG_REPOis also untested here.For triage
.github/workflows/ci.ymlonly builds the kata image (line 138). The rootDockerfileis built only byrelease-image.ymlon a published release, so a broken runtime stage (a renamed Alpine package, a missingdeploy/github_known_hosts) would first fail at release time. Proposed fix: aci.ymljob (foundation's.github/) that runsmake imageand the three in-image checks above (ssh -V,ssh-keygen -F github.com -f /etc/ssh/ssh_known_hosts, and thels-remotethat must end inPermission denied (publickey)).design/workstreams/definitions.md. TheDockerfileis a repo-root file (foundation,definitions.md:132), anddeploy/github_known_hostssits underdeploy/, notdeploy/poc/. Both are named by the spec, so they are changed here.🤖 Generated with Claude Code