Skip to content

FIPS-compliant build chain for boringssl in Bazel Registry (bzlmod) #3587

@phlax

Description

@phlax

Objective

Initiate design, tracking, and implementation of a FIPS-compliant boringssl build chain for the toolshed Bazel Registry (with support for bzlmod),

Security/Compliance Considerations

  • FedRAMP guidance now mandates "latest stable versions" of toolchain (esp. llvm/clang/cmake/go/ninja), not legacy/pinned versions
  • Build-time validation (including post-build tests) for FIPS, as required for compliance—not optional, and must be enforced before libs are exported
  • First-class support for FIPS self-test results: Users must never be able to consume an unvalidated binary
  • Isolation from MVS: All FIPS-relevant build tools/deps (e.g., go-fips, cmake/ninja versions) must be out-of-band from Bazel MVS to prevent accidental version drift/capture. go-fips is critical for this; for cmake/ninja, use rules_foreign_cc toolchain registration, not as separate modules
  • BCR naming conventions: Use kebab-case for all new modules (e.g., boringssl-fips, go-fips) for clarity and searchability

Technical Plan

1. Module Chain (BCR)

  • boringssl-fips: main entrypoint; depends on rules_foreign_cc and go-fips
  • go-fips: supplies a FIPS-pinned Go runtime for validation tests, kept outside MVS
    • Needed because boringssl's FIPS validation logic is written in Go and run at build/test time
    • Other FIPS tools (cmake/ninja) handled via rules_foreign_cc toolchain registration, not as separate modules - as these are registered via foreign_cc they are already outside of MVS
  • Toolchain/LLVM: keep as dev_dependency; document compliance principle, but don't force consumers to upgrade yet

2. Build Process

  • Use cmake() from rules_foreign_cc with -DFIPS=1 for FIPS build
  • Self-test/validation as a post-processing step, required before export
  • Only validated build artifacts should be visible/usable to downstream consumers
    • All intermediate/non-validated build outputs MUST be private/inaccessible
    • Final targets (ssl, crypto, etc.) must depend on successful validation
  • A build/test chain like:
    1. Private: Build libs via cmake (cmake() rule)
    2. Private: Validation step (genrule or sh_test) runs FIPS self-tests; only exposes libcrypto.a/libssl.a if passing
    3. Public: ssl, crypto CC library targets export validated libs

3. Naming/Structure

  • boringssl-fips should be a standalone module (not built on top of boringssl), to avoid MVS entanglement
  • Document clear separation between FIPS/non-FIPS (consumer opts-in by specifying bazel_dep(name = "boringssl-fips", ...))

4. Other Considerations

  • Agent/owner should not take shortcuts: Security implications mean this chain must block unvalidated output as rigorously as possible
  • Foreign_cc as build solution: All cmake/ninja build logic now should use standardized, explicit toolchains, not ad-hoc shell/genrules
  • Continuous validation: As upstream FIPS rules/requirements evolve, registry should track toolchain changes and update the build/test chain accordingly

note: MVS is bzlmods "minimum version system" - for the fips build we need to take the build chain out of that in case a depedency specifies "latest unstable" or any version that resolves as non-fips-compliant

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions