Azure / Azure/webhook-tls-manager
webhook-tls-manager image is not FIPS compliant
- Dominant language
- Go
- Stars
- 2
- Forks
- 8
- Avg merge
- 1d 39m
- Merged PRs (30d)
- 1
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](https://github.com/microsoft/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](https://github.com/microsoft/go/blob/microsoft/main/eng/doc/fips/README.md), 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](https://github.com/microsoft/go/blob/microsoft/main/eng/doc/fips/UserGuide.md). 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](https://github.com/golang/go/issues/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.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by locating the image build configuration, RSA key-generation and certificate-rotation code, and the CI workflow. Check the resulting binary for microsoft_systemcrypto=1 and run the test suite with the OpenSSL backend. Done means the image uses the required toolchain and OpenSSL-bearing base, generates RSA-3072 certificates, rotates incompatible existing certificates, and has a verified release tag.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- docker, go
- Domain
- devops, security
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100