Allow signing commits using SSH key#5920
Draft
hiddeco wants to merge 9 commits into
Draft
Conversation
Member
|
@hiddeco can you please incorporate these changes in this PR https://github.com/fluxcd/flux2/pull/5930/changes |
Member
|
@hiddeco We start the controller releases on Monday, I'd love to get this PR in before that if possible 🙏 |
Bumps fluxcd/pkg/git to v0.52.0, which exposes the generic signature.Signer interface and the NewOpenPGPSigner / NewSSHSigner constructors, and migrates pkg/bootstrap's two WithSigner call sites accordingly. Adds a parallel WithSSHCommitSigning option alongside the existing WithGitCommitSigning so callers can sign commits with an SSH private key. PlainGitBootstrapper now dispatches through a new resolveSigner helper that returns either an OpenPGP or SSH signer; the repository.WithSigner option is appended conditionally to avoid the typed-nil interface hazard the new generic field introduces. The bootstrap path's OpenPGP entity selector is renamed and exported as SelectOpenPGPSigningEntity so the flux CLI's pre-flight (introduced later in this branch) can call it directly instead of carrying a duplicate. Also bumps image-automation-controller/api to a pseudo-version that exposes SigningKey.Type and the SigningKeyTypeGPG/SigningKeyTypeSSH constants; the bump is bundled here so the rest of the branch builds incrementally. Refs fluxcd/pkg#398[1]. [1]: fluxcd/pkg#398 Signed-off-by: Hidde Beydals <hidde@hhh.computer>
Adds two layers of coverage for the SSH commit-signing path that the previous commit wires through PlainGitBootstrapper. TestPlainGitBootstrapper_resolveSigner exercises every branch of the new dispatcher: nil configuration, GPG-only, SSH-only, encrypted-SSH- without-passphrase failure, and the documented GPG-wins-when-both- set precedence. TestPlainGitBootstrapper_sshSignerProducesVerifiableCommit drives an end-to-end roundtrip: resolveSigner returns an SSH signer, the signer plugs into repository.WithSigner, gogit.Client.Commit produces a commit object, and signature.VerifySSHSignature cryptographically verifies the gpgsig header against the matching authorized_key. Catches regressions in the SSH-signing wiring that the dispatcher unit tests would miss. Signed-off-by: Hidde Beydals <hidde@hhh.computer>
Introduces four new persistent flags on flux bootstrap: --ssh-signing-key-file, --ssh-signing-password, the hidden alias --ssh-signing-passphrase, and the reuse boolean --ssh-signing-reuse-private-key. They sit next to the existing --gpg-key-ring / --gpg-passphrase / --gpg-key-id surface. bootstrapValidate pre-flights the configured signing key for the explicit GPG and SSH paths so malformed PEM, wrong passphrases, and unsupported SSH algorithms surface before any clone runs. The GPG pre-flight calls the now-exported SelectOpenPGPSigningEntity from pkg/bootstrap directly, so the pre-flight cannot drift from the bootstrap commit path. The reuse path's pre-flight runs inside each subcommand's RunE (where the subcommand-local SSH transport password is in scope) and lands with the wiring commits that follow. A small effectiveSshSigningPassword helper resolves the --ssh-signing-passphrase alias purely (returning the resolved value or a mutual-exclusion error) instead of mutating the package-scoped bootstrapArgs singleton inside bootstrapValidate. Mutual exclusion is enforced between the GPG and SSH groups, and between --ssh-signing-key-file and --ssh-signing-reuse-private-key. --ssh-signing-reuse-private-key requires --private-key-file; --ssh-signing-password requires --ssh-signing-key-file. The --ssh-signing-passphrase alias is hidden in --help. Signed-off-by: Hidde Beydals <hidde@hhh.computer>
Reads --ssh-signing-key-file when set, decodes the file contents, resolves the effective signing passphrase, and appends bootstrap.WithSSHCommitSigning to the bootstrap options. When --ssh-signing-reuse-private-key is set, reads the transport --private-key-file, pre-flights it against the subcommand-local gitArgs.password, and reuses the same bytes + passphrase for signing. The reuse-path pre-flight lives in this subcommand's RunE because bootstrapValidate does not have access to the transport password. Mutual exclusion with --gpg-* and explicit-path key-parse validation are enforced upstream in bootstrapValidate. Signed-off-by: Hidde Beydals <hidde@hhh.computer>
Adds the same explicit-path SSH-signing wiring to flux bootstrap github / gitlab / gitea / bitbucket-server, consulting the new effectiveSshSigningPassword helper for the resolved passphrase. The reuse-path wiring applies only to gitlab and bitbucket-server (which consume --private-key-file as the SSH transport key). github and gitea generate the transport key in-process, so they reject --ssh-signing-reuse-private-key explicitly with a message explaining why. The reject check fires immediately after each subcommand's bootstrapOpts slice literal closes, before any conditional appends, so the failure semantics match the reading order of the code. Signed-off-by: Hidde Beydals <hidde@hhh.computer>
Covers the validation matrix of the new --gpg-* / --ssh-signing-* surface: mutual exclusion (across GPG/SSH groups and within the SSH group between --ssh-signing-key-file and --ssh-signing-reuse-private- key), alias resolution between --ssh-signing-password and --ssh-signing-passphrase, the dependency checks (--ssh-signing- password requires --ssh-signing-key-file; --ssh-signing-reuse- private-key requires --private-key-file), and pre-flight key-parse failures (malformed PEM, encrypted SSH key without passphrase, GPG ring with wrong passphrase). Test keys are checked in so the test does not depend on local ssh-keygen or gpg invocations at run time. Signed-off-by: Hidde Beydals <hidde@hhh.computer>
Closes a pre-existing gap where the ImageUpdateAutomation SigningKey
field was reachable only by hand-editing the rendered YAML. The two
new flags --signing-key-secret and --signing-key-type populate the
spec.git.commit.signingKey block directly.
When --signing-key-secret is set without --signing-key-type, the run
function fills in 'gpg' explicitly so the rendered YAML matches what
the apiserver would default it to. Validation rejects --signing-key-
type without --signing-key-secret and rejects values outside
{gpg, ssh}, using the typed SigningKeyType constants exported from
the image-automation-controller API so the validator and populator
share a single source of truth.
Signed-off-by: Hidde Beydals <hidde@hhh.computer>
Adds golden-file tests for the new --signing-key-secret and --signing-key-type flags: no-signing (baseline), default-gpg (asserts type: gpg is rendered explicitly when only the secret is set), ssh, and the two validation-error cases. Establishes cmd/flux/testdata/create_image_update/ for future expansion of this command's coverage. Signed-off-by: Hidde Beydals <hidde@hhh.computer>
Extends the existing TestExport 'image update' case with a signingKey block on the seeded ImageUpdateAutomation, asserting the new field survives the kubeClient.Get + serialize path. Parallels how the existing fixture exercises every other field on the resource. Also patches the embedded CRD source under manifests/bases/image- automation-controller/ to inject the signingKey.type schema property into both v1 and v1beta2. The patch is transitional and should be removed once the image-automation-controller release bundle includes the new type field natively. Signed-off-by: Hidde Beydals <hidde@hhh.computer>
02ee573 to
8d23f40
Compare
Member
Author
|
@stefanprodan @matheuscscp fluxcd/image-automation-controller#1035 and this PR have both been updated. |
hiddeco
commented
Jun 13, 2026
| github.com/fluxcd/cli-utils v1.2.1 | ||
| github.com/fluxcd/go-git-providers v0.26.0 | ||
| github.com/fluxcd/helm-controller/api v1.5.5 | ||
| github.com/fluxcd/image-automation-controller/api v1.1.4 |
Member
Author
There was a problem hiding this comment.
This has to be updated once fluxcd/image-automation-controller#1035 ends up in a release.
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.
Depends on: