git: allow signing commits with SSH key#1222
Merged
Merged
Conversation
This was referenced May 29, 2026
Member
|
@hiddeco can you please rebase this PR |
060b313 to
7c001f1
Compare
Re-exports the go-git Signer interface from the signature package so consumers can refer to it without importing go-git directly. Prepares for the upcoming NewOpenPGPSigner and NewSSHSigner constructors. Assisted-by: claude-code/claude-opus-4-7 Signed-off-by: Hidde Beydals <hidde@hhh.computer>
Wraps an *openpgp.Entity in a Signer so it can be used through the new generic signing path on CommitOptions. Produces the same ASCII-armored detached signature as go-git's internal gpgSigner, preserving existing commit-signing output bit-for-bit. The concrete OpenPGPSigner type is exported so callers can type-assert a Signer returned by NewOpenPGPSigner and distinguish it from other Signer implementations. Assisted-by: claude-code/claude-opus-4-7 Signed-off-by: Hidde Beydals <hidde@hhh.computer>
Wraps an SSH private key in a Signer that produces SSHSIG-armored signatures with namespace "git" and SHA-512 hash, matching Git's defaults for SSH-signed commits. The concrete SSHSigner type is exported so callers can type-assert a Signer returned by NewSSHSigner. This commit covers the unencrypted- key happy path; encrypted keys and the algorithm allowlist land in follow-up commits. Assisted-by: claude-code/claude-opus-4-7 Signed-off-by: Hidde Beydals <hidde@hhh.computer>
OpenSSH-format private keys cannot be classified as encrypted before attempting to parse. Detect *gossh.PassphraseMissingError, require a passphrase, and retry through ParsePrivateKeyWithPassphrase. Wrong- passphrase parse failures surface with the generic "could not parse" wrap; missing-passphrase errors are explicit. Assisted-by: claude-code/claude-opus-4-7 Signed-off-by: Hidde Beydals <hidde@hhh.computer>
Allowlist ssh-ed25519, ecdsa-sha2-nistp256/384/521, and ssh-rsa with key size at least 2048 bits. DSA and undersized RSA produce signatures modern OpenSSH refuses to verify, so reject them at construction time instead of letting downstream verify silently fail. Assisted-by: claude-code/claude-opus-4-7 Signed-off-by: Hidde Beydals <hidde@hhh.computer>
CommitOptions.Signer changes from *openpgp.Entity to the go-git Signer interface re-exported from the signature package, and WithSigner takes the same type. The gogit client forwards the value to go-git's generic Signer field, which takes precedence over the legacy typed SignKey. This is a breaking API change in pkg/git/repository; consumers must migrate to signature.NewOpenPGPSigner or signature.NewSSHSigner. Since pkg/git is still pre-1.0, the change lands in a coordinated minor. Refs #398[1]. [1]: #398 Assisted-by: claude-code/claude-opus-4-7 Signed-off-by: Hidde Beydals <hidde@hhh.computer>
Calls gogit.Client.Commit with WithSigner(NewOpenPGPSigner(...)) and verifies the resulting commit's gpgsig header through signature.VerifyPGPSignature. The table-driven harness leaves room for SSH and unsigned cases to land as new rows in follow-up commits. Assisted-by: claude-code/claude-opus-4-7 Signed-off-by: Hidde Beydals <hidde@hhh.computer>
Adds an ed25519 row to TestCommit_WithSigner that exercises NewSSHSigner and verifies the SSHSIG-armored gpgsig header through signature.VerifySSHSignature. Asserts the signature uses the "git" namespace and round-trips against the corresponding authorized_keys public key. Assisted-by: claude-code/claude-opus-4-7 Signed-off-by: Hidde Beydals <hidde@hhh.computer>
Adds an ecdsa-sha2-nistp256 row to TestCommit_WithSigner so the non-ed25519 SSH-signing path is exercised explicitly. Assisted-by: claude-code/claude-opus-4-7 Signed-off-by: Hidde Beydals <hidde@hhh.computer>
Adds a nil-signer row to TestCommit_WithSigner that pins the nil- interface guard at gogit/client.go: a typed-nil reaching go-git's commit path would panic on signer.Sign. The row also documents the contract that WithSigner(nil) produces an empty gpgsig header. Assisted-by: claude-code/claude-opus-4-7 Signed-off-by: Hidde Beydals <hidde@hhh.computer>
Adds the supported-algorithms paragraph to the NewSSHSigner godoc so the public surface signals up front which keys it will accept. No behaviour change; validateSSHSigningKey already enforces this. Assisted-by: claude-code/claude-opus-4-7 Signed-off-by: Hidde Beydals <hidde@hhh.computer>
NewSSHSigner now returns a typed sentinel error instead of a bare errors.New for the encrypted-key-without-passphrase case, so consumers can branch on it via errors.Is rather than matching the literal error string. Assisted-by: claude-code/claude-opus-4-7 Signed-off-by: Hidde Beydals <hidde@hhh.computer>
Member
|
The gitlab test is flaky, looks like a race condition at repo creation with GL API |
Member
|
Going to merge and release this before another small PR sneaks in |
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.
Builds on top of #1141