// Module included in the following module:
//
// proc-oauth-authorization-broker-config.adoc

[id='con-oauth-authorization-keycloak-authorization-services_{context}']
= Managing policies and permissions in Keycloak Authorization Services

This section describes the mappings between the Kafka authorization model and Keycloak Authorization Services model.
The mappings are used in granting permissions to access Kafka.

== Kafka authorization model for resources

The link:https://kafka.apache.org/documentation/#security_authz_primitives[Kafka authorization model] defines resource types, and the permissions available for each type.
When an action is performed by a Kafka client on a broker, the broker uses a configured authorizer to check permissions, depending on the action performed and the resource type.

Kafka has five resource types for controlling access: `Topic`, `Group`, `Cluster`, `TransactionalId`, `DelegationToken`.

Each resource type has different permissions:

Topic:

* `Create`
* `Write`
* `Read`
* `Delete`
* `Describe`
* `DescribeConfigs`
* `Alter`
* `AlterConfigs`

Group:

* `Read`
* `Describe`
* `Delete`

Cluster:

*  `Create`
*  `Describe`
*  `Alter`
*  `DescribeConfigs`
*  `AlterConfigs`
*  `IdempotentWrite`
*  `ClusterAction`

TransactionalId:

*  `Describe`
*  `Write`

DelegationToken:

* `Describe`

[id='con-oauth-authorization-services-model-{context}']
== Keycloak Authorization Services model for managing permissions

Keycloak Authorization Services use four concepts to define and grant permissions: _resources_, _authorization scopes_, _policies_, and _permissions_.

Resources:: Resources are a set of resource definitions that are used to match permitted actions.
For example, a resource can be an individual topic, or it can be a set of all topics with names that start with the same prefix.
The resource definition has a set of available authorization scopes associated with it, which represent a set of all actions available on the particular resource.
Often, only a subset of these actions is actually permitted.

Authorization scopes:: Authorization scopes is simply a set of all available actions on all the different resource types. When defining a new resource,  scopes are added from the set of all scopes.

Policies:: Policies are rules that use criteria to match a list of accounts. Policies can match service accounts based on client id or roles, or user accounts based on username, groups, or roles.

Permissions:: Permissions grant a subset of authorization scopes on a specific resource definition to a set of users.

== Mapping Keycloak Authorization Services to the Kafka authorization model

Use Keycloak Authorization Services rules on the OAuth client that represents the Kafka Broker to grant Kafka permissions to users or service accounts. Typically, the OAuth client has `kafka` as its client id.

The OAuth 2.0 client definition must have the _Authorization Enabled_ option activated.

All permissions exist within the scope of this OAuth 2.0 client, which means that if you have different Kafka clusters configured with different OAuth 2.0 client IDs they would each have a separate set of permissions even though they are part of the same realm.

When the Kafka client use the _SASL OAUTHBEARER_ mechanism, the Keycloak authorizer (`KeycloakAuthorizer`) retrieves the list of grants for the current session from the Keycloak server using the access token of the current session.
This list of grants is the result of evaluating the Keycloak Authorization Services policies and permissions.

.Introducing authorization scopes

Typically, an initial configuration involves uploading the authorization scopes to create a list of all the possible actions that can be performed on all the Kafka resource types.
This step is performed only once, before defining any permissions. Alternatively, you can add authorization scopes manually.

The authorization scopes should contain all the possible Kafka permissions regardless of the resource type:

* `Create`
* `Write`
* `Read`
* `Delete`
* `Describe`
* `Alter`
* `DescribeConfig`
* `AlterConfig`
* `ClusterAction`
* `IdempotentWrite`

.Defining resource patterns for permission checks

The resources use pattern names for pattern matching against the targeted resources when performing permission checks.

The general pattern is `__RESOURCE-TYPE:PATTERN-NAME__`.

The resource types mirror the Kafka authorization model.
The pattern allows for the two matching options: exact matching (when the pattern does not end with `\*`), and prefix matching (when the pattern ends with `*`).

.Example patterns for resources
    Topic:my-topic
    Topic:orders-*
    Group:orders-*
    Cluster:*

In addition, the general pattern can be prefixed by `kafka-cluster:__CLUSTER-NAME__` followed by a comma, where the cluster name refers to the `metadata.name` in the Kafka custom resource.

.Example patterns for resources with cluster prefix
    kafka-cluster:my-cluster,Topic:*
    kafka-cluster:*,Group:b_*

When the `kafka-cluster` prefix is not present it is assumed to be `kafka-cluster:*`.

When defining a resource, you can associate a list of possible authorization scopes relevant to the resource.
Set whatever actions make sense for the targeted resource type.

While you may add any authorization scope to any resource, only the scopes supported by the resource type are considered for access control.

.Policies

Policies are used to target permissions to one or more accounts.
Targeting can refer to:

* Specific user or service accounts
* Realm roles or client roles
* User groups
* JavaScript rule to match a client IP address

A policy is given a unique name, and can be reused to target multiple permissions to multiple resources.

.Defining permissions based on scopes, resources and policies

Use fine-grained permissions to pull together the policies, resources, and authorization scopes that grant access to users.

The name of each permission should clearly define what permissions it grants to which users.

For more information on how to configure permissions through Keycloak Authorization Services, see xref:proc-oauth-authorization-keycloak-example_str[the authorization example].


== Example permissions required for operations on Kafka

The following  examples demonstrate the user permissions required for performing common operations on Kafka.

.Creating a topic

To create a topic, the `Create` permission is required for the specific topic, or for `Cluster:kafka-cluster`.

[source,shell]
----
bin/kafka-topics.sh --create --topic my-topic \
  --bootstrap-server my-cluster-kafka-bootstrap:9092 --command-config=/tmp/config.properties
----

.Listing the topic

If a user has `Describe` permission on the topic, the topic is listed.

[source,shell]
----
bin/kafka-topics.sh --list \
  --bootstrap-server my-cluster-kafka-bootstrap:9092 --command-config=/tmp/config.properties
----

.Displaying the topic details

To display topic details, `Describe` and `DescribeConfigs` permissions are required on the topic.

[source,shell]
----
bin/kafka-topics.sh --describe --topic my-topic \
  --bootstrap-server my-cluster-kafka-bootstrap:9092 --command-config=/tmp/config.properties
----

.Producing to the topic

To produce to the topic, `Describe` and `Write` permissions are required on the topic.
If topic has not yet been created, and autocreation is enabled, the permissions to create the topic are required.

[source,shell]
----
bin/kafka-console-producer.sh  --topic my-topic \
  --bootstrap-server my-cluster-kafka-bootstrap:9092 --producer.config=/tmp/config.properties
----

.Consuming from the topic

To consume from the topic, `Describe` and `Read` permissions are required on the topic.
Consuming from the topic normally relies on storing the consumer offsets in a consumer group,
which requires additional `Describe` and `Read` permissions on the consumer group.

Two `resources` are needed for matching. For example:
----
Topic:my-topic
Group:my-group-*
----

[source,shell]
----
bin/kafka-console-consumer.sh --topic my-topic --group my-group-1 --from-beginning \
  --bootstrap-server my-cluster-kafka-bootstrap:9092 --consumer.config /tmp/config.properties
----

.Producing to the topic using an idempotent producer

Besides needing the permissions for standard producing to the topic, an additional `IdempotentWrite` permission is required on the `Cluster` resource.

Two `resources` are needed for matching. For example:

----
Topic:my-topic
Cluster:kafka-cluster
----

.Listing consumer groups

When listing consumer groups, only the groups on which the user has `Describe` permissions are returned.
Alternatively, if the user has `Describe` permission on the `Cluster:kafka-cluster`, all the consumer groups are returned.

[source,shell]
----
bin/kafka-consumer-groups.sh --list \
  --bootstrap-server my-cluster-kafka-bootstrap:9092 --command-config=/tmp/config.properties
----

.Displaying the consumer group details

To display the consumer group details, `Describe` permission is required on the group, and on the topic associated with the group.

[source,shell]
----
bin/kafka-consumer-groups.sh --describe --group my-group-1 \
  --bootstrap-server my-cluster-kafka-bootstrap:9092 --command-config=/tmp/config.properties
----

.Changing the topic configuration

To change the topic configuration, `Describe` and `Alter` permissions are required on the topic.

[source,shell]
----
bin/kafka-topics.sh --alter --topic my-topic --partitions 2 \
  --bootstrap-server my-cluster-kafka-bootstrap:9092 --command-config=/tmp/config.properties
----

.Displaying the Kafka broker configuration

To be able to use `kafka-configs.sh` to get the broker configuration, `DescribeConfigs` permission is required on the `Cluster:kafka-cluster`.

[source,shell]
----
bin/kafka-configs.sh --entity-type brokers --entity-name 0 --describe --all \
  --bootstrap-server my-cluster-kafka-bootstrap:9092 --command-config=/tmp/config.properties
----

.Changing the Kafka broker configuration

To change the Kafka broker configuration, `DescribeConfigs` and `AlterConfigs` permissions are required on `Cluster:kafka-cluster`.

[source,shell]
----
bin/kafka-configs --entity-type brokers --entity-name 0 --alter --add-config log.cleaner.threads=2 \
  --bootstrap-server my-cluster-kafka-bootstrap:9092 --command-config=/tmp/config.properties
----

.Deleting a topic

To delete the topic, `Describe` and `Delete` permissions are required on the topic.

[source,shell]
----
bin/kafka-topics.sh --delete --topic my-topic \
  --bootstrap-server my-cluster-kafka-bootstrap:9092 --command-config=/tmp/config.properties
----

.Selecting a leader partition

To run leader selection for topic partitions, `Alter` permission is required on the `Cluster:kafka-cluster`.

[source,shell]
----
bin/kafka-leader-election.sh --topic my-topic --partition 0 --election-type PREFERRED  /
  --bootstrap-server my-cluster-kafka-bootstrap:9092 --admin.config /tmp/config.properties
----

.Reassigning partitions

To generate a partition reassignment file, `Describe` permissions are required on the topics involved.

[source,shell]
----
bin/kafka-reassign-partitions.sh --topics-to-move-json-file /tmp/topics-to-move.json --broker-list "0,1" --generate \
  --bootstrap-server my-cluster-kafka-bootstrap:9092 --command-config /tmp/config.properties > /tmp/partition-reassignment.json
----

To execute the partition reassignment, `Describe` and `Alter` permissions are required on `Cluster:kafka-cluster`, and `Describe` permissions are required on the topics involved.

[source,shell]
----
bin/kafka-reassign-partitions.sh --reassignment-json-file /tmp/partition-reassignment.json --execute \
  --bootstrap-server my-cluster-kafka-bootstrap:9092 --command-config /tmp/config.properties
----

To verify partition reassignment, `Describe`, and `AlterConfigs` permissions are required on `Cluster:kafka-cluster`,
and on each of the topics involved.

[source,shell]
----
bin/kafka-reassign-partitions.sh --reassignment-json-file /tmp/partition-reassignment.json --verify \
  --bootstrap-server my-cluster-kafka-bootstrap:9092 --command-config /tmp/config.properties
----
