Summary
The published webhook-tls-manager image is not FIPS compliant and cannot be deployed to FIPS-enabled AKS node pools. There are two independent causes: how the image is built, and the RSA key size the code uses.
1. Build configuration
The image is currently built with the upstream Go toolchain, CGO_ENABLED=0, and a scratch base image. In that configuration all crypto is served by Go's own implementation, with no FIPS-validated module involved.
Making it compliant requires all three of:
- the Microsoft build of Go, which routes
crypto/* calls to the platform's OpenSSL
CGO_ENABLED=1 — required by the OpenSSL backend on Linux through Go 1.26 (Go 1.27 adds a cgo-less backend)
- a base image that ships OpenSSL. The binary loads
libcrypto via dlopen at startup and static linking to OpenSSL is not permitted, so a scratch base cannot work.
2. RSA key size
This is the part a Dockerfile-only change would not catch.
Certificates are currently generated with RSA-4096. The OpenSSL backend only implements rsa.GenerateKey for 2048 or 3072 bits — see the FIPS User Guide. Any other size silently falls back to non-FIPS Go crypto rather than failing, so the image can look compliant while its key generation is not. RSA-4096 public keys are likewise unsupported for x509/TLS in FIPS mode (see golang/go#41147).
The key size needs to move to 3072.
3. Existing certificates
The CA is issued with a 30 year validity, and rotation is currently triggered only by imminent expiry. Clusters that already hold an RSA-4096 CA would therefore never rotate to a compliant key on their own. Rotation needs to additionally trigger when the stored certificate's key size is not the expected one.
Proposed changes
Notes
- FIPS mode is detected at runtime from the host, so a single image continues to work on both FIPS and non-FIPS clusters. The
requirefips build tag is deliberately not used, as it would panic on startup on non-FIPS clusters.
- Moving off
scratch increases the image size.
GOEXPERIMENT=systemcrypto is accepted on Go 1.25/1.26 but rejected on Go 1.27, where the backend is selected automatically. It will need removing when the toolchain is upgraded.
Summary
The published
webhook-tls-managerimage is not FIPS compliant and cannot be deployed to FIPS-enabled AKS node pools. There are two independent causes: how the image is built, and the RSA key size the code uses.1. Build configuration
The image is currently built with the upstream Go toolchain,
CGO_ENABLED=0, and ascratchbase image. In that configuration all crypto is served by Go's own implementation, with no FIPS-validated module involved.Making it compliant requires all three of:
crypto/*calls to the platform's OpenSSLCGO_ENABLED=1— required by the OpenSSL backend on Linux through Go 1.26 (Go 1.27 adds a cgo-less backend)libcryptoviadlopenat startup and static linking to OpenSSL is not permitted, so ascratchbase cannot work.2. RSA key size
This is the part a Dockerfile-only change would not catch.
Certificates are currently generated with RSA-4096. The OpenSSL backend only implements
rsa.GenerateKeyfor 2048 or 3072 bits — see the FIPS User Guide. Any other size silently falls back to non-FIPS Go crypto rather than failing, so the image can look compliant while its key generation is not. RSA-4096 public keys are likewise unsupported for x509/TLS in FIPS mode (see golang/go#41147).The key size needs to move to 3072.
3. Existing certificates
The CA is issued with a 30 year validity, and rotation is currently triggered only by imminent expiry. Clusters that already hold an RSA-4096 CA would therefore never rotate to a compliant key on their own. Rotation needs to additionally trigger when the stored certificate's key size is not the expected one.
Proposed changes
CGO_ENABLED=1, on an OpenSSL-bearing base imagemicrosoft_systemcrypto=1Notes
requirefipsbuild tag is deliberately not used, as it would panic on startup on non-FIPS clusters.scratchincreases the image size.GOEXPERIMENT=systemcryptois accepted on Go 1.25/1.26 but rejected on Go 1.27, where the backend is selected automatically. It will need removing when the toolchain is upgraded.