Skip to content

Commit 2c64f47

Browse files
authored
Add PKC JWK set reloading to JWT realm. (#136996)
Add automatic reloading of PKC (Public Key Cryptography) JWK (JSON Web Key) sets from both file and URL sources, with configurable intervals. File-based JWK sets are reloaded at a fixed interval, with a default of 5 minutes. URL-based JWK sets are reloaded at adaptive intervals informed by Expires and Cache-Control header responses from the JWKS provider. The interval is bounded by a range, with defaults of 5 minutes to 5 days.
1 parent 6c0fd35 commit 2c64f47

File tree

18 files changed

+903
-111
lines changed

18 files changed

+903
-111
lines changed

docs/changelog/136996.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 136996
2+
summary: Add periodic PKC JWK set reloading capability to JWT realm
3+
area: Security
4+
type: enhancement
5+
issues: []

docs/reference/elasticsearch/configuration-reference/security-settings.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1523,7 +1523,19 @@ $$$jwt-claim-pattern-principal$$$
15231523
: ([Static](docs-content://deploy-manage/stack-settings.md#static-cluster-setting)) Specifies the time-to-live for the period of time to cache JWT entries. JWTs can only be cached if client authentication is successful (or disabled). Uses the standard {{es}} [time units](/reference/elasticsearch/rest-apis/api-conventions.md#time-units). If clients use a different JWT for every request, set to `0` to disable the JWT cache. Defaults to `20m`.
15241524

15251525
`pkc_jwkset_path` ![logo cloud](https://doc-icons.s3.us-east-2.amazonaws.com/logo_cloud.svg "Supported on Elastic Cloud Hosted")
1526-
: ([Static](docs-content://deploy-manage/stack-settings.md#static-cluster-setting)) The file name or URL to a JSON Web Key Set (JWKS) with the public key material that the JWT Realm uses for verifying token signatures. A value is considered a file name if it does not begin with `https`. The file name is resolved relative to the {{es}} configuration directory. If a URL is provided, then it must begin with `https://` (`http://` is not supported). {{es}} automatically caches the JWK set and will attempt to refresh the JWK set upon signature verification failure, as this might indicate that the JWT Provider has rotated the signing keys.
1526+
: ([Static](docs-content://deploy-manage/stack-settings.md#static-cluster-setting)) The file name or URL to a JSON Web Key Set (JWKS) with the public key material that the JWT Realm uses for verifying token signatures. A value is considered a file name if it does not begin with `https`. The file name is resolved relative to the {{es}} configuration directory. If a URL is provided, then it must begin with `https://` (`http://` is not supported). {{es}} automatically caches the JWK set and will attempt to refresh the JWK set upon signature verification failure, as this might indicate that the JWT Provider has rotated the signing keys. Background JWKS reloading can also be configured with the setting `pkc_jwkset_reload.enabled`. This ensures that rotated keys are automatically discovered and used to verify JWT signatures.
1527+
1528+
`pkc_jwkset_reload.enabled` {applies_to}`stack: ga 9.3` ![logo cloud](https://doc-icons.s3.us-east-2.amazonaws.com/logo_cloud.svg "Supported on Elastic Cloud Hosted")
1529+
: ([Static](docs-content://deploy-manage/stack-settings.md#static-cluster-setting)) Indicates whether JWKS background reloading is enabled. Defaults to `false`.
1530+
1531+
`pkc_jwkset_reload.file_interval` {applies_to}`stack: ga 9.3` ![logo cloud](https://doc-icons.s3.us-east-2.amazonaws.com/logo_cloud.svg "Supported on Elastic Cloud Hosted")
1532+
: ([Static](docs-content://deploy-manage/stack-settings.md#static-cluster-setting)) Specifies the reload interval for file-based JWKS. Defaults to `5m`.
1533+
1534+
`pkc_jwkset_reload.url_interval_min` {applies_to}`stack: ga 9.3` ![logo cloud](https://doc-icons.s3.us-east-2.amazonaws.com/logo_cloud.svg "Supported on Elastic Cloud Hosted")
1535+
: ([Static](docs-content://deploy-manage/stack-settings.md#static-cluster-setting)) Specifies the minimum reload interval for URL-based JWKS. The `Expires` and `Cache-Control` HTTP response headers inform the reload interval. This configuration setting is the lower bound of what is considered, and it is also the default interval in the absence of useful response headers. Defaults to `1h`.
1536+
1537+
`pkc_jwkset_reload.url_interval_max` {applies_to}`stack: ga 9.3` ![logo cloud](https://doc-icons.s3.us-east-2.amazonaws.com/logo_cloud.svg "Supported on Elastic Cloud Hosted")
1538+
: ([Static](docs-content://deploy-manage/stack-settings.md#static-cluster-setting)) Specifies the maximum reload interval for URL-based JWKS. This configuration setting is the upper bound of what is considered from header responses (`5d`).
15271539

15281540
`hmac_jwkset` ![logo cloud](https://doc-icons.s3.us-east-2.amazonaws.com/logo_cloud.svg "Supported on Elastic Cloud Hosted")
15291541
: ([Secure](docs-content://deploy-manage/security/secure-settings.md)) Contents of a JSON Web Key Set (JWKS), including the secret key that the JWT realm uses to verify token signatures. This format supports multiple keys and optional attributes, and is preferred over the `hmac_key` setting. Cannot be used in conjunction with the `hmac_key` setting. Refer to [Configure {{es}} to use a JWT realm](docs-content://deploy-manage/users-roles/cluster-or-deployment-auth/jwt.md).

x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/jwt/JwtRealmSettings.java

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,18 @@ private static Set<Setting.AffixSetting<?>> getNonSecureSettings() {
158158
final Set<Setting.AffixSetting<?>> set = new HashSet<>(RealmSettings.getStandardSettings(TYPE));
159159
set.add(TOKEN_TYPE);
160160
// JWT Issuer settings
161-
set.addAll(List.of(ALLOWED_ISSUER, ALLOWED_SIGNATURE_ALGORITHMS, ALLOWED_CLOCK_SKEW, PKC_JWKSET_PATH));
161+
set.addAll(
162+
List.of(
163+
ALLOWED_ISSUER,
164+
ALLOWED_SIGNATURE_ALGORITHMS,
165+
ALLOWED_CLOCK_SKEW,
166+
PKC_JWKSET_PATH,
167+
PKC_JWKSET_RELOAD_ENABLED,
168+
PKC_JWKSET_RELOAD_FILE_INTERVAL,
169+
PKC_JWKSET_RELOAD_URL_INTERVAL_MIN,
170+
PKC_JWKSET_RELOAD_URL_INTERVAL_MAX
171+
)
172+
);
162173
// JWT Audience settings
163174
set.addAll(List.of(ALLOWED_AUDIENCES));
164175
// JWT End-user settings
@@ -249,6 +260,30 @@ private static Set<Setting.AffixSetting<SecureString>> getSecureSettings() {
249260
Setting.Property.NodeScope
250261
);
251262

263+
public static final Setting.AffixSetting<Boolean> PKC_JWKSET_RELOAD_ENABLED = Setting.affixKeySetting(
264+
RealmSettings.realmSettingPrefix(TYPE),
265+
"pkc_jwkset_reload.enabled",
266+
key -> Setting.boolSetting(key, false, Setting.Property.NodeScope)
267+
);
268+
269+
public static final Setting.AffixSetting<TimeValue> PKC_JWKSET_RELOAD_FILE_INTERVAL = Setting.affixKeySetting(
270+
RealmSettings.realmSettingPrefix(TYPE),
271+
"pkc_jwkset_reload.file_interval",
272+
key -> Setting.timeSetting(key, TimeValue.timeValueMinutes(5), TimeValue.timeValueMinutes(5), Setting.Property.NodeScope)
273+
);
274+
275+
public static final Setting.AffixSetting<TimeValue> PKC_JWKSET_RELOAD_URL_INTERVAL_MIN = Setting.affixKeySetting(
276+
RealmSettings.realmSettingPrefix(TYPE),
277+
"pkc_jwkset_reload.url_interval_min",
278+
key -> Setting.timeSetting(key, TimeValue.timeValueHours(1), TimeValue.timeValueMinutes(5), Setting.Property.NodeScope)
279+
);
280+
281+
public static final Setting.AffixSetting<TimeValue> PKC_JWKSET_RELOAD_URL_INTERVAL_MAX = Setting.affixKeySetting(
282+
RealmSettings.realmSettingPrefix(TYPE),
283+
"pkc_jwkset_reload.url_interval_max",
284+
key -> Setting.timeSetting(key, TimeValue.timeValueDays(5), TimeValue.timeValueMinutes(5), Setting.Property.NodeScope)
285+
);
286+
252287
public static final Setting.AffixSetting<SecureString> HMAC_JWKSET = RealmSettings.secureString(TYPE, "hmac_jwkset");
253288
public static final Setting.AffixSetting<SecureString> HMAC_KEY = RealmSettings.secureString(TYPE, "hmac_key");
254289

x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/InternalRealms.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ public static Map<String, Realm.Factory> getFactories(
171171
config -> new OpenIdConnectRealm(config, sslService, userRoleMapper, resourceWatcherService),
172172
// JWT realm
173173
JwtRealmSettings.TYPE,
174-
config -> new JwtRealm(config, sslService, userRoleMapper)
174+
config -> new JwtRealm(config, sslService, userRoleMapper, threadPool)
175175
);
176176
}
177177

0 commit comments

Comments
 (0)