Skip to content

Add 'SslProfileExtension' SPI interface#134609

Merged
tvernum merged 6 commits intoelastic:mainfrom
tvernum:ssl/profile/pluggable
Sep 23, 2025
Merged

Add 'SslProfileExtension' SPI interface#134609
tvernum merged 6 commits intoelastic:mainfrom
tvernum:ssl/profile/pluggable

Conversation

@tvernum
Copy link
Contributor

@tvernum tvernum commented Sep 12, 2025

This new SPI extension point allows plugins to define new SSL profiles (contexts) that will be automatically loaded and managed by the SSLService

Each extension defines the settings prefix(s) that it uses (e.g. "foo.bar.ssl") and then the SSL Service reads those settings and constructs SslConfiguration and SslProfile objects from those settings. The SslProfile is provided back to the extension for its use

This new SPI extension point allows plugins to define new SSL profiles
(contexts) that will be automatically loaded and managed by the
SSLService

Each extension defines the settings prefix(s) that it uses
(e.g.  "foo.bar.ssl") and then the SSL Service reads those settings
and constructs `SslConfiguration` and `SslProfile` objects from those
settings. The `SslProfile` is provided back to the extension for its
use
@elasticsearchmachine elasticsearchmachine added the Team:Security Meta label for security team label Sep 12, 2025
@elasticsearchmachine
Copy link
Collaborator

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

@elasticsearchmachine
Copy link
Collaborator

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

/**
* Used for sharing internal configuration information between {@link SSLService} and {@link SSLConfigurationReloader}
*/
public static class LoadedConfiguration {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We have an unusual setup when we load SSL material.

  • First we call the SSL Service to load all the config (settings) but not read the files
  • Then we call the SSL Configuration Reloader to start watching the files
  • Then we go back the SSL Service and read the files load the SslProfile objects.

We need to do it in this order so that we are watching the files before we read them. Otherwise we risk missing an update (if they change between the time we read them and start watching them).

That means we need to carry certain information from step 1 into step 3.
That information has now been refactored into this LoadedConfiguration class. I needed to do that because I need to track which profile/context names belong to which extensions, and I need to carry that information from step 1 to step 3, and the existing Map was no long good enough.

description = 'A test plugin to test the SPI behaviour of SslProfileExtension'
classname = 'org.elasticsearch.test.xpack.core.ssl.extension.SslExtensionTestPlugin'
extendedPlugins = [ "x-pack-core" ]
}
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 QA project creates a test extension, and verifies that it gets loaded correctly and appears in the /_ssl/certificates API.

List<Setting<?>> settings = super.getSettings();
settings.add(SourceOnlySnapshotRepository.SOURCE_ONLY);

settings.addAll(SSLService.getExtensionSettings(this.sslExtensions));
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Here we automatically register the SSL settings for any extensions.

.stream()
.peek(e -> logger.info("SSL extension [{}] defines context [{}]", e.getValue().getClass(), e.getKey()))
.map(Map.Entry::getKey)
.map(prefix -> SSLConfigurationSettings.withPrefix(prefix + ".", false))
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 false here means that we don't support legacy non-secure settings for passwords.

That is, if a keystore/key has a password, then the password need to be in the elasticsearch.keystore, it can't be plaintext in elasticsearch.yml

/**
* Used for sharing internal configuration information between {@link SSLService} and {@link SSLConfigurationReloader}
*/
public static class LoadedConfiguration {
Copy link
Contributor

@slobodanadamovic slobodanadamovic Sep 16, 2025

Choose a reason for hiding this comment

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

suggestion:

Suggested change
public static class LoadedConfiguration {
public static class LoadedSslConfiguration {
Copy link
Contributor

@slobodanadamovic slobodanadamovic left a comment

Choose a reason for hiding this comment

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

LGTM 🚀

@tvernum tvernum merged commit 4d79a59 into elastic:main Sep 23, 2025
40 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

>enhancement :Security/TLS SSL/TLS, Certificates Team:Security Meta label for security team v9.2.0

3 participants