// Module included in the following assemblies:
//
// assembly-securing-kafka-clients.adoc

[id='con-securing-client-authentication-{context}']
= User authentication

[role="_abstract"]
User authentication is configured using the `authentication` property in `KafkaUser.spec`.
The authentication mechanism enabled for the user is specified using the `type` field.

Supported authentication types:

* `tls` for TLS client authentication
* `tls-external` for TLS client authentication using external certificates
* `scram-sha-512` for SCRAM-SHA-512 authentication

If `tls` or `scram-sha-512` is specified, the User Operator creates authentication credentials when it creates the user.
If `tls-external` is specified, the user still uses TLS client authentication, but no authentication credentials are created.
Use this option when you're providing your own certificates.
When no authentication type is specified, the User Operator does not create the user or its credentials.

You can use `tls-external` to authenticate with TLS client authentication using a certificate issued outside the User Operator.
The User Operator does not generate a TLS certificate or a secret.
You can still manage ACL rules and quotas through the User Operator in the same way as when you're using the `tls` mechanism.
This means that you use the `CN=__USER-NAME__` format when specifying ACL rules and quotas.
_USER-NAME_ is the common name given in a TLS certificate.

[role="_additional-resources"]
.Additional resources

* xref:con-securing-kafka-authentication-{context}[When to use mutual TLS authentication or SCRAM-SHA Authentication authentication for clients]
* xref:type-KafkaUserSpec-reference[`KafkaUserSpec` schema reference]

== TLS client authentication

To use TLS client authentication, you set the `type` field in the `KafkaUser` resource to `tls`.

.Example user with TLS client authentication enabled
[source,yaml,subs="attributes+"]
----
apiVersion: {KafkaUserApiVersion}
kind: KafkaUser
metadata:
  name: my-user
  labels:
    strimzi.io/cluster: my-cluster
spec:
  authentication:
    type: tls
  # ...
----

When the user is created by the User Operator, it creates a new secret with the same name as the `KafkaUser` resource.
The secret contains a private and public key for TLS client authentication.
The public key is contained in a user certificate, which is signed by the client Certificate Authority (CA).

All keys are in X.509 format.

Secrets provide private keys and certificates in PEM and PKCS #12 formats.

For more information on securing Kafka communication with secrets, see xref:security-{context}[].

.Example secret with user credentials
[source,yaml,subs="attributes+"]
----
apiVersion: v1
kind: Secret
metadata:
  name: my-user
  labels:
    strimzi.io/kind: KafkaUser
    strimzi.io/cluster: my-cluster
type: Opaque
data:
  ca.crt: # Public key of the client CA
  user.crt: # User certificate that contains the public key of the user
  user.key: # Private key of the user
  user.p12: # PKCS #12 archive file for storing certificates and keys
  user.password: # Password for protecting the PKCS #12 archive file
----

== TLS client authentication using a certificate issued outside the User Operator

To use TLS client authentication using a certificate issued outside the User Operator, you set the `type` field in the `KafkaUser` resource to `tls-external`.
A secret and credentials are not created for the user.

.Example user with TLS client authentication that uses a certificate issued outside the User Operator
[source,yaml,subs="attributes+"]
----
apiVersion: {KafkaUserApiVersion}
kind: KafkaUser
metadata:
  name: my-user
  labels:
    strimzi.io/cluster: my-cluster
spec:
  authentication:
    type: tls-external
  # ...
----

== SCRAM-SHA-512 authentication

To use the SCRAM-SHA-512 authentication mechanism, you set the `type` field in the `KafkaUser` resource to `scram-sha-512`.

.Example user with SCRAM-SHA-512 authentication enabled
[source,yaml,subs="attributes+"]
----
apiVersion: {KafkaUserApiVersion}
kind: KafkaUser
metadata:
  name: my-user
  labels:
    strimzi.io/cluster: my-cluster
spec:
  authentication:
    type: scram-sha-512
  # ...
----

When the user is created by the User Operator, it creates a new secret with the same name as the `KafkaUser` resource.
The secret contains the generated password in the `password` key, which is encoded with base64.
In order to use the password, it must be decoded.

.Example secret with user credentials
[source,yaml,subs="attributes+"]
----
apiVersion: v1
kind: Secret
metadata:
  name: my-user
  labels:
    strimzi.io/kind: KafkaUser
    strimzi.io/cluster: my-cluster
type: Opaque
data:
  password: Z2VuZXJhdGVkcGFzc3dvcmQ= <1>
  sasl.jaas.config: b3JnLmFwYWNoZS5rYWZrYS5jb21tb24uc2VjdXJpdHkuc2NyYW0uU2NyYW1Mb2dpbk1vZHVsZSByZXF1aXJlZCB1c2VybmFtZT0ibXktdXNlciIgcGFzc3dvcmQ9ImdlbmVyYXRlZHBhc3N3b3JkIjsK <2>
----
<1> The generated password, base64 encoded.
<2> The JAAS configuration string for SASL SCRAM-SHA-512 authentication, base64 encoded.

Decoding the generated password:
----
echo "Z2VuZXJhdGVkcGFzc3dvcmQ=" | base64 --decode
----

=== Custom password configuration

When a user is created, Strimzi generates a random password.
You can use your own password instead of the one generated by Strimzi. To do so, create a secret with the password and reference it in the `KafkaUser` resource.

.Example user with a password set for SCRAM-SHA-512 authentication
[source,yaml,subs="attributes+"]
----
apiVersion: {KafkaUserApiVersion}
kind: KafkaUser
metadata:
  name: my-user
  labels:
    strimzi.io/cluster: my-cluster
spec:
  authentication:
    type: scram-sha-512
    password:
      valueFrom:
        secretKeyRef:
          name: my-secret <1>
          key: my-password <2>
  # ...
----
<1> The name of the secret containing the predefined password.
<2> The key for the password stored inside the secret.
