jwt-realm.asciidoc 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729
  1. [role="xpack"]
  2. [[jwt-auth-realm]]
  3. === JWT authentication
  4. {es} can be configured to trust JSON Web Tokens (JWTs) issued from an external service
  5. as bearer tokens for authentication.
  6. When a JWT realm is used to authenticate with {es}, a distinction is made
  7. between the _client_ that is connecting to {es}, and the _user_ on whose behalf
  8. the request should run. The JWT authenticates the user, and a separate credential
  9. authenticates the client.
  10. The JWT realm supports two token types, `id_token` (the default) and `access_token`.
  11. They are designed to work for the following two scenarios, respectively:
  12. 1. `id_token` - An application authenticates and identifies a user with an authentication flow,
  13. e.g. OpenID Connect (OIDC), and then accesses {es} on behalf of the authenticated user using
  14. a JSON Web Token (JWT) conforming to OIDC ID Token specification.
  15. 2. `access_token` - An application accesses {es} using its own identity, encoded as a JWT,
  16. e.g. The application authenticates itself to a central identity platform using an
  17. OAuth2 Client Credentials Flow and then uses the resulting JWT-based access token to connect to {es}.
  18. NOTE: A single JWT realm can only work with a single token type. To handle both token types,
  19. you must configure at least two JWT realms. You should choose the token type carefully based
  20. on the use case because it impacts on how validations are performed.
  21. The JWT realm validates the incoming JWT based on its configured token type.
  22. JSON Web Tokens (JWT) of both types must contain the following 5 pieces of information.
  23. While ID Tokens, based on the OIDC specification, have strict rules for what claims should provide these information,
  24. access tokens allow some claims to be configurable.
  25. [cols="3",frame=all]
  26. |====
  27. h| 2+^h| Claims
  28. h| Information | ID Token | Access Token
  29. | Issuer | `iss` | `iss`
  30. | Subject | `sub` | Defaults to `sub`, but can fall back to another claim if `sub` does not exist
  31. | Audiences | `aud` | Defaults to `aud`, but can fall back to another claim if `aud` does not exist
  32. | Issue Time | `iat` | `iat`
  33. | Expiration Time | `exp` | `exp`
  34. |====
  35. In addition, {es} also validates `nbf` and `auth_time` claims for ID Tokens if these claims are present.
  36. But these claims are ignored for access tokens.
  37. Overall, the access token type has more relaxed validation rules and is suitable for more generic JWTs,
  38. including self-signed ones.
  39. [[jwt-realm-oidc]]
  40. ==== ID Tokens from OIDC workflows
  41. JWT authentication in {es} is derived from OIDC user workflows, where different
  42. tokens can be issued by an OIDC Provider (OP), including ID Tokens.
  43. ID Tokens from an OIDC provider are well-defined JSON Web Tokens (JWT) and should be always compatible with
  44. a JWT realm of the `id_token` token type. The subject claim of an ID token represents the end-user.
  45. This means that ID tokens will generally have many allowed subjects.
  46. Therefore, a JWT realm of `id_token` token type does _not_ mandate the `allowed_subjects`
  47. (or `allowed_subject_patterns`) validation.
  48. NOTE: Because JWTs are obtained external to {es}, you can define a custom workflow
  49. instead of using the OIDC workflow. However, the JWT format must still be JSON
  50. Web Signature (JWS). The JWS header and JWS signature are validated using OIDC
  51. ID token validation rules.
  52. {es} supports a separate <<oidc-realm,OpenID Connect realm>>. It is preferred for any
  53. use case where {es} can act as an OIDC RP. The OIDC realm is the only supported
  54. way to enable OIDC authentication in {kib}.
  55. TIP: Users authenticating with a JWT realm can optionally impersonate another user
  56. with the <<run-as-privilege,`run_as`>> feature. See also <<jwt-realm-runas>>.
  57. [[jwt-realm-oauth2]]
  58. ==== Access Tokens
  59. A common method to obtain access tokens is with the OAuth2 Client Credentials Flow.
  60. A typical usage of this flow is for an application to get a credential for itself.
  61. This is the use case that the `access_token` token type is designed for.
  62. It is likely that this application also obtains ID Tokens for its end-users.
  63. To prevent end-user ID Tokens being used to authenticate with the JWT realm configured
  64. for the application, we mandate `allowed_subjects` or `allowed_subject_patterns`
  65. validation when a JWT realm has token type `access_token`.
  66. NOTE: Not every access token is formatted as a JSON Web Token (JWT).
  67. For it to be compatible with the JWT realm, it must at least use the JWT format and satisfies
  68. relevant requirements in the above table.
  69. [[jwt-realm-configuration]]
  70. ==== Configure {es} to use a JWT realm
  71. To use JWT authentication, create the realm in the `elasticsearch.yml` file
  72. to configure it within the {es} authentication chain.
  73. The JWT realm has a few mandatory settings, plus optional settings that are
  74. described in <<ref-jwt-settings,JWT realm settings>>.
  75. NOTE: Client authentication is enabled by default for the JWT realms. Disabling
  76. client authentication is possible, but strongly discouraged.
  77. . Add your JWT realm to the `elasticsearch.yml` file. The following example
  78. includes the most common settings, which are not intended for every use case:
  79. +
  80. --
  81. [source,yaml]
  82. ----
  83. xpack.security.authc.realms.jwt.jwt1:
  84. order: 3
  85. token_type: id_token
  86. client_authentication.type: shared_secret
  87. allowed_issuer: "https://issuer.example.com/jwt/"
  88. allowed_audiences: [ "8fb85eba-979c-496c-8ae2-a57fde3f12d0" ]
  89. allowed_signature_algorithms: [RS256,HS256]
  90. pkc_jwkset_path: jwt/jwkset.json
  91. claims.principal: sub
  92. ----
  93. `order`::
  94. Specifies a realm `order` of `3`, which indicates the order in which the
  95. configured realm is checked when authenticating a user. Realms are consulted in
  96. ascending order, where the realm with the lowest order value is consulted first.
  97. `token_type`::
  98. Instructs the realm to treat and validate incoming JWTs as ID Tokens (`id_token`).
  99. `client_authentication.type`::
  100. Specifies the client authentication type as `shared_secret`, which means that
  101. the client is authenticated using an HTTP request header that must match a
  102. pre-configured secret value. The client must provide this shared secret with
  103. every request in the `ES-Client-Authentication` header and using the
  104. `SharedSecret` scheme. The header value must be a case-sensitive match
  105. to the realm's `client_authentication.shared_secret`.
  106. `allowed_issuer`::
  107. Sets a verifiable identifier for your JWT issuer. This value is typically a
  108. URL, UUID, or some other case-sensitive string value.
  109. `allowed_audiences`::
  110. Specifies a list of JWT audiences that the realm will allow.
  111. These values are typically URLs, UUIDs, or other case-sensitive string values.
  112. `allowed_signature_algorithms`::
  113. Indicates that {es} should use the `RS256` or `HS256` signature algorithms to
  114. verify the signature of the JWT from the JWT issuer.
  115. `pkc_jwkset_path`::
  116. The file name or URL to a JSON Web Key Set (JWKS) with the public key material that
  117. the JWT Realm uses for verifying token signatures. A value is considered a file name
  118. if it does not begin with `https`. The file name
  119. is resolved relative to the {es} configuration directory. If a URL is provided, then
  120. it must begin with `https://` (`http://` is not supported).
  121. {es} automatically caches the JWK set and will attempt to refresh the
  122. JWK set upon signature verification failure, as this might indicate that the JWT Provider has
  123. rotated the signing keys.
  124. `claims.principal`::
  125. The name of the JWT claim that contains the user's principal (username).
  126. The following is an example snippet for configure a JWT realm for handling
  127. access tokens:
  128. [source,yaml]
  129. ----
  130. xpack.security.authc.realms.jwt.jwt2:
  131. order: 4
  132. token_type: access_token
  133. client_authentication.type: shared_secret
  134. allowed_issuer: "https://issuer.example.com/jwt/"
  135. allowed_subjects: [ "123456-compute@admin.example.com" ]
  136. allowed_subject_patterns: [ "wild*@developer?.example.com", "/[a-z]+<1-10>\\@dev\\.example\\.com/"]
  137. allowed_audiences: [ "elasticsearch" ]
  138. required_claims:
  139. token_use: access
  140. version: ["1.0", "2.0"]
  141. allowed_signature_algorithms: [RS256,HS256]
  142. pkc_jwkset_path: "https://idp-42.example.com/.well-known/configuration"
  143. fallback_claims.sub: client_id
  144. fallback_claims.aud: scope
  145. claims.principal: sub
  146. ----
  147. `token_type`::
  148. Instructs the realm to treat and validate incoming JWTs as access tokens (`access_token`).
  149. `allowed_subjects`::
  150. Specifies a list of JWT subjects that the realm will allow.
  151. These values are typically URLs, UUIDs, or other case-sensitive string values.
  152. `allowed_subject_patterns`::
  153. Analogous to `allowed_subjects` but it accepts a list of <<regexp-syntax,Lucene regexp>>
  154. and wildcards for the allowed JWT subjects. Wildcards use the `*` and `?` special
  155. characters (which are escaped by `\`) to mean "any string" and "any single character"
  156. respectively, for example "a?\\**", matches "a1*" and "ab*whatever", but not "a", "abc", or "abc*"
  157. (in Java strings `\` must itself be escaped by another `\`).
  158. <<regexp-syntax,Lucene regexp>> must be enclosed between `/`,
  159. for example "/https?://[^/]+/?/" matches any http or https URL with no path component
  160. (matches "https://elastic.co/" but not "https://elastic.co/guide").
  161. NOTE: At least one of the `allowed_subjects` or `allowed_subject_patterns` settings must be specified
  162. (and be non-empty) when `token_type` is `access_token`.
  163. NOTE: When both `allowed_subjects` and `allowed_subject_patterns` settings are specified
  164. an incoming JWT's `sub` claim is accepted if it matches any of the two lists.
  165. `required_claims`::
  166. Specifies a list of key/value pairs for additional verifications to be performed
  167. against a JWT. The values are either a string or an array of strings.
  168. `fallback_claims.sub`::
  169. The name of the JWT claim to extract the subject information if the `sub` claim does not exist.
  170. This setting is only available when `token_type` is `access_token`.
  171. The fallback is applied everywhere the `sub` claim is used.
  172. In the above snippet, it means the `claims.principal` will also fallback to `client_id`
  173. if `sub` does not exist.
  174. `fallback_claims.aud`::
  175. The name of the JWT claim to extract the audiences information if the `aud` claim does not exist.
  176. This setting is only available when `token_type` is `access_token`.
  177. The fallback is applied everywhere the `aud` claim is used.
  178. --
  179. . After defining settings, use the
  180. {ref}/elasticsearch-keystore.html[`elasticsearch-keystore`] tool to store
  181. values for secure settings in the {es} keystore.
  182. .. Store the `shared_secret` value for `client_authentication.type`:
  183. +
  184. [source,shell]
  185. ----
  186. bin/elasticsearch-keystore add xpack.security.authc.realms.jwt.jwt1.client_authentication.shared_secret
  187. ----
  188. .. Store the HMAC keys for `allowed_signature_algorithms`, which use the HMAC
  189. SHA-256 algorithm `HS256` in the example:
  190. +
  191. [source,shell]
  192. ----
  193. bin/elasticsearch-keystore add-file xpack.security.authc.realms.jwt.jwt1.hmac_jwkset <path> <1>
  194. ----
  195. <1> Path to a JWKS, which is a resource for a set of JSON-encoded secret keys.
  196. The file can be removed after you load the contents into the {es} keystore.
  197. +
  198. [NOTE]
  199. ====
  200. Using the JWKS is preferred. However, you can add an HMAC key in string format
  201. using the following command. This format is compatible with HMAC UTF-8 keys, but
  202. only supports a single key with no attributes. You can only use one HMAC format
  203. (either `hmac_jwkset` or `hmac_key`) simultaneously.
  204. [source,shell]
  205. ----
  206. bin/elasticsearch-keystore add xpack.security.authc.realms.jwt.jwt1.hmac_key
  207. ----
  208. ====
  209. [[jwt-validation]]
  210. ==== JWT encoding and validation
  211. JWTs can be parsed into three pieces:
  212. Header::
  213. Provides information about how to validate the token.
  214. Claims::
  215. Contains data about the calling user or application.
  216. Signature::
  217. The data that's used to validate the token.
  218. [source,js]
  219. ----
  220. Header: {"typ":"JWT","alg":"HS256"}
  221. Claims: {"aud":"aud8","sub":"security_test_user","iss":"iss8","exp":4070908800,"iat":946684800}
  222. Signature: UnnFmsoFKfNmKMsVoDQmKI_3-j95PCaKdgqqau3jPMY
  223. ----
  224. // NOTCONSOLE
  225. This example illustrates a partial decoding of a JWT. The validity period is
  226. from 2000 to 2099 (inclusive), as defined by the issue time (`iat`) and
  227. expiration time (`exp`). JWTs typically have a validity period shorter than
  228. 100 years, such as 1-2 hours or 1-7 days, not an entire human life.
  229. The signature in this example is deterministic because the header, claims, and
  230. HMAC key are fixed. JWTs typically have a `nonce` claim to make the signature
  231. non-deterministic. The supported JWT encoding is JSON Web Signature (JWS), and
  232. the JWS `Header` and `Signature` are validated using OpenID Connect ID Token
  233. validation rules. Some validation is customizable through
  234. <<ref-jwt-settings,JWT realm settings>>.
  235. [[jwt-validation-header]]
  236. ===== Header claims
  237. The header claims indicate the token type and the algorithm used to sign the
  238. token.
  239. `alg`::
  240. (Required, String) Indicates the algorithm that was used to sign the token, such
  241. as `HS256`. The algorithm must be in the realm's allow list.
  242. `typ`::
  243. (Optional, String) Indicates the token type.
  244. +
  245. For an ID token, this must be
  246. +
  247. - `JWT`
  248. +
  249. For access tokens, this must be one of
  250. +
  251. - `JWT`
  252. - `at+jwt`
  253. [[jwt-validation-payload]]
  254. ===== Payload claims
  255. Tokens contain several claims, which provide information about the user
  256. who is issuing the token, and the token itself.
  257. Depending on the token type, these information can optionally be identified
  258. by different claims.
  259. ====== JWT payload claims
  260. The following claims are validated by a subset of OIDC ID token rules.
  261. {es} doesn't validate `nonce` claims, but a custom JWT issuer can add a
  262. random `nonce` claim to introduce entropy into the signature.
  263. NOTE: You can relax validation of any of the time-based claims by setting
  264. `allowed_clock_skew`. This value sets the maximum allowed clock skew before
  265. validating JWTs with respect to their authentication time (`auth_time`),
  266. creation (`iat`), not before (`nbf`), and expiration times (`exp`).
  267. `iss`::
  268. (Required, String) Denotes the issuer that created the ID token. The value must
  269. be an exact, case-sensitive match to the value in the `allowed_issuer` setting.
  270. `sub`::
  271. (Required*, String) Indicates the subject that the ID token is created for.
  272. If the JWT realm is of the `id_token` type, this claim is mandatory.
  273. A JWT realm of the `id_token` type by defaults accepts all subjects.
  274. A JWT realm of the access_token type must specify the `allowed_subjects` setting and the subject value
  275. must be an exact, case-sensitive match to any of the CSV values in the
  276. allowed_subjects setting.
  277. A JWT realm of the access_token type can specify a fallback claim that will
  278. be used in place where the `sub` claim does not exist.
  279. `aud`::
  280. (Required*, String) Indicates the audiences that the ID token is for, expressed as a
  281. comma-separated value (CSV). One of the values must be an exact, case-sensitive
  282. match to any of the CSV values in the `allowed_audiences` setting.
  283. If the JWT realm is of the `id_token` type, this claim is mandatory.
  284. A JWT realm of the `access_token` type can specify a fallback claim that will
  285. be used in place where the `aud` claim does not exist.
  286. `exp`::
  287. (Required, integer) Expiration time for the ID token, expressed in UTC
  288. seconds since epoch.
  289. `iat`::
  290. (Required, integer) Time that the ID token was issued, expressed in UTC
  291. seconds since epoch.
  292. `nbf`::
  293. (Optional, integer) Indicates the time before which the JWT must not be accepted,
  294. expressed as UTC seconds since epoch.
  295. This claim is optional. If it exists, a JWT realm of `id_token` type will verify
  296. it, while a JWT realm of `access_token` will just ignore it.
  297. `auth_time`::
  298. (Optional, integer) Time when the user authenticated to the JWT issuer,
  299. expressed as UTC seconds since epoch.
  300. This claim is optional. If it exists, a JWT realm of `id_token` type will verify
  301. it, while a JWT realm of `access_token` will just ignore it.
  302. [[jwt-validation-payload-es]]
  303. ====== {es} settings for consuming JWT claims
  304. {es} uses JWT claims for the following settings.
  305. `principal`::
  306. (Required, String) Contains the user's principal (username). The value is
  307. configurable using the realm setting `claims.principal`.
  308. You can configure an optional regular expression using the
  309. `claim_patterns.principal` to extract a substring.
  310. `groups`::
  311. (Optional, JSON array) Contains the user's group membership.
  312. The value is configurable using the realm setting `claims.groups`. You can
  313. configure an optional regular expression using the realm setting
  314. `claim_patterns.groups` to extract a substring value.
  315. `name`::
  316. (Optional, String) Contains a human-readable identifier that identifies the
  317. subject of the token. The value is configurable using the realm setting
  318. `claims.name`. You can configure an optional regular expression using the realm
  319. setting `claim_patterns.name` to extract a substring value.
  320. `mail`::
  321. (Optional, String) Contains the e-mail address to associate with the user. The
  322. value is configurable using the realm setting `claims.mail`. You can configure an
  323. optional regular expression using the realm setting `claim_patterns.mail` to
  324. extract a substring value.
  325. `dn`::
  326. (Optional, String) Contains the user's Distinguished Name (DN), which uniquely
  327. identifies a user or group. The value is configurable using the realm setting
  328. `claims.dn`. You can configure an optional regular expression using the realm
  329. setting `claim_patterns.dn` to extract a substring value.
  330. [[jwt-authorization]]
  331. ==== JWT realm authorization
  332. The JWT realm supports authorization with the create or update role mappings API,
  333. or delegating authorization to another realm. You cannot use these methods
  334. simultaneously, so choose whichever works best for your environment.
  335. IMPORTANT: You cannot map roles in the JWT realm using the `role_mapping.yml`
  336. file.
  337. [[jwt-authorization-role-mapping]]
  338. ===== Authorizing with the role mapping API
  339. You can use the
  340. <<security-api-put-role-mapping,create or update role mappings API>> to define
  341. role mappings that determine which roles should be assigned to each user based on
  342. their username, groups, or other metadata.
  343. [source,console]
  344. ----
  345. PUT /_security/role_mapping/jwt1_users?refresh=true
  346. {
  347. "roles" : [ "user" ],
  348. "rules" : { "all" : [
  349. { "field": { "realm.name": "jwt1" } },
  350. { "field": { "username": "principalname1" } },
  351. { "field": { "dn": "CN=Principal Name 1,DC=example.com" } },
  352. { "field": { "groups": "group1" } },
  353. { "field": { "metadata.jwt_claim_other": "other1" } }
  354. ] },
  355. "enabled": true
  356. }
  357. ----
  358. If you use this API in the JWT realm, the following claims are available for
  359. role mapping:
  360. `principal`::
  361. (Required, String) Principal claim that is used as the {es} user's username.
  362. `dn`::
  363. (Optional, String) Distinguished Name (DN) that is used as the {es} user's DN.
  364. `groups`::
  365. (Optional, String) Comma-separated value (CSV) list that is used as the {es}
  366. user's list of groups.
  367. `metadata`::
  368. (Optional, object) Additional metadata about the user, such as strings, integers,
  369. boolean values, and collections that are used as the {es} user's metadata.
  370. These values are key value pairs formatted as
  371. `metadata.jwt_claim_<key>` = `<value>`.
  372. [[jwt-authorization-delegation]]
  373. ===== Delegating JWT authorization to another realm
  374. If you <<authorization_realms,delegate authorization>> to other realms from the
  375. JWT realm, only the `principal` claim is available for role lookup. When
  376. delegating the assignment and lookup of roles to another realm from the JWT
  377. realm, claims for `dn`, `groups`, `mail`, `metadata`, and `name` are not used
  378. for the {es} user's values. Only the JWT `principal` claim is passed to the
  379. delegated authorization realms. The realms that are delegated for authorization
  380. - not the JWT realm - become responsible for populating all of the {es} user's
  381. values.
  382. The following example shows how you define delegation authorization in the
  383. `elasticsearch.yml` file to multiple other realms from the JWT realm. A JWT
  384. realm named `jwt2` is delegating authorization to multiple realms:
  385. [source,yaml]
  386. ----
  387. xpack.security.authc.realms.jwt.jwt2.authorization_realms: file1,native1,ldap1,ad1
  388. ----
  389. You can then use the
  390. <<security-api-put-role-mapping,create or update role mappings API>> to map
  391. roles to the authorizing realm. The following example maps roles in the `native1`
  392. realm for the `principalname1` JWT principal.
  393. [source,console]
  394. ----
  395. PUT /_security/role_mapping/native1_users?refresh=true
  396. {
  397. "roles" : [ "user" ],
  398. "rules" : { "all" : [
  399. { "field": { "realm.name": "native1" } },
  400. { "field": { "username": "principalname1" } }
  401. ] },
  402. "enabled": true
  403. }
  404. ----
  405. If realm `jwt2` successfully authenticates a client with a JWT for principal
  406. `principalname1`, and delegates authorization to one of the listed realms
  407. (such as `native1`), then that realm can look up the {es} user's values. With
  408. this defined role mapping, the realm can also look up this role mapping rule
  409. linked to realm `native1`.
  410. [[jwt-realm-runas]]
  411. ===== Applying the `run_as` privilege to JWT realm users
  412. {es} can retrieve roles for a JWT user through either role mapping or
  413. delegated authorization. Regardless of which option you choose, you can apply the
  414. <<run-as-privilege-apply,`run_as` privilege>> to a role so that a user can
  415. submit authenticated requests to "run as" a different user. To submit requests as
  416. another user, include the `es-security-runas-user` header in your requests.
  417. Requests run as if they were issued from that user and {es} uses their roles.
  418. For example, let's assume that there's a user with the username `user123_runas`.
  419. The following request creates a user role named `jwt_role1`, which specifies a
  420. `run_as` user with the `user123_runas` username. Any user with the `jwt_role1`
  421. role can issue requests as the specified `run_as` user.
  422. [source,console]
  423. ----
  424. POST /_security/role/jwt_role1?refresh=true
  425. {
  426. "cluster": ["manage"],
  427. "indices": [ { "names": [ "*" ], "privileges": ["read"] } ],
  428. "run_as": [ "user123_runas" ],
  429. "metadata" : { "version" : 1 }
  430. }
  431. ----
  432. You can then map that role to a user in a specific realm. The following request
  433. maps the `jwt_role1` role to a user with the username `user2` in the `jwt2` JWT
  434. realm. This means that {es} will use the `jwt2` realm to authenticate the user
  435. named `user2`. Because `user2` has a role (the `jwt_role1` role) that includes
  436. the `run_as` privilege, {es} retrieves the role mappings for the `user123_runas`
  437. user and uses the roles for that user to submit requests.
  438. [source,console]
  439. ----
  440. POST /_security/role_mapping/jwt_user1?refresh=true
  441. {
  442. "roles": [ "jwt_role1"],
  443. "rules" : { "all" : [
  444. { "field": { "realm.name": "jwt2" } },
  445. { "field": { "username": "user2" } }
  446. ] },
  447. "enabled": true,
  448. "metadata" : { "version" : 1 }
  449. }
  450. ----
  451. After mapping the roles, you can make an
  452. <<security-api-authenticate,authenticated call>> to {es} using a JWT and include
  453. the `ES-Client-Authentication` header:
  454. [[jwt-auth-shared-secret-scheme-example]]
  455. [source,sh]
  456. ----
  457. curl -s -X GET -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOlsiZXMwMSIsImVzMDIiLCJlczAzIl0sInN1YiI6InVzZXIyIiwiaXNzIjoibXktaXNzdWVyIiwiZXhwIjo0MDcwOTA4ODAwLCJpYXQiOjk0NjY4NDgwMCwiZW1haWwiOiJ1c2VyMkBzb21ldGhpbmcuZXhhbXBsZS5jb20ifQ.UgO_9w--EoRyUKcWM5xh9SimTfMzl1aVu6ZBsRWhxQA" -H "ES-Client-Authentication: sharedsecret test-secret" https://localhost:9200/_security/_authenticate
  458. ----
  459. // NOTCONSOLE
  460. The response includes the user who submitted the request (`user2`), including
  461. the `jwt_role1` role that you mapped to this user in the JWT realm:
  462. [source,sh]
  463. ----
  464. {"username":"user2","roles":["jwt_role1"],"full_name":null,"email":"user2@something.example.com",
  465. "metadata":{"jwt_claim_email":"user2@something.example.com","jwt_claim_aud":["es01","es02","es03"],
  466. "jwt_claim_sub":"user2","jwt_claim_iss":"my-issuer"},"enabled":true,"authentication_realm":
  467. {"name":"jwt2","type":"jwt"},"lookup_realm":{"name":"jwt2","type":"jwt"},"authentication_type":"realm"}
  468. %
  469. ----
  470. If you want to specify a request as the `run_as` user, include the
  471. `es-security-runas-user` header with the name of the user that you want to
  472. submit requests as. The following request uses the `user123_runas` user:
  473. [source,sh]
  474. ----
  475. 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
  476. ----
  477. // NOTCONSOLE
  478. In the response, you'll see that the `user123_runas` user submitted the request,
  479. and {es} used the `jwt_role1` role:
  480. [source,sh]
  481. ----
  482. {"username":"user123_runas","roles":["jwt_role1"],"full_name":null,"email":null,"metadata":{},
  483. "enabled":true,"authentication_realm":{"name":"jwt2","type":"jwt"},"lookup_realm":{"name":"native",
  484. "type":"native"},"authentication_type":"realm"}%
  485. ----
  486. [[jwt-realm-jwkset-reloading]]
  487. ===== PKC JWKS reloading
  488. JWT authentication supports signature verification using PKC (Public Key Cryptography)
  489. or HMAC algorithms.
  490. PKC JSON Web Token Key Sets (JWKS) can contain public RSA and EC keys. HMAC JWKS
  491. or an HMAC UTF-8 JWK contain secret keys. JWT issuers typically rotate PKC JWKS
  492. more frequently (such as daily), because RSA and EC public keys are designed to
  493. be easier to distribute than secret keys like HMAC.
  494. JWT realms load a PKC JWKS and an HMAC JWKS or HMAC UTF-8 JWK at startup. JWT
  495. realms can also reload PKC JWKS contents at runtime; a reload is triggered by
  496. signature validation failures.
  497. NOTE: HMAC JWKS or HMAC UTF-8 JWK reloading is not supported at this time.
  498. Load failures, parse errors, and configuration errors prevent a node from
  499. starting (and restarting). However, runtime PKC reload errors and recoveries are
  500. handled gracefully.
  501. All other JWT realm validations are checked before a signature failure can
  502. trigger a PKC JWKS reload. If multiple JWT authentication signature failures
  503. occur simultaneously with a single {es} node, reloads are combined to reduce
  504. the reloads that are sent externally.
  505. Separate reload requests cannot be combined if JWT signature failures trigger:
  506. * PKC JWKS reloads in different {es} nodes
  507. * PKC JWKS reloads in the same {es} node at different times
  508. [IMPORTANT]
  509. ====
  510. Enabling client authentication (`client_authentication.type`) is strongly
  511. recommended. Only trusted client applications and realm-specific JWT users can
  512. trigger PKC reload attempts. Additionally, configuring the following
  513. <<ref-jwt-settings,JWT security settings>> is recommended:
  514. * `allowed_audiences`
  515. * `allowed_clock_skew`
  516. * `allowed_issuer`
  517. * `allowed_signature_algorithms`
  518. ====
  519. [[hmac-oidc-example]]
  520. ==== Authorizing to the JWT realm with an HMAC UTF-8 key
  521. The following settings are for a JWT issuer, {es}, and a client of {es}. The
  522. example HMAC key is in an OIDC format that's compatible with HMAC. The key bytes
  523. are the UTF-8 encoding of the UNICODE characters.
  524. IMPORTANT: HMAC UTF-8 keys need to be longer than HMAC random byte keys to
  525. achieve the same key strength.
  526. [[hmac-oidc-example-jwt-issuer]]
  527. ===== JWT issuer
  528. The following values are for the bespoke JWT issuer.
  529. [source,js]
  530. ----
  531. Issuer: iss8
  532. Audiences: aud8
  533. Algorithms: HS256
  534. HMAC UTF-8: hmac-oidc-key-string-for-hs256-algorithm
  535. ----
  536. // NOTCONSOLE
  537. [[hmac-oidc-example-jwt-realm]]
  538. ===== JWT realm settings
  539. To define a JWT realm, add the following realm settings to `elasticsearch.yml`.
  540. [source,yaml]
  541. ----
  542. xpack.security.authc.realms.jwt.jwt8.order: 8 <1>
  543. xpack.security.authc.realms.jwt.jwt8.allowed_issuer: iss8
  544. xpack.security.authc.realms.jwt.jwt8.allowed_audiences: [aud8]
  545. xpack.security.authc.realms.jwt.jwt8.allowed_signature_algorithms: [HS256]
  546. xpack.security.authc.realms.jwt.jwt8.claims.principal: sub
  547. xpack.security.authc.realms.jwt.jwt8.client_authentication.type: shared_secret
  548. ----
  549. <1> In {ecloud}, the realm order starts at `2`. `0` and `1` are reserved in the
  550. realm chain on {ecloud}.
  551. ===== JWT realm secure settings
  552. After defining the realm settings, use the
  553. {ref}/elasticsearch-keystore.html[`elasticsearch-keystore`] tool to add the
  554. following secure settings to the {es} keystore. In {ecloud}, you define settings
  555. for the {es} keystore under **Security** in your deployment.
  556. [source,yaml]
  557. ----
  558. xpack.security.authc.realms.jwt.jwt8.hmac_key: hmac-oidc-key-string-for-hs256-algorithm
  559. xpack.security.authc.realms.jwt.jwt8.client_authentication.shared_secret: client-shared-secret-string
  560. ----
  561. ===== JWT realm role mapping rule
  562. The following request creates role mappings for {es} in the `jwt8` realm for
  563. the user `principalname1`:
  564. [source,console]
  565. ----
  566. PUT /_security/role_mapping/jwt8_users?refresh=true
  567. {
  568. "roles" : [ "user" ],
  569. "rules" : { "all" : [
  570. { "field": { "realm.name": "jwt8" } },
  571. { "field": { "username": "principalname1" } }
  572. ] },
  573. "enabled": true
  574. }
  575. ----
  576. [[hmac-oidc-example-request-headers]]
  577. ===== Request headers
  578. The following header settings are for an {es} client.
  579. [source,js]
  580. ----
  581. Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJpc3M4IiwiYXVkIjoiYXVkOCIsInN1YiI6InNlY3VyaXR5X3Rlc3RfdXNlciIsImV4cCI6NDA3MDkwODgwMCwiaWF0Ijo5NDY2ODQ4MDB9.UnnFmsoFKfNmKMsVoDQmKI_3-j95PCaKdgqqau3jPMY
  582. ES-Client-Authentication: SharedSecret client-shared-secret-string
  583. ----
  584. // NOTCONSOLE
  585. You can use this header in a `curl` request to make an authenticated call to
  586. {es}. Both the bearer token and the client authorization token must be
  587. specified as separate headers with the `-H` option:
  588. [source,sh]
  589. ----
  590. 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
  591. ----
  592. // NOTCONSOLE
  593. If you used role mapping in the JWT realm, the response includes the user's
  594. `username`, their `roles`, metadata about the user, and the details about the
  595. JWT realm itself.
  596. [source,sh]
  597. ----
  598. {"username":"user2","roles":["jwt_role1"],"full_name":null,"email":"user2@something.example.com",
  599. "metadata":{"jwt_claim_email":"user2@something.example.com","jwt_claim_aud":["es01","es02","es03"],
  600. "jwt_claim_sub":"user2","jwt_claim_iss":"my-issuer"},"enabled":true,"authentication_realm":
  601. {"name":"jwt2","type":"jwt"},"lookup_realm":{"name":"jwt2","type":"jwt"},"authentication_type":"realm"}
  602. ----