8000 feat(fips): Project Brisbane prototype by slaskawi · Pull Request #53711 · keycloak/keycloak · GitHub
[go: up one dir, main page]

Skip to content

feat(fips): Project Brisbane prototype - #53711

Draft
slaskawi wants to merge 1 commit into
keycloak:mainfrom
slaskawi:brisbane_poc
Draft

slaskawi wants to merge 1 commit into
keycloak:mainfrom
slaskawi:brisbane_poc

Conversation

@slaskawi
@slaskawi slaskawi commented Oct 7, 2026 •
Copy link
Copy Markdown
Contributor

Summary

This draft prototypes Project Brisbane as an alternative FIPS cryptographic provider in Keycloak. Bouncy Castle remains the default. --features=fips,brisbane opts into Brisbane; brisbane depends on fips. The implementation uses the pinned JitPack artifact, OpenJDK 25, and an OpenSSL 3.1.2 FIPS provider with an OpenSSL 3.5.9 runtime.

The Brisbane PoC report covers the architecture, native build, exact macOS and Linux run steps, validation, and FIPS limits. This is a prototype, not a claim that Keycloak or this image is FIPS 140-3 validated.

Try the image

docker pull quay.io/sebastian_laskawiec/keycloak:brisbane
CONTAINER_ID=$(docker run --detach \
  --publish 8080:8080 \
  --env KC_BOOTSTRAP_ADMIN_USERNAME=admin \
  --env KC_BOOTSTRAP_ADMIN_PASSWORD=brisbaneAdminPassword25 \
  quay.io/sebastian_laskawiec/keycloak:brisbane \
  start --optimized --features=fips,brisbane --fips-mode=strict \
  --http-enabled=true --hostname=localhost)
docker logs --follow "$CONTAINER_ID"

The image is built with strict Brisbane mode. After the startup message, check discovery and request a token:

curl --fail --silent --output /dev/null --write-out 'HTTP %{http_code}\n' \
  http://127.0.0.1:8080/realms/master/.well-known/openid-configuration
curl --fail --silent \
  --request POST \
  --header 'Content-Type: application/x-www-form-urlencoded' \
  --data client_id=admin-cli \
  --data username=admin \
  --data password=brisbaneAdminPassword25 \
  --data grant_type=password \
  http://127.0.0.1:8080/realms/master/protocol/openid-connect/token

Discovery should return HTTP 200; the token response should contain a bearer access token. Confirm the native versions in the running image:

docker exec "$CONTAINER_ID" java --enable-native-access=ALL-UNNAMED \
  -Djipher.openssl.dir=/opt/jipher/openssl \
  -cp /opt/keycloak/lib/lib/main/com.github.slaskawi.brisbane-d50c2f1.jar \
  com.oracle.jipher.provider.JipherJCE

Expected: JipherJCE 20.1, OpenSSL 3.5.9, OpenSSL FIPS provider 3.1.2. Stop the demo with docker rm --force "$CONTAINER_ID". The example uses HTTP and an embedded database for local evaluation.

Implementation details

  • Brisbane is experimental and depends on fips. It is selected during augmentation, so switching providers requires rebuilding the distribution or image.
  • Brisbane registers JipherJCE and sets its FIPS or FIPS_STRICT policy before use. Strict mode requires JipherJCE to have highest provider priority.
  • Brisbane binds JWE ciphers to JipherJCE without fallback. It rejects RSA1_5; existing providers retain their behavior.
  • Maven uses a Brisbane JAR pinned to a JitPack source commit. Runtime needs Java 25, native access, and a configured OpenSSL 3 installation.
  • The UBI 9.8 image builds OpenSSL for its target architecture, combining a 3.5.9 runtime with the 3.1.2 FIPS provider. It runs self-tests and augments Keycloak in strict mode.
  • Augmentation removes unused provider JARs: Brisbane builds exclude Bouncy Castle FIPS; other builds exclude Brisbane.

Limitations

  • OS OpenSSL integration is limited to Oracle Linux. The pinned Brisbane version rejects UBI/RHEL with jipher.openssl.useOsInstance=true, even when their OpenSSL and FIPS packages are installed. This limits adoption on those distributions; the PoC retains its separate OpenSSL build. Pinned OS detection.
  • Clean Maven builds resolve the unsigned JitPack JAR even when Brisbane is disabled. JitPack availability and artifact provenance affect ordinary builds.
  • The JAR alone cannot run Brisbane. Each runtime needs compatible native OpenSSL files, configuration, Java 25, and native access.
  • Native files are architecture-specific. The published image covers Linux ARM64 and AMD64; other environments need their own build and verification.
  • OpenSSL self-tests and startup do not validate the image or Keycloak. The FIPS certificate covers the specified module and operating environments.
  • JipherJCE provides neither KeyStore nor JSSE. Keystores, TLS, certificate paths, and other providers still need audit.
  • Brisbane builds omit Bouncy Castle FIPS JARs, which may affect extensions. Clients using JWE RSA1_5 must choose another algorithm.
  • Container and token checks were manual; AMD64 ran under emulation. They do not cover every algorithm or establish Keycloak FIPS compliance.
  • Removing priority-based selection requires broad changes across signing, hashing, random generation, passwords/OTP, and SAML. Changing Brisbane alone would leave implicit provider lookups.
  • Elytron's X509CertificateBuilder signs certificates without a provider-selection hook. Explicit selection would require a different certificate-building path.
  • Santuario's DOMReference hashes XML references without a provider-selection hook. Its signature-provider hook does not cover these digests; removing priority dependence also requires changes to the XML signature integration.

Validation

  • Focused Profile, Brisbane, provider selection, Quarkus configuration, and JWE provider tests passed on JDK 25.
  • Keycloak distribution package, CLI help approvals, Spotless, and git diff --check passed.
  • UBI 9.8 ARM64 and AMD64 images: OpenSSL FIPS self-tests passed; strict Brisbane startup, OIDC discovery, and RS256 bearer tokens passed on both. AMD64 ran under emulation on an ARM64 host.
  • Independent brutal review and finding verification completed; fixed the confirmed JWE cipher fallback, ECDSA key generator alias, and FIPS guide issue.

AI assistance: Codex helped implement and review this prototype.


@Override
public Cipher getAesCbcCipher() throws NoSuchAlgorithmException, NoSuchPaddingException {
return Cipher.getInstance("AES/CBC/PKCS5Padding", jipherProvider);
@slaskawi
slaskawi force-pushed the brisbane_poc branch 4 times, most recently from 8a85c84 to 6ce3106 Compare October 7, 2026 20:05
@slaskawi slaskawi changed the title feat(fips): prototype Brisbane provider behind feature switch feat(fips): Project Brisbane prototype\ Oct 12, 2026
@slaskawi slaskawi changed the title feat(fips): Project Brisbane prototype\ feat(fips): Project Brisbane prototype Oct 12, 2026
Signed-off-by: Sebastian Łaskawiec <sebastian.laskawiec@defenseunicorns.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

0