Skip to content

Keycloak doesn't honor --https-trust-store-type when automatically creating the Trust Store #50110

Closed

Description

@slaskawi

Before reporting an issue

  • I have read and understood the above terms for submitting issues, and I understand that my issue may be closed without action if I do not follow them.

Area

core

Describe the bug

When Keycloak automatically generates the Trust Store (using the TruststoreBuilder), it hardcodes the PKCS12. In a Strict FIPS environment this may either lead to a non-FIPS compliant configuration (as PKCS12 are not FIPS compliant) or a failure (dependning on the java.security configuration).

The TruststoreBuilder should repect the selected Trust Store type passed through the settings.

Version

nightly

Regression

  • The issue is a regression

Expected behavior

When --https-trust-store-type=bcfks is used, Keycloak should generate a BCFKS Trust Store.

Actual behavior

When --https-trust-store-type=bcfks is used, Keycloak generates a PKCS12 Trust Store.

How to Reproduce?

Use Keycloak container image and put a properly formed PEM file into the /opt/keycloak/conf/truststores. Configure the FIPS settings properly and pass the --https-trust-store-type=bcfks option in.

Observe the results.

Anything else?

There's a workaround for this issue. Create a BCFKS beforehand and then boot Keycloak up.

Here's the workaround for the UDS Platform:

Activity

  1. added theissue type on Jun 18, 2026
  2. slaskawi commented on Jun 18, 2026

    @slaskawi
    ContributorAuthor

    To Keycloak Maintainers - please assign this issue to me. I should have a Pull Request for it soon.

  3. shawkins commented on Jun 18, 2026

    @shawkins
    Contributor

    To Keycloak Maintainers - please assign this issue to me. I should have a Pull Request for it soon.

    Unfortunately this needs more discussion. There isn't a direct relationship between the --https-trust-store-type, and the generated truststor. This setting is only used when the --https-trust-store-file is specified.

    a non-FIPS compliant configuration (as PKCS12 are not FIPS compliant)

    An unencrypted PKCS12 truststore does appear to be FIPS compliant - can you elaborate on a configuration where it is not?

    I think the original motivation for having it always be PKCS12 was based around the idea that the generated file may end up being directly referenced, so having a consistent extension seemed good.

    An alternative would be to use logic similar to what we have in other places, like with the infinispan logic, that determine the store type from the CryptoProvider.getSupportedKeyStoreTypes. As we now have differentated the TruststoreFormat and KeystoreFormat, it would probably make sense to have a getSupportedTrustStoreTypes method.

  4. slaskawi commented on Jun 18, 2026

    @slaskawi
    ContributorAuthor

    Unfortunately this needs more discussion. There isn't a direct relationship between the --https-trust-store-type, and the generated truststor. This setting is only used when the --https-trust-store-file is specified.

    I believe there is:

    • The KeycloakRecorder#configureTruststore always checks ${kc.home}/conf/truststores - it's hardcoded.
    • The TruststoreBuilder#setSystemTruststore generates the PKCS12 Trust Store using the javax.net.ssl.* settings.
    • The FileTruststoreProviderFactory#init then uses the generated (by the TruststoreBuilder) PKCS12 Trust Store.

    In other words - a generated Trust Store is picked up automatically by Keycloak (unless the deprecated spi-truststore-file-* options are used but I'm ruling this out).

    So my argument is that if we specify the --https-trust-store-type, we should use this on both sides (creating the Trust Store and using it) of the code symmetrically. This leads to the idea that --https-trust-store-type might also configure what type of Trust Store shall be generated.

    An unencrypted PKCS12 truststore does appear to be FIPS compliant - can you elaborate on a configuration where it is not?

    Keycloak's TruststoreBuilder creates the merged system truststore as a Java PKCS12 keystore, saves it as keycloak-truststore.p12, and sets javax.net.ssl.trustStoreType=PKCS12. While saving, it sets only:

    keystore.pkcs12.certProtectionAlgorithm=NONE
    

    That disables certificate encryption in the PKCS12 file. It does not disable the PKCS12 integrity MAC. Because setSystemTruststore() passes the dummy password keycloakchangeit, the JDK PKCS12 implementation still emits MacData. In the OpenJDK 21 implementation used by the upstream Quay image, the default PKCS12 MAC algorithm is:

    keystore.pkcs12.macAlgorithm = HmacPBESHA256
    

    So HmacPBESHA256 is not selected by Keycloak directly. It is selected by the JDK PKCS12 keystore implementation when KeyStore.store(output, nonNullPassword) is called and no keystore.pkcs12.macAlgorithm override is present.

    To sum it up - PKCS12 is absolutely fine; the problem is the mix of OpenJDK 21 defaults and how Keycloak configures it.

    think the original motivation for having it always be PKCS12 was based around the idea that the generated file may end up being directly referenced, so having a consistent extension seemed good.

    💯 agree and I'm open for suggestions here!

    An alternative would be to use logic similar to what we have in other places, like with the infinispan logic, that determine the store type from the CryptoProvider.getSupportedKeyStoreTypes. As we now have differentated the TruststoreFormat and KeystoreFormat, it would probably make sense to have a getSupportedTrustStoreTypes method.

    This is actually a fantastic advice!

    Judging by the code, when using Fips1402StrictCryptoProvider, we should obtain only KeystoreUtil.KeystoreFormat.BCFKS, which satisfies the use case. Unless someone objects, I'll use that approach for the implementation.

  5. slaskawi commented on Jun 22, 2026

    @slaskawi
    ContributorAuthor

    @shawkins I've created a PR with your implementation suggestion. Looks even better than using --https-trust-store-type I think: #50149

  6. shawkins commented on Jun 22, 2026

    @shawkins
    Contributor

    @shawkins I've created a PR with your implementation suggestion. Looks even better than using --https-trust-store-type I think: #50149

    Thank you @slaskawi, we'll have a look.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/coreCore server — startup, configuration, providers/SPIs, cross-cutting concernskind/bugCategorizes a PR related to a bugpriority/importantMust be worked on very soonrelease/26.8.0team/cloud-native

    Type

    Fields

    No fields configured for bug.

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions