Skip to content

webhook-tls-manager image is not FIPS compliant #59

Description

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

  • Build with the Microsoft build of Go, CGO_ENABLED=1, on an OpenSSL-bearing base image
  • Fail the build if the resulting binary does not report microsoft_systemcrypto=1
  • Change the RSA key size from 4096 to 3072
  • Rotate existing certificates whose key size does not match
  • Run the test suite against the OpenSSL backend in CI, not just the upstream toolchain
  • Release a new tag and verify the published image

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions