You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Keycloak doesn't honor --https-trust-store-type when automatically creating the Trust Store #50110
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.
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.
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.
Activity
slaskawi commentedon Jun 18, 2026
To Keycloak Maintainers - please assign this issue to me. I should have a Pull Request for it soon.
shawkins commentedon Jun 18, 2026
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.
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.
slaskawi commentedon Jun 18, 2026
I believe there is:
KeycloakRecorder#configureTruststorealways checks${kc.home}/conf/truststores- it's hardcoded.TruststoreBuilder#setSystemTruststoregenerates the PKCS12 Trust Store using thejavax.net.ssl.*settings.FileTruststoreProviderFactory#initthen uses the generated (by theTruststoreBuilder) 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-typemight also configure what type of Trust Store shall be generated.Keycloak's
TruststoreBuildercreates the merged system truststore as a JavaPKCS12keystore, saves it askeycloak-truststore.p12, and setsjavax.net.ssl.trustStoreType=PKCS12. While saving, it sets only:That disables certificate encryption in the PKCS12 file. It does not disable the PKCS12 integrity MAC. Because
setSystemTruststore()passes the dummy passwordkeycloakchangeit, the JDK PKCS12 implementation still emitsMacData. In the OpenJDK 21 implementation used by the upstream Quay image, the default PKCS12 MAC algorithm is:So
HmacPBESHA256is not selected by Keycloak directly. It is selected by the JDK PKCS12 keystore implementation whenKeyStore.store(output, nonNullPassword)is called and nokeystore.pkcs12.macAlgorithmoverride is present.To sum it up - PKCS12 is absolutely fine; the problem is the mix of OpenJDK 21 defaults and how Keycloak configures it.
💯 agree and I'm open for suggestions here!
This is actually a fantastic advice!
Judging by the code, when using
Fips1402StrictCryptoProvider, we should obtain onlyKeystoreUtil.KeystoreFormat.BCFKS, which satisfies the use case. Unless someone objects, I'll use that approach for the implementation.slaskawi commentedon Jun 22, 2026
@shawkins I've created a PR with your implementation suggestion. Looks even better than using
--https-trust-store-typeI think: #50149shawkins commentedon Jun 22, 2026
Thank you @slaskawi, we'll have a look.