Browse Source

JWT realm documentation update - take 2 (#92539)

This PR is another round of documentation update for the JWT realm with the goal to achieve better clarity, differentiating more between the two token types and encourage readers to choose between them carefully.

Relates: #92409
Yang Wang 2 years ago
parent
commit
9ce06fddc4

+ 12 - 2
docs/reference/settings/security-settings.asciidoc

@@ -2035,9 +2035,12 @@ incoming JWTs. Defaults to `id_token`.
 (<<static-cluster-setting,Static>>)
 A list of allowed JWT audiences that {es} should verify. {es} will only consume
 JWTs that were intended for any of these audiences, as denoted by the `aud`
-claim in the JWT). Examples of `aud` claim are `https://example.com/client1`
+claim in the JWT).
+The audiences are compared with exact string matches and do not support wildcards or regex.
+Examples of `aud` claim are `https://example.com/client1`
 and `other_service,elasticsearch`. When `token_type` is `access_token`, the audiences can
 be optionally denoted by a different claim in the JWT if `aud` does not exist.
+See also <<security-settings-jwt-fallback-claims-aud,`fallback_claims.aud`>>.
 // end::jwt-allowed-audiences-tag[]
 
 // tag::jwt-allowed-clock-skew-tag[]
@@ -2055,6 +2058,7 @@ Identifier is usually a case sensitive URL using the https scheme that contains
 scheme, host, and optionally, port number and path components and no query or
 fragment components. However, it can be any string. The value for this setting
 should be provided by your JWT Issuer.
+The issuer is compared with exact string matches and do not support wildcards or regex.
 Examples of `iss` claim are `https://example.com:8443/jwt` and `issuer123`.
 // end::jwt-allowed-issuer-tag[]
 
@@ -2063,13 +2067,17 @@ Examples of `iss` claim are `https://example.com:8443/jwt` and `issuer123`.
 (<<static-cluster-setting,Static>>)
 A list of allowed JWT subjects that {es} should verify. {es} will only consume
 JWTs that were issued for any of these subjects, as denoted by the `sub`
-claim in the JWT. Examples of `sub` claim are `https://example.com/user1`
+claim in the JWT.
+The subjects are compared with exact string matches and do not support wildcards or regex.
+Examples of `sub` claim are `https://example.com/user1`
 and `user_1,user2`.
 When `token_type` is `access_token`, this setting is mandatory and the subject can be
 optionally denoted by a different claim in the JWT if `sub` does not exist.
+See also <<security-settings-jwt-fallback-claims-sub,`fallback_claims.sub`>>.
 // end::jwt-allowed-subjects-tag[]
 
 // tag::jwt-fallback-claims-sub-tag[]
+[[security-settings-jwt-fallback-claims-sub]]
 `fallback_claims.sub` {ess-icon}::
 (<<static-cluster-setting,Static>>)
 The alternative claim to look for the subject information if the `sub` claim
@@ -2078,6 +2086,7 @@ The fallback is applied everywhere the `sub` claim is used.
 // end::jwt-fallback-claims-sub-tag[]
 
 // tag::jwt-fallback-claims-aud-tag[]
+[[security-settings-jwt-fallback-claims-aud]]
 `fallback_claims.aud` {ess-icon}::
 (<<static-cluster-setting,Static>>)
 The alternative claim to look for the audiences information if the `aud` claim
@@ -2091,6 +2100,7 @@ The fallback is applied everywhere the `aud` claim is used.
 Additional claims and associated values that {es} should verify.
 This is a group setting that takes key/value pairs, where the key is a string
 and the value must be either a string or an array of strings.
+The values are compared with exact string matches and do not support wildcards or regex.
 
 For example:
 

+ 51 - 33
x-pack/docs/en/security/authentication/jwt-realm.asciidoc

@@ -12,22 +12,24 @@ between the _client_ that is connecting to {es}, and the _user_ on whose behalf
 the request should run. The JWT authenticates the user, and a separate credential
 authenticates the client.
 
-The JWT realm is designed to cater for the following two scenarios:
-
-1. An application authenticates and identifies a user with an authentication flow, e.g.
-OpenID Connect (OIDC), and then accesses {es} on behalf of the authenticated user.
-A common scenario for JWTs is when an existing application uses
-2. An application itself goes through an authentication flow, e.g. OAuth2 Client Credentials
-Flow, and then accesses {es} for itself.
-
-In both scenarios, the application should present a JWT to {es} that represents either the user (scenario 1)
-or itself (scenario 2). {es} categorizes the JWT into two types, ID Token and Access token,
-and validates them accordingly. The ID Token type basically follows the OIDC specification.
-The access token type is similar to the ID Token type, but with more relaxed rules which makes it
-suitable for loosely-defined JWTs, including self-signed ones.
-Tokens of both types must contain the following 5 pieces of information. While ID Tokens follow
-strict rules on which claim should provide each piece of the information,
-access tokens allow certain configurable options.
+The JWT realm supports two token types, `id_token` (the default) and `access_token`.
+They are designed to work for the following two scenarios, respectively:
+
+1. `id_token` - An application authenticates and identifies a user with an authentication flow,
+e.g. OpenID Connect (OIDC), and then accesses {es} on behalf of the authenticated user using
+a JSON Web Token (JWT) conforming to OIDC ID Token specification.
+2. `access_token` - An application accesses {es} using its own identity, encoded as a JWT,
+e.g. The application authenticates itself to a central identity platform using an
+OAuth2 Client Credentials Flow and then uses the resulting JWT-based access token to connect to {es}.
+
+NOTE: A single JWT realm can only work with a single token type. To handle both token types,
+you must configure at least two JWT realms. You should choose the token type carefully based
+on the use case because it impacts on how validations are performed.
+
+The JWT realm validates the incoming JWT based on its configured token type.
+JSON Web Tokens (JWT) of both types must contain the following 5 pieces of information.
+While ID Tokens, based on the OIDC specification, have strict rules for what claims should provide these information,
+access tokens allow some claims to be configurable.
 
 [cols="3",frame=all]
 |====
@@ -43,18 +45,17 @@ h| Information     | ID Token   | Access Token
 In addition, {es} also validates `nbf` and `auth_time` claims for ID Tokens if these claims are present.
 But these claims are ignored for access tokens.
 
-A single JWT realm can only work with a single token type. The default token
-type is `id_token`. To handle both token types, you must configure at least
-two JWT realms.
+Overall, the access token type has more relaxed validation rules and is suitable for more generic JWTs,
+including self-signed ones.
 
 [[jwt-realm-oidc]]
-==== JWT from OIDC workflows
+==== ID Tokens from OIDC workflows
 JWT authentication in {es} is derived from OIDC user workflows, where different
-tokens can be issued by an OIDC Provider (OP), including ID Tokens and access
-tokens. ID Tokens are well-defined JWT and should be always compatible with
-what JWT realm supports. Access tokens can be arbitrary in theory. For them to
-be usable with JWT realm, they must at least use the JWT format and satisfy
-relevant requirements in the above table.
+tokens can be issued by an OIDC Provider (OP), including ID Tokens.
+ID Tokens from an OIDC provider are well-defined JSON Web Tokens (JWT) and should be always compatible with
+a JWT realm of the `id_token` token type. The subject claim of an ID token represents the end-user.
+This means that ID tokens will generally have many allowed subjects.
+Therefore, a JWT realm of `id_token` token type does _not_ mandate the `allowed_subjects` validation.
 
 NOTE: Because JWTs are obtained external to {es}, you can define a custom workflow
 instead of using the OIDC workflow. However, the JWT format must still be JSON
@@ -65,8 +66,23 @@ ID token validation rules.
 use case where {es} can act as an OIDC RP. The OIDC realm is the only supported
 way to enable OIDC authentication in {kib}.
 
-TIP: The JWT realm is compatible with the <<run-as-privilege,`run_as`>> feature.
-See also <<jwt-realm-runas>>.
+TIP: Users authenticating with a JWT realm can optionally impersonate another user
+with the <<run-as-privilege,`run_as`>> feature. See also <<jwt-realm-runas>>.
+
+[[jwt-realm-oauth2]]
+==== Access Tokens
+A common method to obtain access tokens is with the OAuth2 Client Credentials Flow.
+A typical usage of this flow is for an application to get a credential for itself.
+This is the use case that the `access_token` token type is designed for.
+It is likely that this application also obtains ID Tokens for its end-users.
+To prevent end-user ID Tokens being used to authenticate with the JWT realm configured
+for the application, we mandate `allowed_subjects` validation when a JWT realm
+has token type `access_token`.
+
+NOTE: Not every access token is formatted as a JSON Web Token (JWT).
+For it to be compatible with the JWT realm, it must at least use the JWT format and satisfies
+relevant requirements in the above table.
+
 
 [[jwt-realm-configuration]]
 ==== Configure {es} to use a JWT realm
@@ -284,18 +300,20 @@ creation (`iat`), not before (`nbf`), and expiration times (`exp`).
 be an exact, case-sensitive match to the value in the `allowed_issuer` setting.
 
 `sub`::
-(Required, String) Indicates the subject that the ID token is created for.
+(Required*, String) Indicates the subject that the ID token is created for.
+If the JWT realm is of the `id_token` type, this claim is mandatory.
 A JWT realm of the `id_token` type by defaults accepts all subjects.
-A JWT realm of the `access_token` type can specify a fallback claim that will
-be used in place where the `sub` claim does not exist. Such JWT realm
-must also specify the `allowed_subjects` setting and the subject value
+A JWT realm of the access_token type must specify the `allowed_subjects` setting and the subject value
 must be an exact, case-sensitive match to any of the CSV values in the
-`allowed_subjects` setting.
+allowed_subjects setting.
+A JWT realm of the access_token type can specify a fallback claim that will
+be used in place where the `sub` claim does not exist.
 
 `aud`::
-(Required, String) Indicates the audiences that the ID token is for, expressed as a
+(Required*, String) Indicates the audiences that the ID token is for, expressed as a
 comma-separated value (CSV). One of the values must be an exact, case-sensitive
 match to any of the CSV values in the `allowed_audiences` setting.
+If the JWT realm is of the `id_token` type, this claim is mandatory.
 A JWT realm of the `access_token` type can specify a fallback claim that will
 be used in place where the `aud` claim does not exist.