123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729 |
- [role="xpack"]
- [[jwt-auth-realm]]
- === JWT authentication
- {es} can be configured to trust JSON Web Tokens (JWTs) issued from an external service
- as bearer tokens for authentication.
- When a JWT realm is used to authenticate with {es}, a distinction is made
- 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 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]
- |====
- h| 2+^h| Claims
- h| Information | ID Token | Access Token
- | Issuer | `iss` | `iss`
- | Subject | `sub` | Defaults to `sub`, but can fall back to another claim if `sub` does not exist
- | Audiences | `aud` | Defaults to `aud`, but can fall back to another claim if `aud` does not exist
- | Issue Time | `iat` | `iat`
- | Expiration Time | `exp` | `exp`
- |====
- 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.
- Overall, the access token type has more relaxed validation rules and is suitable for more generic JWTs,
- including self-signed ones.
- [[jwt-realm-oidc]]
- ==== 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.
- 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`
- (or `allowed_subject_patterns`) 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
- Web Signature (JWS). The JWS header and JWS signature are validated using OIDC
- ID token validation rules.
- {es} supports a separate <<oidc-realm,OpenID Connect realm>>. It is preferred for any
- 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: 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` or `allowed_subject_patterns`
- 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
- To use JWT authentication, create the realm in the `elasticsearch.yml` file
- to configure it within the {es} authentication chain.
- The JWT realm has a few mandatory settings, plus optional settings that are
- described in <<ref-jwt-settings,JWT realm settings>>.
- NOTE: Client authentication is enabled by default for the JWT realms. Disabling
- client authentication is possible, but strongly discouraged.
- . Add your JWT realm to the `elasticsearch.yml` file. The following example
- includes the most common settings, which are not intended for every use case:
- +
- --
- [source,yaml]
- ----
- xpack.security.authc.realms.jwt.jwt1:
- order: 3
- token_type: id_token
- client_authentication.type: shared_secret
- allowed_issuer: "https://issuer.example.com/jwt/"
- allowed_audiences: [ "8fb85eba-979c-496c-8ae2-a57fde3f12d0" ]
- allowed_signature_algorithms: [RS256,HS256]
- pkc_jwkset_path: jwt/jwkset.json
- claims.principal: sub
- ----
- `order`::
- Specifies a realm `order` of `3`, which indicates the order in which the
- configured realm is checked when authenticating a user. Realms are consulted in
- ascending order, where the realm with the lowest order value is consulted first.
- `token_type`::
- Instructs the realm to treat and validate incoming JWTs as ID Tokens (`id_token`).
- `client_authentication.type`::
- Specifies the client authentication type as `shared_secret`, which means that
- the client is authenticated using an HTTP request header that must match a
- pre-configured secret value. The client must provide this shared secret with
- every request in the `ES-Client-Authentication` header and using the
- `SharedSecret` scheme. The header value must be a case-sensitive match
- to the realm's `client_authentication.shared_secret`.
- `allowed_issuer`::
- Sets a verifiable identifier for your JWT issuer. This value is typically a
- URL, UUID, or some other case-sensitive string value.
- `allowed_audiences`::
- Specifies a list of JWT audiences that the realm will allow.
- These values are typically URLs, UUIDs, or other case-sensitive string values.
- `allowed_signature_algorithms`::
- Indicates that {es} should use the `RS256` or `HS256` signature algorithms to
- verify the signature of the JWT from the JWT issuer.
- `pkc_jwkset_path`::
- 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.
- `claims.principal`::
- The name of the JWT claim that contains the user's principal (username).
- The following is an example snippet for configure a JWT realm for handling
- access tokens:
- [source,yaml]
- ----
- xpack.security.authc.realms.jwt.jwt2:
- order: 4
- token_type: access_token
- client_authentication.type: shared_secret
- allowed_issuer: "https://issuer.example.com/jwt/"
- allowed_subjects: [ "123456-compute@admin.example.com" ]
- allowed_subject_patterns: [ "wild*@developer?.example.com", "/[a-z]+<1-10>\\@dev\\.example\\.com/"]
- allowed_audiences: [ "elasticsearch" ]
- required_claims:
- token_use: access
- version: ["1.0", "2.0"]
- allowed_signature_algorithms: [RS256,HS256]
- pkc_jwkset_path: "https://idp-42.example.com/.well-known/configuration"
- fallback_claims.sub: client_id
- fallback_claims.aud: scope
- claims.principal: sub
- ----
- `token_type`::
- Instructs the realm to treat and validate incoming JWTs as access tokens (`access_token`).
- `allowed_subjects`::
- Specifies a list of JWT subjects that the realm will allow.
- These values are typically URLs, UUIDs, or other case-sensitive string values.
- `allowed_subject_patterns`::
- Analogous to `allowed_subjects` but it accepts a list of <<regexp-syntax,Lucene regexp>>
- and wildcards for the allowed JWT subjects. Wildcards use the `*` and `?` special
- characters (which are escaped by `\`) to mean "any string" and "any single character"
- respectively, for example "a?\\**", matches "a1*" and "ab*whatever", but not "a", "abc", or "abc*"
- (in Java strings `\` must itself be escaped by another `\`).
- <<regexp-syntax,Lucene regexp>> must be enclosed between `/`,
- for example "/https?://[^/]+/?/" matches any http or https URL with no path component
- (matches "https://elastic.co/" but not "https://elastic.co/guide").
- NOTE: At least one of the `allowed_subjects` or `allowed_subject_patterns` settings must be specified
- (and be non-empty) when `token_type` is `access_token`.
- NOTE: When both `allowed_subjects` and `allowed_subject_patterns` settings are specified
- an incoming JWT's `sub` claim is accepted if it matches any of the two lists.
- `required_claims`::
- Specifies a list of key/value pairs for additional verifications to be performed
- against a JWT. The values are either a string or an array of strings.
- `fallback_claims.sub`::
- The name of the JWT claim to extract the subject information if the `sub` claim does not exist.
- This setting is only available when `token_type` is `access_token`.
- The fallback is applied everywhere the `sub` claim is used.
- In the above snippet, it means the `claims.principal` will also fallback to `client_id`
- if `sub` does not exist.
- `fallback_claims.aud`::
- The name of the JWT claim to extract the audiences information if the `aud` claim does not exist.
- This setting is only available when `token_type` is `access_token`.
- The fallback is applied everywhere the `aud` claim is used.
- --
- . After defining settings, use the
- {ref}/elasticsearch-keystore.html[`elasticsearch-keystore`] tool to store
- values for secure settings in the {es} keystore.
- .. Store the `shared_secret` value for `client_authentication.type`:
- +
- [source,shell]
- ----
- bin/elasticsearch-keystore add xpack.security.authc.realms.jwt.jwt1.client_authentication.shared_secret
- ----
- .. Store the HMAC keys for `allowed_signature_algorithms`, which use the HMAC
- SHA-256 algorithm `HS256` in the example:
- +
- [source,shell]
- ----
- bin/elasticsearch-keystore add-file xpack.security.authc.realms.jwt.jwt1.hmac_jwkset <path> <1>
- ----
- <1> Path to a JWKS, which is a resource for a set of JSON-encoded secret keys.
- The file can be removed after you load the contents into the {es} keystore.
- +
- [NOTE]
- ====
- Using the JWKS is preferred. However, you can add an HMAC key in string format
- using the following command. This format is compatible with HMAC UTF-8 keys, but
- only supports a single key with no attributes. You can only use one HMAC format
- (either `hmac_jwkset` or `hmac_key`) simultaneously.
- [source,shell]
- ----
- bin/elasticsearch-keystore add xpack.security.authc.realms.jwt.jwt1.hmac_key
- ----
- ====
- [[jwt-validation]]
- ==== JWT encoding and validation
- JWTs can be parsed into three pieces:
- Header::
- Provides information about how to validate the token.
- Claims::
- Contains data about the calling user or application.
- Signature::
- The data that's used to validate the token.
- [source,js]
- ----
- Header: {"typ":"JWT","alg":"HS256"}
- Claims: {"aud":"aud8","sub":"security_test_user","iss":"iss8","exp":4070908800,"iat":946684800}
- Signature: UnnFmsoFKfNmKMsVoDQmKI_3-j95PCaKdgqqau3jPMY
- ----
- // NOTCONSOLE
- This example illustrates a partial decoding of a JWT. The validity period is
- from 2000 to 2099 (inclusive), as defined by the issue time (`iat`) and
- expiration time (`exp`). JWTs typically have a validity period shorter than
- 100 years, such as 1-2 hours or 1-7 days, not an entire human life.
- The signature in this example is deterministic because the header, claims, and
- HMAC key are fixed. JWTs typically have a `nonce` claim to make the signature
- non-deterministic. The supported JWT encoding is JSON Web Signature (JWS), and
- the JWS `Header` and `Signature` are validated using OpenID Connect ID Token
- validation rules. Some validation is customizable through
- <<ref-jwt-settings,JWT realm settings>>.
- [[jwt-validation-header]]
- ===== Header claims
- The header claims indicate the token type and the algorithm used to sign the
- token.
- `alg`::
- (Required, String) Indicates the algorithm that was used to sign the token, such
- as `HS256`. The algorithm must be in the realm's allow list.
- `typ`::
- (Optional, String) Indicates the token type.
- +
- For an ID token, this must be
- +
- - `JWT`
- +
- For access tokens, this must be one of
- +
- - `JWT`
- - `at+jwt`
- [[jwt-validation-payload]]
- ===== Payload claims
- Tokens contain several claims, which provide information about the user
- who is issuing the token, and the token itself.
- Depending on the token type, these information can optionally be identified
- by different claims.
- ====== JWT payload claims
- The following claims are validated by a subset of OIDC ID token rules.
- {es} doesn't validate `nonce` claims, but a custom JWT issuer can add a
- random `nonce` claim to introduce entropy into the signature.
- NOTE: You can relax validation of any of the time-based claims by setting
- `allowed_clock_skew`. This value sets the maximum allowed clock skew before
- validating JWTs with respect to their authentication time (`auth_time`),
- creation (`iat`), not before (`nbf`), and expiration times (`exp`).
- `iss`::
- (Required, String) Denotes the issuer that created the ID token. The value must
- 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.
- 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 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.
- 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
- 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.
- `exp`::
- (Required, integer) Expiration time for the ID token, expressed in UTC
- seconds since epoch.
- `iat`::
- (Required, integer) Time that the ID token was issued, expressed in UTC
- seconds since epoch.
- `nbf`::
- (Optional, integer) Indicates the time before which the JWT must not be accepted,
- expressed as UTC seconds since epoch.
- This claim is optional. If it exists, a JWT realm of `id_token` type will verify
- it, while a JWT realm of `access_token` will just ignore it.
- `auth_time`::
- (Optional, integer) Time when the user authenticated to the JWT issuer,
- expressed as UTC seconds since epoch.
- This claim is optional. If it exists, a JWT realm of `id_token` type will verify
- it, while a JWT realm of `access_token` will just ignore it.
- [[jwt-validation-payload-es]]
- ====== {es} settings for consuming JWT claims
- {es} uses JWT claims for the following settings.
- `principal`::
- (Required, String) Contains the user's principal (username). The value is
- configurable using the realm setting `claims.principal`.
- You can configure an optional regular expression using the
- `claim_patterns.principal` to extract a substring.
- `groups`::
- (Optional, JSON array) Contains the user's group membership.
- The value is configurable using the realm setting `claims.groups`. You can
- configure an optional regular expression using the realm setting
- `claim_patterns.groups` to extract a substring value.
- `name`::
- (Optional, String) Contains a human-readable identifier that identifies the
- subject of the token. The value is configurable using the realm setting
- `claims.name`. You can configure an optional regular expression using the realm
- setting `claim_patterns.name` to extract a substring value.
- `mail`::
- (Optional, String) Contains the e-mail address to associate with the user. The
- value is configurable using the realm setting `claims.mail`. You can configure an
- optional regular expression using the realm setting `claim_patterns.mail` to
- extract a substring value.
- `dn`::
- (Optional, String) Contains the user's Distinguished Name (DN), which uniquely
- identifies a user or group. The value is configurable using the realm setting
- `claims.dn`. You can configure an optional regular expression using the realm
- setting `claim_patterns.dn` to extract a substring value.
- [[jwt-authorization]]
- ==== JWT realm authorization
- The JWT realm supports authorization with the create or update role mappings API,
- or delegating authorization to another realm. You cannot use these methods
- simultaneously, so choose whichever works best for your environment.
- IMPORTANT: You cannot map roles in the JWT realm using the `role_mapping.yml`
- file.
- [[jwt-authorization-role-mapping]]
- ===== Authorizing with the role mapping API
- You can use the
- <<security-api-put-role-mapping,create or update role mappings API>> to define
- role mappings that determine which roles should be assigned to each user based on
- their username, groups, or other metadata.
- [source,console]
- ----
- PUT /_security/role_mapping/jwt1_users?refresh=true
- {
- "roles" : [ "user" ],
- "rules" : { "all" : [
- { "field": { "realm.name": "jwt1" } },
- { "field": { "username": "principalname1" } },
- { "field": { "dn": "CN=Principal Name 1,DC=example.com" } },
- { "field": { "groups": "group1" } },
- { "field": { "metadata.jwt_claim_other": "other1" } }
- ] },
- "enabled": true
- }
- ----
- If you use this API in the JWT realm, the following claims are available for
- role mapping:
- `principal`::
- (Required, String) Principal claim that is used as the {es} user's username.
- `dn`::
- (Optional, String) Distinguished Name (DN) that is used as the {es} user's DN.
- `groups`::
- (Optional, String) Comma-separated value (CSV) list that is used as the {es}
- user's list of groups.
- `metadata`::
- (Optional, object) Additional metadata about the user, such as strings, integers,
- boolean values, and collections that are used as the {es} user's metadata.
- These values are key value pairs formatted as
- `metadata.jwt_claim_<key>` = `<value>`.
- [[jwt-authorization-delegation]]
- ===== Delegating JWT authorization to another realm
- If you <<authorization_realms,delegate authorization>> to other realms from the
- JWT realm, only the `principal` claim is available for role lookup. When
- delegating the assignment and lookup of roles to another realm from the JWT
- realm, claims for `dn`, `groups`, `mail`, `metadata`, and `name` are not used
- for the {es} user's values. Only the JWT `principal` claim is passed to the
- delegated authorization realms. The realms that are delegated for authorization
- - not the JWT realm - become responsible for populating all of the {es} user's
- values.
- The following example shows how you define delegation authorization in the
- `elasticsearch.yml` file to multiple other realms from the JWT realm. A JWT
- realm named `jwt2` is delegating authorization to multiple realms:
- [source,yaml]
- ----
- xpack.security.authc.realms.jwt.jwt2.authorization_realms: file1,native1,ldap1,ad1
- ----
- You can then use the
- <<security-api-put-role-mapping,create or update role mappings API>> to map
- roles to the authorizing realm. The following example maps roles in the `native1`
- realm for the `principalname1` JWT principal.
- [source,console]
- ----
- PUT /_security/role_mapping/native1_users?refresh=true
- {
- "roles" : [ "user" ],
- "rules" : { "all" : [
- { "field": { "realm.name": "native1" } },
- { "field": { "username": "principalname1" } }
- ] },
- "enabled": true
- }
- ----
- If realm `jwt2` successfully authenticates a client with a JWT for principal
- `principalname1`, and delegates authorization to one of the listed realms
- (such as `native1`), then that realm can look up the {es} user's values. With
- this defined role mapping, the realm can also look up this role mapping rule
- linked to realm `native1`.
- [[jwt-realm-runas]]
- ===== Applying the `run_as` privilege to JWT realm users
- {es} can retrieve roles for a JWT user through either role mapping or
- delegated authorization. Regardless of which option you choose, you can apply the
- <<run-as-privilege-apply,`run_as` privilege>> to a role so that a user can
- submit authenticated requests to "run as" a different user. To submit requests as
- another user, include the `es-security-runas-user` header in your requests.
- Requests run as if they were issued from that user and {es} uses their roles.
- For example, let's assume that there's a user with the username `user123_runas`.
- The following request creates a user role named `jwt_role1`, which specifies a
- `run_as` user with the `user123_runas` username. Any user with the `jwt_role1`
- role can issue requests as the specified `run_as` user.
- [source,console]
- ----
- POST /_security/role/jwt_role1?refresh=true
- {
- "cluster": ["manage"],
- "indices": [ { "names": [ "*" ], "privileges": ["read"] } ],
- "run_as": [ "user123_runas" ],
- "metadata" : { "version" : 1 }
- }
- ----
- You can then map that role to a user in a specific realm. The following request
- maps the `jwt_role1` role to a user with the username `user2` in the `jwt2` JWT
- realm. This means that {es} will use the `jwt2` realm to authenticate the user
- named `user2`. Because `user2` has a role (the `jwt_role1` role) that includes
- the `run_as` privilege, {es} retrieves the role mappings for the `user123_runas`
- user and uses the roles for that user to submit requests.
- [source,console]
- ----
- POST /_security/role_mapping/jwt_user1?refresh=true
- {
- "roles": [ "jwt_role1"],
- "rules" : { "all" : [
- { "field": { "realm.name": "jwt2" } },
- { "field": { "username": "user2" } }
- ] },
- "enabled": true,
- "metadata" : { "version" : 1 }
- }
- ----
- After mapping the roles, you can make an
- <<security-api-authenticate,authenticated call>> to {es} using a JWT and include
- the `ES-Client-Authentication` header:
- [[jwt-auth-shared-secret-scheme-example]]
- [source,sh]
- ----
- curl -s -X GET -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOlsiZXMwMSIsImVzMDIiLCJlczAzIl0sInN1YiI6InVzZXIyIiwiaXNzIjoibXktaXNzdWVyIiwiZXhwIjo0MDcwOTA4ODAwLCJpYXQiOjk0NjY4NDgwMCwiZW1haWwiOiJ1c2VyMkBzb21ldGhpbmcuZXhhbXBsZS5jb20ifQ.UgO_9w--EoRyUKcWM5xh9SimTfMzl1aVu6ZBsRWhxQA" -H "ES-Client-Authentication: sharedsecret test-secret" https://localhost:9200/_security/_authenticate
- ----
- // NOTCONSOLE
- The response includes the user who submitted the request (`user2`), including
- the `jwt_role1` role that you mapped to this user in the JWT realm:
- [source,sh]
- ----
- {"username":"user2","roles":["jwt_role1"],"full_name":null,"email":"user2@something.example.com",
- "metadata":{"jwt_claim_email":"user2@something.example.com","jwt_claim_aud":["es01","es02","es03"],
- "jwt_claim_sub":"user2","jwt_claim_iss":"my-issuer"},"enabled":true,"authentication_realm":
- {"name":"jwt2","type":"jwt"},"lookup_realm":{"name":"jwt2","type":"jwt"},"authentication_type":"realm"}
- %
- ----
- If you want to specify a request as the `run_as` user, include the
- `es-security-runas-user` header with the name of the user that you want to
- submit requests as. The following request uses the `user123_runas` user:
- [source,sh]
- ----
- curl -s -X GET -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOlsiZXMwMSIsImVzMDIiLCJlczAzIl0sInN1YiI6InVzZXIyIiwiaXNzIjoibXktaXNzdWVyIiwiZXhwIjo0MDcwOTA4ODAwLCJpYXQiOjk0NjY4NDgwMCwiZW1haWwiOiJ1c2VyMkBzb21ldGhpbmcuZXhhbXBsZS5jb20ifQ.UgO_9w--EoRyUKcWM5xh9SimTfMzl1aVu6ZBsRWhxQA" -H "ES-Client-Authentication: sharedsecret test-secret" -H "es-security-runas-user: user123_runas" https://localhost:9200/_security/_authenticate
- ----
- // NOTCONSOLE
- In the response, you'll see that the `user123_runas` user submitted the request,
- and {es} used the `jwt_role1` role:
- [source,sh]
- ----
- {"username":"user123_runas","roles":["jwt_role1"],"full_name":null,"email":null,"metadata":{},
- "enabled":true,"authentication_realm":{"name":"jwt2","type":"jwt"},"lookup_realm":{"name":"native",
- "type":"native"},"authentication_type":"realm"}%
- ----
- [[jwt-realm-jwkset-reloading]]
- ===== PKC JWKS reloading
- JWT authentication supports signature verification using PKC (Public Key Cryptography)
- or HMAC algorithms.
- PKC JSON Web Token Key Sets (JWKS) can contain public RSA and EC keys. HMAC JWKS
- or an HMAC UTF-8 JWK contain secret keys. JWT issuers typically rotate PKC JWKS
- more frequently (such as daily), because RSA and EC public keys are designed to
- be easier to distribute than secret keys like HMAC.
- JWT realms load a PKC JWKS and an HMAC JWKS or HMAC UTF-8 JWK at startup. JWT
- realms can also reload PKC JWKS contents at runtime; a reload is triggered by
- signature validation failures.
- NOTE: HMAC JWKS or HMAC UTF-8 JWK reloading is not supported at this time.
- Load failures, parse errors, and configuration errors prevent a node from
- starting (and restarting). However, runtime PKC reload errors and recoveries are
- handled gracefully.
- All other JWT realm validations are checked before a signature failure can
- trigger a PKC JWKS reload. If multiple JWT authentication signature failures
- occur simultaneously with a single {es} node, reloads are combined to reduce
- the reloads that are sent externally.
- Separate reload requests cannot be combined if JWT signature failures trigger:
- * PKC JWKS reloads in different {es} nodes
- * PKC JWKS reloads in the same {es} node at different times
- [IMPORTANT]
- ====
- Enabling client authentication (`client_authentication.type`) is strongly
- recommended. Only trusted client applications and realm-specific JWT users can
- trigger PKC reload attempts. Additionally, configuring the following
- <<ref-jwt-settings,JWT security settings>> is recommended:
- * `allowed_audiences`
- * `allowed_clock_skew`
- * `allowed_issuer`
- * `allowed_signature_algorithms`
- ====
- [[hmac-oidc-example]]
- ==== Authorizing to the JWT realm with an HMAC UTF-8 key
- The following settings are for a JWT issuer, {es}, and a client of {es}. The
- example HMAC key is in an OIDC format that's compatible with HMAC. The key bytes
- are the UTF-8 encoding of the UNICODE characters.
- IMPORTANT: HMAC UTF-8 keys need to be longer than HMAC random byte keys to
- achieve the same key strength.
- [[hmac-oidc-example-jwt-issuer]]
- ===== JWT issuer
- The following values are for the bespoke JWT issuer.
- [source,js]
- ----
- Issuer: iss8
- Audiences: aud8
- Algorithms: HS256
- HMAC UTF-8: hmac-oidc-key-string-for-hs256-algorithm
- ----
- // NOTCONSOLE
- [[hmac-oidc-example-jwt-realm]]
- ===== JWT realm settings
- To define a JWT realm, add the following realm settings to `elasticsearch.yml`.
- [source,yaml]
- ----
- xpack.security.authc.realms.jwt.jwt8.order: 8 <1>
- xpack.security.authc.realms.jwt.jwt8.allowed_issuer: iss8
- xpack.security.authc.realms.jwt.jwt8.allowed_audiences: [aud8]
- xpack.security.authc.realms.jwt.jwt8.allowed_signature_algorithms: [HS256]
- xpack.security.authc.realms.jwt.jwt8.claims.principal: sub
- xpack.security.authc.realms.jwt.jwt8.client_authentication.type: shared_secret
- ----
- <1> In {ecloud}, the realm order starts at `2`. `0` and `1` are reserved in the
- realm chain on {ecloud}.
- ===== JWT realm secure settings
- After defining the realm settings, use the
- {ref}/elasticsearch-keystore.html[`elasticsearch-keystore`] tool to add the
- following secure settings to the {es} keystore. In {ecloud}, you define settings
- for the {es} keystore under **Security** in your deployment.
- [source,yaml]
- ----
- xpack.security.authc.realms.jwt.jwt8.hmac_key: hmac-oidc-key-string-for-hs256-algorithm
- xpack.security.authc.realms.jwt.jwt8.client_authentication.shared_secret: client-shared-secret-string
- ----
- ===== JWT realm role mapping rule
- The following request creates role mappings for {es} in the `jwt8` realm for
- the user `principalname1`:
- [source,console]
- ----
- PUT /_security/role_mapping/jwt8_users?refresh=true
- {
- "roles" : [ "user" ],
- "rules" : { "all" : [
- { "field": { "realm.name": "jwt8" } },
- { "field": { "username": "principalname1" } }
- ] },
- "enabled": true
- }
- ----
- [[hmac-oidc-example-request-headers]]
- ===== Request headers
- The following header settings are for an {es} client.
- [source,js]
- ----
- Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJpc3M4IiwiYXVkIjoiYXVkOCIsInN1YiI6InNlY3VyaXR5X3Rlc3RfdXNlciIsImV4cCI6NDA3MDkwODgwMCwiaWF0Ijo5NDY2ODQ4MDB9.UnnFmsoFKfNmKMsVoDQmKI_3-j95PCaKdgqqau3jPMY
- ES-Client-Authentication: SharedSecret client-shared-secret-string
- ----
- // NOTCONSOLE
- You can use this header in a `curl` request to make an authenticated call to
- {es}. Both the bearer token and the client authorization token must be
- specified as separate headers with the `-H` option:
- [source,sh]
- ----
- curl -s -X GET -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJpc3M4IiwiYXVkIjoiYXVkOCIsInN1YiI6InNlY3VyaXR5X3Rlc3RfdXNlciIsImV4cCI6NDA3MDkwODgwMCwiaWF0Ijo5NDY2ODQ4MDB9.UnnFmsoFKfNmKMsVoDQmKI_3-j95PCaKdgqqau3jPMY" -H "ES-Client-Authentication: SharedSecret client-shared-secret-string" https://localhost:9200/_security/_authenticate
- ----
- // NOTCONSOLE
- If you used role mapping in the JWT realm, the response includes the user's
- `username`, their `roles`, metadata about the user, and the details about the
- JWT realm itself.
- [source,sh]
- ----
- {"username":"user2","roles":["jwt_role1"],"full_name":null,"email":"user2@something.example.com",
- "metadata":{"jwt_claim_email":"user2@something.example.com","jwt_claim_aud":["es01","es02","es03"],
- "jwt_claim_sub":"user2","jwt_claim_iss":"my-issuer"},"enabled":true,"authentication_realm":
- {"name":"jwt2","type":"jwt"},"lookup_realm":{"name":"jwt2","type":"jwt"},"authentication_type":"realm"}
- ----
|