fix: avoid FIPS 140-only panic when parsing sops PGP private keys - #1846
Merged
joaopapereira merged 1 commit intoAug 13, 2026
Conversation
Parsing any OpenPGP key packet (golang.org/x/crypto/openpgp) unconditionally computes its RFC 4880 V4 fingerprint using SHA-1 as part of the wire-format parse itself, in PublicKey.setFingerPrintAndKeyId. Under Go's native FIPS 140-3 module running with GODEBUG=fips140=only, that SHA-1 call panics - so gpgKeyring.Write panics on every App reconcile that uses the sops PGP template backend (AppTemplateSops.PGP), before sops ever gets a chance to decrypt anything. That fingerprint is only used here as an OpenPGP key identifier while loading a user-supplied private key for later use by the external sops binary; it is not used to verify or trust any signature. Since Go 1.26, crypto/fips140.WithoutEnforcement lets us relax FIPS enforcement for just this parse call without weakening enforcement anywhere else in the binary, including the rest of gpgKeyring.Write - the subsequent Serialize calls were confirmed (by removing the wrapper locally) not to need it, since serializing already-parsed packets performs no further hashing. The sops Age backend is unaffected; ReadArmoredKeyRing is only reached from the PGP branch. Adds TestGpgKeyringWrite_UnderFIPS140Only, which reproduces the panic pre-fix under GOFIPS140=v1.0.0 GODEBUG=fips140=only. Signed-off-by: Sameer <sameer.khan@broadcom.com> Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Signed-off-by: Sameer <sameer.khan@broadcom.com>
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.
Problem
When kapp-controller is built with Go's native FIPS 140-3 module and run with strict enforcement (GODEBUG=fips140=only), using the sops template's PGP backend panics while loading the user's private key:
panic: crypto/sha1: use of SHA-1 is not allowed in FIPS 140-only modeThis happens on every reconcile of an
Appthat usesspec.template[].sops.pgp, making the PGP decryption path entirely unusable under strict FIPS mode.Root cause
gpgKeyring.Write (pkg/template/sops.go)callsgolang.org/x/crypto/openpgp.ReadArmoredKeyRingto parse the user-supplied private key. Parsing an OpenPGP key packet unconditionally computes its RFC 4880 V4 key fingerprint using SHA-1, as part of just building the in-memory key structure — regardless of whether that fingerprint is ever used for anything security-sensitive. SHA-1 is not an approved algorithm under FIPS 140-3, so under strict enforcement this call panics rather than returning an error.Fix
Wrap the
openpgp.ReadArmoredKeyRingcall incrypto/fips140.WithoutEnforcement(available since Go 1.26), which scopes the enforcement relaxation to just that one call rather than disabling FIPS enforcement for the process:This is safe because the fingerprint computed here is used only as a local identifier while loading the key for later use by the external sops binary — it does not verify or establish trust in any signature, so relaxing enforcement for this narrow, non-security parse step does not weaken any FIPS security guarantee.
WithoutEnforcementis a no-op everywhere exceptGODEBUG=fips140=only: it short-circuits to a direct call in non-FIPS builds and underfips140=on/off/unset, so this change has no effect outside of strict FIPS mode.Testing
TestGpgKeyringWrite_UnderFIPS140Onlyinpkg/template/sops_test.go, which loads a private PGP key and writes it out viagpgKeyring.Write. Confirmed it panics on the pre-fix code underGODEBUG=fips140=onlyand passes with the fix applied.GODEBUG=fips140=on/off/unsetand in non-FIPS builds — no behavioral change outside strict mode.pkg/templateunit suite with and withoutGODEBUG=fips140=only; no other regressions.