elastic / elastic/beats

Enable Kafka SASL SCRAM-SHA-256/512 in FIPS builds

Closed
#53,202 1 comment 0 reactions 1 assignee Claimed by @pickypg View on GitHub
enhancement Team:Elastic-Agent-Data-Plane
Dominant language
Go
Stars
12.7k
Forks
5k
Avg merge
2d 15m
Merged PRs (30d)
385

Description

## Problem

Running Beats in FIPS mode (`requirefips` build tag, `GOFIPS140=v1.0.0`) rejects `SCRAM-SHA-256` and `SCRAM-SHA-512` as Kafka SASL mechanisms, leaving `PLAIN` as the only usable option. This is particularly noticeable to users coming from the Java ecosystem (where BouncyCastle keeps SCRAM available in FIPS mode), making it reasonable to expect the same from Beats.

## Root cause (historical)

PR #43062 disabled SCRAM in FIPS builds with the reason:

> scram is using custom implementation of pbkdf2 which is not allowed in fips mode

At the time, `github.com/xdg-go/scram` used `github.com/xdg-go/pbkdf2`, a pure-Go PBKDF2 implementation outside any validated cryptographic module. That was a correct call.

## Why it can be re-enabled

All three conditions needed are already true in this repo, nothing needs upgrading:

1. `go.mod` already pins `github.com/xdg-go/scram v1.2.0` (released 2025-11-24). That release added a `//go:build go1.24` path that calls **stdlib `crypto/pbkdf2`** instead of the third-party implementation. The upstream changelog explicitly states the Go 1.24+ path "provides FIPS 140-3 compliance when using SHA-256 or SHA-512".
2. The repo targets Go 1.26.7, so the legacy `xdg-go/pbkdf2` path is never compiled.
3. Stdlib `crypto/pbkdf2` delegates to `crypto/internal/fips140/pbkdf2`, which is inside the certified boundary. `$GOROOT/lib/fips140/certified.txt` names `v1.0.0-c2097c7c` (`CMVP #5247`), and that archive ships the PBKDF2 implementation and its self-test.

The rest of SCRAM has always been FIPS-clean: HMAC-SHA-256/512 and SHA-256/512 are both approved algorithms, and SASLprep (`xdg-go/stringprep`) is Unicode normalization, not cryptography.

## Proposed changes

- Merge `sasl_fips.go` / `sasl_nofips.go` into a single untagged `Validate()` in `sasl.go`
- Remove the `//go:build !requirefips` tag from `scram.go`
- Merge the split unit tests into a single table-driven `sasl_test.go`
- Remove the `SkipIfFIPSOnly` guard from `filebeat/input/kafka`'s `TestSASLAuthentication`, letting the existing `goFIPSOnlyIntegTest` CI job verify SCRAM against a live broker

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.