Skip to content

Fix createLDAPCertStore failing in FIPS mode (#144376)#144453

Merged
JVerwolf merged 27 commits intoelastic:mainfrom
JVerwolf:fix/144376-ldap-certstore-fips
Mar 24, 2026
Merged

Fix createLDAPCertStore failing in FIPS mode (#144376)#144453
JVerwolf merged 27 commits intoelastic:mainfrom
JVerwolf:fix/144376-ldap-certstore-fips

Conversation

@JVerwolf
Copy link
Copy Markdown
Contributor

@JVerwolf JVerwolf commented Mar 17, 2026

In FIPS environments the LDAP CertStore provider is absent, so CertStore.getInstance("LDAP", null) throws NoSuchAlgorithmException with no cause. The entitlement check handler treated any NSAE as a denial and returned HTTP 403, causing EntitlementsAllowedNonModularIT to fail.

The fix catches NSAE(NoSuchAlgorithmException) in createLDAPCertStore() and re-throws only when getCause() != null, which is the signature of a genuine entitlement denial (the instrumentation creates the exception as new NoSuchAlgorithmException(notEntitledException)). A no-cause NSAE means the provider is simply absent and should be silently swallowed.

Adds unit tests that reproduce both paths by temporarily manipulating JCA providers.

Closes: #144376
Closes: #144377
Relates: #144431

In FIPS environments the LDAP CertStore provider is absent, so
CertStore.getInstance("LDAP", null) throws NoSuchAlgorithmException
with no cause. The entitlement check handler treated any NSAE as a
denial and returned HTTP 403, causing EntitlementsAllowedNonModularIT
to fail.

The fix catches NSAE in createLDAPCertStore() and re-throws only when
getCause() != null, which is the signature of a genuine entitlement
denial (the instrumentation creates the exception as
new NoSuchAlgorithmException(notEntitledException)). A no-cause NSAE
means the provider is simply absent and should be silently swallowed.

Adds unit tests that reproduce both paths by temporarily manipulating
JCA providers.
@JVerwolf JVerwolf requested a review from jdconrad March 17, 2026 22:21
@JVerwolf JVerwolf requested a review from a team as a code owner March 17, 2026 22:21
@JVerwolf JVerwolf added >bug :Core/Infra/Entitlements Entitlements infrastructure v9.4.0 labels Mar 17, 2026
@elasticsearchmachine elasticsearchmachine added the Team:Core/Infra Meta label for core/infra team label Mar 17, 2026
@elasticsearchmachine
Copy link
Copy Markdown
Collaborator

Pinging @elastic/es-core-infra (Team:Core/Infra)

@elasticsearchmachine
Copy link
Copy Markdown
Collaborator

Hi @JVerwolf, I've created a changelog YAML for you.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 17, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds handling for NoSuchAlgorithmException in createLDAPCertStore so the exception is suppressed when the LDAP CertStore algorithm is unavailable but rethrown when its cause is a NotEntitledException. Introduces NetworkAccessCheckActionsTests with four regression tests covering provider-present, provider-absent, entitlement-denial, and non-entitlement-denial paths. Removes two entries from muted-tests.yml that muted createLDAPCertStore-related tests.

Suggested labels

>test-mute

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Linked Issues check ✅ Passed PR fully addresses both linked issues by fixing NoSuchAlgorithmException handling in FIPS mode and adding comprehensive regression tests.
Out of Scope Changes check ✅ Passed All changes directly support the linked issue objectives: exception handling logic, regression tests, and unmuting previously failing tests.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • 🛠️ Update Documentation: Commit on current branch
  • 🛠️ Update Documentation: Create PR

Comment @coderabbitai help to get the list of available commands and usage tips.

@slobodanadamovic
Copy link
Copy Markdown
Contributor

slobodanadamovic commented Mar 18, 2026

@JVerwolf Thanks for handling this. I'll close my mute PR since it makes no sense to proceed with it.

One small suggestion, can you add >test-fips and >test-fips-140-3 labels in order to trigger FIPS related CI pipelines? This will verify the fix. You may need to merge main after adding labels in order for labels to be effective.

Also, these tests are failing in other branches as well. It would be great to backport this fix to all active ones.

@n1v0lg
Copy link
Copy Markdown
Contributor

n1v0lg commented Mar 18, 2026

@slobodanadamovic @JVerwolf since the PR is still waiting on a review it'd be great to mute the tests in the meantime to avoid blocking other PRs.

Thanks for the fix @JVerwolf!

@slobodanadamovic
Copy link
Copy Markdown
Contributor

slobodanadamovic commented Mar 18, 2026

@slobodanadamovic @JVerwolf since the PR is still waiting on a review it'd be great to mute the tests in the meantime to avoid blocking other PRs.

Thanks for the fix @JVerwolf!

I can re-open #144431 and merge it if I get 👍 (or do we even require approval for muting tests?)

@n1v0lg
Copy link
Copy Markdown
Contributor

n1v0lg commented Mar 18, 2026

do we even require approval for muting tests

nope mutes go straight to main without approval 👍 (I think automation might even just straight commit them without PRs but perhaps I'm making that part up)
thanks @slobodanadamovic!

@slobodanadamovic

This comment was marked as off-topic.

@JVerwolf
Copy link
Copy Markdown
Contributor Author

@slobodanadamovic I don't think you need approval to mute tests, but I gave it a 👍 anyways. Thanks for this!

Question: I don't see the labels you mentioned: >test-fips and >test-fips-140-3 as pre-existing in GH. When I add those, I'm prompted to create a new label. Are you sure that the automation you mentioned exists for this codebase? (Entitlements are a bit out of my wheelhouse, but I'll look in @jdconrad to double check the PR).

@slobodanadamovic slobodanadamovic added test-fips Trigger CI checks for FIPS test-fips-140-3 labels Mar 18, 2026
@slobodanadamovic
Copy link
Copy Markdown
Contributor

slobodanadamovic commented Mar 18, 2026

Question: I don't see the labels you mentioned: >test-fips and >test-fips-140-3 as pre-existing in GH. When I add those, I'm prompted to create a new label. Are you sure that the automation you mentioned exists for this codebase? (Entitlements are a bit out of my wheelhouse, but I'll look in @jdconrad to double check the PR).

My bad, they don't have > as prefix. I added them now.

@slobodanadamovic
Copy link
Copy Markdown
Contributor

Keep in mind that we now muted the failing tests on main. You'll need to unmute them after merging the main branch - since they will be skipped.

} catch (InvalidAlgorithmParameterException ex) {
// Assert we actually hit the class we care about, LDAPCertStore (or its impl)
assert Arrays.stream(ex.getStackTrace()).anyMatch(e -> e.getClassName().endsWith("LDAPCertStore"));
} catch (NoSuchAlgorithmException ex) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jdconrad should we consider solving this in a general way? Potentially always checking the thrown exception cause to ensure it's a NotEntitledException?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was considering seeing if a different exception made more sense, but the problem remains that we need to know if something isn't entitled. I'll think about how to fix this today.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JVerwolf After reviewing rule options, I do think NoSuchAlgorithmException is still the best one.

@mark-vieira is correct that we should guard this test with an additional check, though, to make sure it was actually a NEE that was thrown, but because the bridge is compile-only, you'll have to use a string comparison.

if (ex.getCause() != null && ex.getCause().getClass().getName().equals("org.elasticsearch.enti
          +tlement.bridge.NotEntitledException"))
Add a test for the normal (non-FIPS) path where the LDAP CertStore
provider is present and InvalidAlgorithmParameterException is caught.
Harden the provider removal helper to fail fast with a clear assertion
if a provider to be removed is not found in the installed list, rather
than silently using position 0 and restoring to the wrong slot.
…elasticsearch into fix/144376-ldap-certstore-fips
Copy link
Copy Markdown
Contributor

@jdconrad jdconrad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just one minor change request.

} catch (InvalidAlgorithmParameterException ex) {
// Assert we actually hit the class we care about, LDAPCertStore (or its impl)
assert Arrays.stream(ex.getStackTrace()).anyMatch(e -> e.getClassName().endsWith("LDAPCertStore"));
} catch (NoSuchAlgorithmException ex) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JVerwolf After reviewing rule options, I do think NoSuchAlgorithmException is still the best one.

@mark-vieira is correct that we should guard this test with an additional check, though, to make sure it was actually a NEE that was thrown, but because the bridge is compile-only, you'll have to use a string comparison.

if (ex.getCause() != null && ex.getCause().getClass().getName().equals("org.elasticsearch.enti
          +tlement.bridge.NotEntitledException"))
@JVerwolf
Copy link
Copy Markdown
Contributor Author

I'm running into two (seemingly) unrelated failures that also happen on main:

  1. Failure 1: ./gradlew ":server:test" --tests "org.elasticsearch.index.mapper.TsidExtractingIdFieldMapperTests.testParsedDescriptionWithIndexDimensions {p0=s1=1 p1=false}" -Dtests.seed=18ECDFDC94B74127 -Dtests.locale=hu -Dtests.timezone=Pacific/Fiji -Druntime.java=25 -Dtests.fips.enabled=true
  2. Failure 2: ./gradlew ":server:test" --tests "org.elasticsearch.index.mapper.TsidExtractingIdFieldMapperTests.testParsedDescriptionWithIndexDimensions {p0=2022-01-01T01:00:01Z p1=false}" -Dtests.seed=18ECDFDC94B74127 -Dtests.locale=hu -Dtests.timezone=Pacific/Fiji -Druntime.java=25 -Dtests.fips.enabled=true
@JVerwolf
Copy link
Copy Markdown
Contributor Author

run elasticsearch-ci/part-1-fips-140-3

@JVerwolf
Copy link
Copy Markdown
Contributor Author

This PR is blocked on this issue: #144678, as it's preventing a clean CI run.

@JVerwolf
Copy link
Copy Markdown
Contributor Author

@elasticmachine test serverless

@JVerwolf JVerwolf disabled auto-merge March 24, 2026 19:57
@JVerwolf JVerwolf merged commit 8234302 into elastic:main Mar 24, 2026
38 of 48 checks passed
@JVerwolf
Copy link
Copy Markdown
Contributor Author

Passed in CI but the status failed to report back to GH: https://buildkite.com/elastic/elasticsearch-pull-request/builds/131176. Merging

@elasticsearchmachine
Copy link
Copy Markdown
Collaborator

💔 Backport failed

You can use sqren/backport to manually backport by running backport --upstream elastic/elasticsearch --pr 144453

JVerwolf added a commit to JVerwolf/elasticsearch that referenced this pull request Mar 24, 2026
In FIPS environments the LDAP CertStore provider is absent, so
CertStore.getInstance("LDAP", null) throws NoSuchAlgorithmException
with no cause. The entitlement check handler treated any NSAE as a
denial and returned HTTP 403, causing EntitlementsAllowedNonModularIT
to fail.

The fix catches NSAE in createLDAPCertStore() and re-throws only when
getCause() != null, which is the signature of a genuine entitlement
denial (the instrumentation creates the exception as
new NoSuchAlgorithmException(notEntitledException)). A no-cause NSAE
means the provider is simply absent and should be silently swallowed.

Adds unit tests that reproduce both paths by temporarily manipulating
JCA providers.

(cherry picked from commit 8234302)

# Conflicts:
#	muted-tests.yml
@JVerwolf
Copy link
Copy Markdown
Contributor Author

💚 All backports created successfully

Status Branch Result
9.3
9.2
8.19

Questions ?

Please refer to the Backport tool documentation

JVerwolf added a commit to JVerwolf/elasticsearch that referenced this pull request Mar 24, 2026
In FIPS environments the LDAP CertStore provider is absent, so
CertStore.getInstance("LDAP", null) throws NoSuchAlgorithmException
with no cause. The entitlement check handler treated any NSAE as a
denial and returned HTTP 403, causing EntitlementsAllowedNonModularIT
to fail.

The fix catches NSAE in createLDAPCertStore() and re-throws only when
getCause() != null, which is the signature of a genuine entitlement
denial (the instrumentation creates the exception as
new NoSuchAlgorithmException(notEntitledException)). A no-cause NSAE
means the provider is simply absent and should be silently swallowed.

Adds unit tests that reproduce both paths by temporarily manipulating
JCA providers.

(cherry picked from commit 8234302)

# Conflicts:
#	muted-tests.yml
JVerwolf added a commit to JVerwolf/elasticsearch that referenced this pull request Mar 24, 2026
In FIPS environments the LDAP CertStore provider is absent, so
CertStore.getInstance("LDAP", null) throws NoSuchAlgorithmException
with no cause. The entitlement check handler treated any NSAE as a
denial and returned HTTP 403, causing EntitlementsAllowedNonModularIT
to fail.

The fix catches NSAE in createLDAPCertStore() and re-throws only when
getCause() != null, which is the signature of a genuine entitlement
denial (the instrumentation creates the exception as
new NoSuchAlgorithmException(notEntitledException)). A no-cause NSAE
means the provider is simply absent and should be silently swallowed.

Adds unit tests that reproduce both paths by temporarily manipulating
JCA providers.

(cherry picked from commit 8234302)

# Conflicts:
#	muted-tests.yml
JVerwolf added a commit to JVerwolf/elasticsearch that referenced this pull request Mar 24, 2026
In FIPS environments the LDAP CertStore provider is absent, so
CertStore.getInstance(LDAP, null) throws NoSuchAlgorithmException
with no cause. The entitlement check handler treated any NSAE as a
denial and returned HTTP 403, causing EntitlementsAllowedNonModularIT
to fail.

The fix catches NSAE in createLDAPCertStore() and re-throws only when
getCause() != null, which is the signature of a genuine entitlement
denial (the instrumentation creates the exception as
new NoSuchAlgorithmException(notEntitledException)). A no-cause NSAE
means the provider is simply absent and should be silently swallowed.

Adds unit tests that reproduce both paths by temporarily manipulating
JCA providers.

(cherry picked from commit 8234302)
JVerwolf added a commit to JVerwolf/elasticsearch that referenced this pull request Mar 24, 2026
In FIPS environments the LDAP CertStore provider is absent, so
CertStore.getInstance(LDAP, null) throws NoSuchAlgorithmException
with no cause. The entitlement check handler treated any NSAE as a
denial and returned HTTP 403, causing EntitlementsAllowedNonModularIT
to fail.

The fix catches NSAE in createLDAPCertStore() and re-throws only when
getCause() != null, which is the signature of a genuine entitlement
denial (the instrumentation creates the exception as
new NoSuchAlgorithmException(notEntitledException)). A no-cause NSAE
means the provider is simply absent and should be silently swallowed.

Adds unit tests that reproduce both paths by temporarily manipulating
JCA providers.

(cherry picked from commit 8234302)
JVerwolf added a commit to JVerwolf/elasticsearch that referenced this pull request Mar 24, 2026
In FIPS environments the LDAP CertStore provider is absent, so
CertStore.getInstance(LDAP, null) throws NoSuchAlgorithmException
with no cause. The entitlement check handler treated any NSAE as a
denial and returned HTTP 403, causing EntitlementsAllowedNonModularIT
to fail.

The fix catches NSAE in createLDAPCertStore() and re-throws only when
getCause() != null, which is the signature of a genuine entitlement
denial (the instrumentation creates the exception as
new NoSuchAlgorithmException(notEntitledException)). A no-cause NSAE
means the provider is simply absent and should be silently swallowed.

Adds unit tests that reproduce both paths by temporarily manipulating
JCA providers.

(cherry picked from commit 8234302)
JVerwolf added a commit that referenced this pull request Mar 24, 2026
In FIPS environments the LDAP CertStore provider is absent, so
CertStore.getInstance(LDAP, null) throws NoSuchAlgorithmException
with no cause. The entitlement check handler treated any NSAE as a
denial and returned HTTP 403, causing EntitlementsAllowedNonModularIT
to fail.

The fix catches NSAE in createLDAPCertStore() and re-throws only when
getCause() != null, which is the signature of a genuine entitlement
denial (the instrumentation creates the exception as
new NoSuchAlgorithmException(notEntitledException)). A no-cause NSAE
means the provider is simply absent and should be silently swallowed.

Adds unit tests that reproduce both paths by temporarily manipulating
JCA providers.

(cherry picked from commit 8234302)
JVerwolf added a commit that referenced this pull request Mar 24, 2026
In FIPS environments the LDAP CertStore provider is absent, so
CertStore.getInstance(LDAP, null) throws NoSuchAlgorithmException
with no cause. The entitlement check handler treated any NSAE as a
denial and returned HTTP 403, causing EntitlementsAllowedNonModularIT
to fail.

The fix catches NSAE in createLDAPCertStore() and re-throws only when
getCause() != null, which is the signature of a genuine entitlement
denial (the instrumentation creates the exception as
new NoSuchAlgorithmException(notEntitledException)). A no-cause NSAE
means the provider is simply absent and should be silently swallowed.

Adds unit tests that reproduce both paths by temporarily manipulating
JCA providers.

(cherry picked from commit 8234302)
JVerwolf added a commit that referenced this pull request Mar 24, 2026
In FIPS environments the LDAP CertStore provider is absent, so
CertStore.getInstance(LDAP, null) throws NoSuchAlgorithmException
with no cause. The entitlement check handler treated any NSAE as a
denial and returned HTTP 403, causing EntitlementsAllowedNonModularIT
to fail.

The fix catches NSAE in createLDAPCertStore() and re-throws only when
getCause() != null, which is the signature of a genuine entitlement
denial (the instrumentation creates the exception as
new NoSuchAlgorithmException(notEntitledException)). A no-cause NSAE
means the provider is simply absent and should be silently swallowed.

Adds unit tests that reproduce both paths by temporarily manipulating
JCA providers.

(cherry picked from commit 8234302)
eranweiss-elastic pushed a commit to eranweiss-elastic/elasticsearch that referenced this pull request Mar 25, 2026
In FIPS environments the LDAP CertStore provider is absent, so
CertStore.getInstance("LDAP", null) throws NoSuchAlgorithmException
with no cause. The entitlement check handler treated any NSAE as a
denial and returned HTTP 403, causing EntitlementsAllowedNonModularIT
to fail.

The fix catches NSAE in createLDAPCertStore() and re-throws only when
getCause() != null, which is the signature of a genuine entitlement
denial (the instrumentation creates the exception as
new NoSuchAlgorithmException(notEntitledException)). A no-cause NSAE
means the provider is simply absent and should be silently swallowed.

Adds unit tests that reproduce both paths by temporarily manipulating
JCA providers.
sidosera pushed a commit to sidosera/elasticsearch that referenced this pull request Mar 26, 2026
In FIPS environments the LDAP CertStore provider is absent, so
CertStore.getInstance("LDAP", null) throws NoSuchAlgorithmException
with no cause. The entitlement check handler treated any NSAE as a
denial and returned HTTP 403, causing EntitlementsAllowedNonModularIT
to fail.

The fix catches NSAE in createLDAPCertStore() and re-throws only when
getCause() != null, which is the signature of a genuine entitlement
denial (the instrumentation creates the exception as
new NoSuchAlgorithmException(notEntitledException)). A no-cause NSAE
means the provider is simply absent and should be silently swallowed.

Adds unit tests that reproduce both paths by temporarily manipulating
JCA providers.
seanzatzdev pushed a commit to seanzatzdev/elasticsearch that referenced this pull request Mar 27, 2026
In FIPS environments the LDAP CertStore provider is absent, so
CertStore.getInstance("LDAP", null) throws NoSuchAlgorithmException
with no cause. The entitlement check handler treated any NSAE as a
denial and returned HTTP 403, causing EntitlementsAllowedNonModularIT
to fail.

The fix catches NSAE in createLDAPCertStore() and re-throws only when
getCause() != null, which is the signature of a genuine entitlement
denial (the instrumentation creates the exception as
new NoSuchAlgorithmException(notEntitledException)). A no-cause NSAE
means the provider is simply absent and should be silently swallowed.

Adds unit tests that reproduce both paths by temporarily manipulating
JCA providers.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

auto-backport Automatically create backport pull requests when merged backport pending >bug :Core/Infra/Entitlements Entitlements infrastructure Team:Core/Infra Meta label for core/infra team test-fips Trigger CI checks for FIPS test-fips-140-3 v8.19.14 v9.2.8 v9.3.3 v9.4.0

6 participants