// Module included in the following assemblies:
//
// assembly-oauth-authentication.adoc

[id='con-oauth-authentication-client-options-{context}']
= OAuth 2.0 client authentication flows

[role="_abstract"]
OAuth 2.0 authentication flows depend on the underlying Kafka client and Kafka broker configuration.
The flows must also be supported by the authorization server used.

The Kafka broker listener configuration determines how clients authenticate using an access token.
The client can pass a client ID and secret to request an access token.

If a listener is configured to use PLAIN authentication, the client can authenticate with a client ID and secret or username and access token.
These values are passed as the `username` and `password` properties of the PLAIN mechanism.

Listener configuration supports the following token validation options:

* You can use fast local token validation based on JWT signature checking and local token introspection, without contacting an authorization server.
The authorization server provides a JWKS endpoint with public certificates that are used to validate signatures on the tokens.
* You can use a call to a token introspection endpoint provided by an authorization server.
Each time a new Kafka broker connection is established, the broker passes the access token received from the client to the authorization server.
The Kafka broker checks the response to confirm whether or not the token is valid.

NOTE: An authorization server might only allow the use of opaque access tokens, which means that local token validation is not possible.

Kafka client credentials can also be configured for the following types of authentication:

* Direct local access using a previously generated long-lived access token
* Contact with the authorization server for a new access token to be issued (using a client ID and a secret, or a refresh token, or a username and a password)

== Example client authentication flows using the SASL OAUTHBEARER mechanism

You can use the following communication flows for Kafka authentication using the SASL OAUTHBEARER mechanism.

* xref:oauth-introspection-endpoint-{context}[Client using client ID and secret, with broker delegating validation to authorization server]
* xref:oauth-jwt-{context}[Client using client ID and secret, with broker performing fast local token validation]
* xref:oauth-token-endpoint-{context}[Client using long-lived access token, with broker delegating validation to authorization server]
* xref:oauth-token-jwt-{context}[Client using long-lived access token, with broker performing fast local validation]

[id='oauth-introspection-endpoint-{context}']
.Client using client ID and secret, with broker delegating validation to authorization server

image:oauth-introspection-endpoint.png[Client using client ID and secret with broker delegating validation to authorization server]

. The Kafka client requests an access token from the authorization server using a client ID and secret, and optionally a refresh token. Alternatively, the client may authenticate using a username and a password.
. The authorization server generates a new access token.
. The Kafka client authenticates with the Kafka broker using the SASL OAUTHBEARER mechanism to pass the access token.
. The Kafka broker validates the access token by calling a token introspection endpoint on the authorization server using its own client ID and secret.
. A Kafka client session is established if the token is valid.

[id='oauth-jwt-{context}']
.Client using client ID and secret, with broker performing fast local token validation

image:oauth-jwt-signature.png[Client using client ID and secret with broker performing fast local token validation]

. The Kafka client authenticates with the authorization server from the token endpoint, using a client ID and secret, and optionally a refresh token. Alternatively, the client may authenticate using a username and a password.
. The authorization server generates a new access token.
. The Kafka client authenticates with the Kafka broker using the SASL OAUTHBEARER mechanism to pass the access token.
. The Kafka broker validates the access token locally using a JWT token signature check, and local token introspection.

[id='oauth-token-endpoint-{context}']
.Client using long-lived access token, with broker delegating validation to authorization server

image:oauth-introspection-endpoint-long-token.png[Client using long-lived access token with broker delegating validation to authorization server]

. The Kafka client authenticates with the Kafka broker using the SASL OAUTHBEARER mechanism to pass the long-lived access token.
. The Kafka broker validates the access token by calling a token introspection endpoint on the authorization server, using its own client ID and secret.
. A Kafka client session is established if the token is valid.

[id='oauth-token-jwt-{context}']
.Client using long-lived access token, with broker performing fast local validation

image:oauth-jwt-signature-token.png[Client using long-lived access token with broker performing fast local validation]

. The Kafka client authenticates with the Kafka broker using the SASL OAUTHBEARER mechanism to pass the long-lived access token.
. The Kafka broker validates the access token locally using a JWT token signature check and local token introspection.

WARNING: Fast local JWT token signature validation is suitable only for short-lived tokens as there is no check with the authorization server if a token has been revoked.
Token expiration is written into the token, but revocation can happen at any time, so cannot be accounted for without contacting the authorization server.
Any issued token would be considered valid until it expires.

== Example client authentication flows using the SASL PLAIN mechanism

You can use the following communication flows for Kafka authentication using the OAuth PLAIN mechanism.

* xref:oauth-plain-client-id-{context}[Client using a client ID and secret, with the broker obtaining the access token for the client]
* xref:oauth-plain-access-token-{context}[Client using a long-lived access token without a client ID and secret]

[id='oauth-plain-client-id-{context}']
.Client using a client ID and secret, with the broker obtaining the access token for the client

image:oauth-plain-client-id.png[Client using a client ID and secret with the broker obtaining the access token for the client]

. The Kafka client passes a `clientId` as a username and a `secret` as a password.
. The Kafka broker uses a token endpoint to pass the `clientId` and `secret` to the authorization server.
. The authorization server returns a fresh access token or an error if the client credentials are not valid.
. The Kafka broker validates the token in one of the following ways:
.. If a token introspection endpoint is specified, the Kafka broker validates the access token by calling the endpoint on the authorization server.
A session is established if the token validation is successful.
.. If local token introspection is used, a request is not made to the authorization server.
The Kafka broker validates the access token locally using a JWT token signature check.

[id='oauth-plain-access-token-{context}']
.Client using a long-lived access token without a client ID and secret

image:oauth-plain-access-token.png[Client using a long-lived access token without a client ID and secret]

. The Kafka client passes a username and password. The password provides the value of an access token that was obtained manually and configured before running the client.
. The password is passed with or without an `$accessToken:` string prefix depending on whether or not the Kafka broker listener is configured with a token endpoint for authentication.
.. If the token endpoint is configured, the password should be prefixed by `$accessToken:` to let the broker know that the password parameter contains an access token rather than a client secret. The Kafka broker interprets the username as the account username.
.. If the token endpoint is not configured on the Kafka broker listener (enforcing a `no-client-credentials mode`), the password should provide the access token without the prefix. The Kafka broker interprets the username as the account username.
In this mode, the client doesn't use a client ID and secret, and the `password` parameter is always interpreted as a raw access token.
. The Kafka broker validates the token in one of the following ways:
.. If a token introspection endpoint is specified, the Kafka broker validates the access token by calling the endpoint on the authorization server. A session is established if token validation is successful.
.. If local token introspection is used, there is no request made to the authorization server. Kafka broker validates the access token locally using a JWT token signature check.
