Skip to content

Include Secure Setting Names and Keystore Modified Time in Reload API Response#138052

Merged
ebarlas merged 10 commits intoelastic:mainfrom
ebarlas:keystore-details-in-reload-response
Nov 20, 2025
Merged

Include Secure Setting Names and Keystore Modified Time in Reload API Response#138052
ebarlas merged 10 commits intoelastic:mainfrom
ebarlas:keystore-details-in-reload-response

Conversation

@ebarlas
Copy link
Contributor

@ebarlas ebarlas commented Nov 13, 2025

This change augments the reload_secure_settings API response with the following properties for each node object:

  • secure_setting_names: JSON array of secure setting names from ES keystore
  • keystore_path: JSON string with file system path to keystore file
  • keystore_digest: JSON string with hex-encoded SHA-256 hash of keystore file raw bytes
  • keystore_last_modified_time: JSON string with ES keystore last-modified date-time

This change is a response to recurring ES admin confusion about which securing settings are being reloaded from which keystore. See issue #112268.


Curl call to reload_secure_settings targeting local ES distribution:

Screenshot 2025-11-18 at 2 43 44 PM
@ebarlas ebarlas requested a review from a team November 13, 2025 19:28
@ebarlas ebarlas self-assigned this Nov 13, 2025
@ebarlas ebarlas added >enhancement :Security/Security Security issues without another label Team:Security Meta label for security team labels Nov 13, 2025
@elasticsearchmachine
Copy link
Collaborator

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

@ebarlas ebarlas marked this pull request as ready for review November 13, 2025 19:30
@ebarlas ebarlas requested a review from a team as a code owner November 13, 2025 19:30
@elasticsearchmachine
Copy link
Collaborator

Pinging @elastic/es-security (Team:Security)

Copy link
Contributor

@jfreden jfreden left a comment

Choose a reason for hiding this comment

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

The PR looks great and the code is solid as always! I have a couple of comments.

At a higher level, it was discussed in the issue if the absolute path to the keystore should be included or not. My understanding from the discussion is that you landed on including it but it's not part of the change?

return ElasticsearchException.readException(this);
}

/**
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice addition!

try {
return Files.readAttributes(path, BasicFileAttributes.class).lastModifiedTime().toMillis();
} catch (IOException e) {
return null; // fallback to null if we can't read the time
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we should log a warning here since it's unexpected. We just refreshed the keystore and now we can't get the modified timestamp.

summary: Include Secure Setting Names and Keystore Modified Time in Reload API Response
area: Security
type: enhancement
issues: []
Copy link
Contributor

Choose a reason for hiding this comment

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

This could reference #112268

@@ -412,6 +413,8 @@ public void onResponse(NodesReloadSecureSettingsResponse nodesReloadResponse) {
assertThat(nodesMap.size(), equalTo(cluster().size()));
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think it matters but this test is disabled when running in fips mode. Since we're reading properties on the keystore we might want to make sure it works in fips mode too?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The current approach seems adequate. I see that ReloadSecureSettingsWithPasswordProtectedKeystoreRestIT has a group of tests with a keystore password.

public static class NodeResponse extends BaseNodeResponse {

private Exception reloadException = null;
private static final TransportVersion KEYSTORE_DETAILS = TransportVersion.fromName("keystore_details_in_reload_response");
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: might want to use more specific naming since we might want to add more details in the future.

import java.util.List;
import java.util.Optional;

public class NodesReloadSecureSettingsResponseTests extends ESTestCase {
Copy link
Contributor

Choose a reason for hiding this comment

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

There is actually an abstract class that does testing like this AbstractBWCSerializationTestCase that's used throughout the code base. You might want to consider extending that for more test coverage.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This turned out to be a poor match since AbstractBWCSerializationTestCase expects both wire serialization and XContent serialization. The NodesReloadSecureSettingsResponse source code is not currently arranged that way.

@ankit--sethi
Copy link
Contributor

I think someone jumped ahead of you in terms of transport version, but otherwise LGTM to me!

ebarlas and others added 2 commits November 20, 2025 11:00
…de/reload/NodesReloadSecureSettingsResponse.java

Co-authored-by: Slobodan Adamović <slobodanadamovic@users.noreply.github.com>
…de/reload/NodesReloadSecureSettingsResponse.java

Co-authored-by: Slobodan Adamović <slobodanadamovic@users.noreply.github.com>
@ebarlas ebarlas merged commit b283d24 into elastic:main Nov 20, 2025
40 checks passed
assertNotNull(readNr.reloadException());
assertEquals(nr.reloadException().getMessage(), readNr.reloadException().getMessage());
}
if (version.equals(TransportVersion.current())) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This would cause a failure as soon as somebody introduce a new transport version.
Should this be version.supports(NodesReloadSecureSettingsResponse.NodeResponse.KEYSTORE_DETAILS) instead?

Copy link
Contributor

Choose a reason for hiding this comment

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

ncordon pushed a commit to ncordon/elasticsearch that referenced this pull request Nov 26, 2025
Include keystore details in reload-secure-settings API response:

- Secure setting names
- Keystore file path
- Keystore SHA-256 checksum
- Keystore last modified time
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

>enhancement :Security/Security Security issues without another label Team:Security Meta label for security team v9.3.0

6 participants