Open albertzaharovits opened 3 years ago
Pinging @elastic/es-security (Team:Security)
Some first thoughts to get the discussion going:
(leaving the above for reference, even though I have answered some of my Qs in my head :) )
I thought about this again this morning and I guess my main concerns where regarding how this is framed and not with the technical solution which I summarized in my mind as:
_security/oidc/authenticate
is that in this flow we don't validate the nonce
claim and the state
parameter ( because we can't and because we assume that the caller of the API already did ) oidc_manage
in this case?(Always happy to have a chat about his - I just wanted to write down my thoughts and augment my half-baked response from yesterday)
This solution depends on a facilitator component. I'm not certain if this is actually a disadvantage (compared to a "JWT realm") as I haven't thought through how the JWT realm would work, but I was assuming that we would consume these JWTs as Bearer tokens from an HTTP header and as such the realm would be usable by end users without a facilitator.
I think this is the critical question for the issue. I also had the impression that what users ask for is not partial oidc function, but instead an authentication mechanism that happens to use a JWT as the credentials. With this proposal, the end user will need not only a faciliator to act as RP proxy, but also managing the access/refresh token lifecycle. If I remember correctly, there are users claimed that their system cannot do much other than forward the JWT token in a HTTP header. I think we need to be clear on the exact use case (or cases) that we are trying to cater first before deciding on the approach.
The question of whether the client has the capacity to call APIs to exchange for ES token credentials is the most important point. If they don't, then this feature is not suitable.
This is a proposal to convert a JWT ID token (that contains claims) into an Elasticsearch internal Access Token, by using the OIDC realms, but not really enforcing the OIDC protocol flows.
Preamble
The Elasticsearch OIDC realm, with Kibana as the facilitator, implements the OIDC code flow. Kibana is required because the OIDC flow relies on HTTP Redirects. The code flow is designed for Relying Parties that can keep a secret (the rp.client_secret realm secure setting in the keystore). To obtain the JWT ID token, which contains the user claims, Elasticsearch exchanges a
code
through a secure back-channel with the OP. Thecode
is designed to be un-replay-able and bound to an end user and an RP, and is obtained in the front channel interaction (using the browser), following a successful authentication at the OP.For this purpose, Elasticsearch exposes two APIs, that the Kibana facilitator calls: one to construct the authentication request to submit to the OP (_security/oidc/prepare), and another one that validates the response, which contains the
code
, of the aforementioned request (_security/oidc/authenticate).Implicit flow uses JWTs already
In addition to the code flow, OIDC also standardizes what's called the implicit flow. In the implicit flow, the JWT ID Token is released directly in the front-channel. This is to support serverless Relying Parties (where the client runs in the browser/phone, not on a server). Elasticsearch supports this flow as well: the response to validate by the ES
_security/oidc/authenticate
call will contain the ID Token instead of thecode
. The API returns an Elasticsearch internal Access Token.Therefore there is already a protocol way to exchange JWTs with ES internal Access Tokens. But of course, the protocol must be followed, eg calling the ES
prepare
API, binding thestate
parameter to a cookie and validating that on the response, etc...Proposal
For a more "direct" way to exchange a JWT into an ES token, we could introduce something analogous to the PKI realm delegation. There, we rely on a trusted proxy to perform the authentication as part of the TLS protocol. In the OIDC case, the facilitator actually becomes a full-fledged OIDC RP, and the OIDC realm in ES works in a delegated mode. It trusts that the proxying RP obtained and validated the JWT according to the OIDC flow of choice. Before releasing an access token, the ES OIDC realm, working in a delegated mode (a new realm setting), authenticates (validates signature) and possibly decrypts the JWT and maps the claims to a principal and roles.
Analogous to the POST /_security/delegate_pki there would be a new API and a new cluster privilege to restrict the clients that are trusted in this way.