<a id="ksql-rbac"></a>

# Deploy Secure ksqlDB with RBAC in Confluent Platform

ksqlDB supports [role-based access control (RBAC)](overview.md#rbac-overview) to cluster resources.

#### NOTE
ksqlDB supports RBAC to provide authorization to ksqlDB clusters when running
in interactive mode. RBAC for users isn’t used in ksqlDB clusters that are
deployed in headless mode.

Use the [Confluent CLI](https://docs.confluent.io/confluent-cli/current/command-reference/iam/rbac/role-binding/confluent_iam_rbac_role-binding_create.html) or
[Control Center](/control-center/current/security/c3-rbac-manage-roles-ui.html) to create roles for users.

You need the cluster ID of the Kafka cluster, the service ID of the ksqlDB
cluster, and the cluster ID of the Schema Registry cluster, if your topics have Avro,
Protobuf, or JSON_SR schemas. For more information, see [Cluster Identifiers in Confluent Platform](rbac-get-cluster-ids.md#rbac-get-cluster-ids).

#### SEE ALSO
To get started, try the [automated RBAC example](cp-rbac-example.md#rbac-demo) that showcases the RBAC
functionality in Confluent Platform.

## ksqlDB service principal

ksqlDB applications run with the roles granted to a privileged *ksqlDB user*
service principal. By default, the ksqlDB service principal is named “ksql”. The roles granted to
the ksqlDB service principal by default are required to run ksqlDB and are distinct from
the roles granted to an interactive user who wants to connect and contribute
to ksqlDB.

When you grant roles to an interactive user, you must also grant the same roles
to the ksqlDB user service principal. ksqlDB applications execute user commands as the ksqlDB
service principal in the background and on other servers in the ksqlDB cluster, and some
ksqlDB statements start long-running persistent queries. ksqlDB checks that the
interactive user has the required permissions to access any resources required,
but the query itself runs in the security context of the ksqlDB service principal. For
this reason, it’s important that both the interactive user and the ksqlDB
service principal have the correct permissions to all resources required by any ksqlDB
statements.

The following example commands show how to grant an interactive user and the
ksqlDB service principal read-only access to a topic. To grant these roles, you must be
logged in to the Confluent CLI with sufficient permissions, for example as
`UserAdmin` or `ResourceOwner`.

```bash
# Grant read-only access for a user to a topic.
confluent iam rbac role-binding create \
  --principal User:<user-name> \
  --role DeveloperRead \
  --resource Topic:<topic-name> \
  <kafka-id>

# Grant read-only access for the ksql service principal to a topic.
confluent iam rbac role-binding create \
  --principal User:ksql \
  --role DeveloperRead \
  --resource Topic:<topic-name> \
  <kafka-id>
```

## Configure ksqlDB Server for RBAC

Assign the following configuration settings in the ksqlDB Server properties
file to enable ksqlDB in an [RBAC environment](../../../kafka/configure-mds/mds-configuration.md#mds-configuration-options).

To access the Confluent security service, you must generate a public/private
key pair. Specify the path to the public key file by assigning the
`public.key.path` setting. For more information, see [Configure Metadata Service (MDS) in Confluent Platform](../../../kafka/configure-mds/index.md#rbac-mds-config).

Append the following settings to the ksqlDB Server configuration file, which by
default is named `${CONFLUENT_HOME}/etc/ksqldb/ksql-server.properties`.

```properties
#------ External service configuration -------

# The set of Kafka brokers to bootstrap Kafka cluster information from
bootstrap.servers=<kafka-hostname>:9092

# Schema Registry authentication
ksql.schema.registry.url=http://<sr-hostname>:8081
# Credentials for accessing Schema Registry
ksql.schema.registry.basic.auth.user.info=<ksql-user>:<ksql-user-password>

############ ksqlDB security settings for Confluent RBAC ######################

# Set the ksqlDB cluster ID to work on specific roles and permissions for this ksqlDB cluster scope.
ksql.service.id=<ksql-cluster-id>

# Enable the ksqlDB Confluent security plugin.
ksql.security.extension.class=io.confluent.ksql.security.KsqlConfluentSecurityExtension

# Enable permissions validations used for persistent queries requests.

# By default, this setting is set to 'auto', but DESCRIBE_CONFIGS ACLs on the Kafka cluster are required for the client user.
ksql.access.validator.enable=on

# Assign the metadata URL and access credentials, which are shared by authentication security handlers and the ksqlDB security extension.
# May be the same as the Kafka cluster hostname.
confluent.metadata.bootstrap.server.urls=http://<metadata-server-hostname>:8090
confluent.metadata.http.auth.credentials.provider=BASIC
# Credentials for accessing the metadata server
confluent.metadata.basic.auth.user.info=<ksql-user>:<ksql-user-password>

# Enable ksqlDB Basic+Bearer authentication.
ksql.authentication.plugin.class=io.confluent.ksql.security.VertxBearerOrBasicAuthenticationPlugin

# Assign credentials for Kafka access.
# These settings may vary, depending on your Kafka cluster authentication settings.
security.protocol=SASL_PLAINTEXT
sasl.mechanism=OAUTHBEARER
sasl.login.callback.handler.class=io.confluent.kafka.clients.plugins.auth.token.TokenUserLoginCallbackHandler
# Credentials for the ksqlDB user, which has the default user name of "ksql".
# These credentials authorize ksqlDB Server to access the Kafka cluster.
sasl.jaas.config=org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required \
    metadataServerUrls="http://<metadata-server-hostname>" username="<ksql-user>" password="<ksql-user-password>";
```

Save the file and restart ksqlDB Server.

Log in to the server by using the ksqlDB CLI.

```bash
ksql --config-file <path_to_config_file> https://<ksqldb_server>:<port> --user <username> --password <password>
```

RBAC for ksqlDB depends on the Confluent Platform [Metadata Service (MDS)](overview.md#metadata-service)
and the Confluent Server Authorizer. The `confluent.metadata` settings configure the Metadata
Service. The `ksql.security.extension.class` setting configures ksqlDB for the
Confluent Server Authorizer. For more information, see [Configure Confluent Server Authorizer in Confluent Platform](../../csa-introduction.md#confluent-server-authorizer).

Use the ksqlDB service principal credentials for the following settings.

- `sasl.jaas.config` for authorizing to the Kafka cluster with Confluent Server Authorizer
- `confluent.metadata.basic.auth.user.info` for authorizing to MDS
- `ksql.schema.registry.basic.auth.user.info` for authorizing to Schema Registry

#### NOTE
When RBAC is enabled and the Schema Registry `/permissions` endpoint is reachable,
ksqlDB checks whether SQL statements have permissions to access Schema Registry schemas.
The `ksql.security.extension.sr-permissions.validator.enabled` config
controls whether this check occurs. The default is `true`.

For additional configurations available to any client communicating with MDS,
see [REST client configurations](../../../kafka/configure-mds/mds-configuration.md#rest-client-mds-config) in the Confluent Platform Security documentation.

## Assign roles for ksqlDB access

The following section defines the minimal set of roles and resources required
for a user to connect to ksqlDB and execute SQL statements, including transient
queries.

As a best practice for security, give users the minimum necessary access level
to resources. For example, prefer granting an interactive user the
`DeveloperRead` role over the `ResourceOwner` role for reading from a topic.

#### IMPORTANT
Users require permissions in Kafka to use any ksqlDB statements that attempt
to read, write, list, and create topics. Additional access to resources on
the Kafka cluster and Schema Registry must be granted explicitly. For more information,
see [Grant a user access to resources](#config-security-ksql-grant-access).

To grant these roles, you must be logged in to the Confluent CLI as a
`UserAdmin`, `ResourceOwner`, or other role with sufficient permissions.

## ksqlDB role mappings

The following table shows the permitted ksqlDB operations for each RBAC role.

| Role            | Access a ksqlDB cluster   | Terminate a ksqlDB cluster   | Modify access to ksqlDB clusters   | View access from a ksqlDB cluster   |
|-----------------|---------------------------|------------------------------|------------------------------------|-------------------------------------|
| SystemAdmin     | Yes                       | Yes                          | Yes                                | Yes                                 |
| UserAdmin       | No                        | No                           | Yes                                | Yes                                 |
| ClusterAdmin    | Yes                       | Yes                          | No                                 | No                                  |
| Operator        | No                        | No                           | No                                 | No                                  |
| SecurityAdmin   | No                        | No                           | No                                 | Yes                                 |
| ResourceOwner   | Yes                       | Yes                          | Yes                                | No                                  |
| DeveloperRead   | No                        | No                           | No                                 | No                                  |
| DeveloperWrite  | Yes                       | No                           | No                                 | No                                  |
| DeveloperManage | No                        | Yes                          | No                                 | No                                  |

## Cluster identifiers

To create role bindings, you need the cluster identifiers for the components in
your Confluent Platform deployment. For more information, see [Cluster Identifiers in Confluent Platform](rbac-get-cluster-ids.md#rbac-get-cluster-ids).

The following commands use these environment variables for the cluster IDs.
Variables for the interactive user name and topic name are also defined.

```bash
# Cluster identifiers
export KAFKA_ID=<kafka-cluster-id>
export KSQLDB_ID=<ksql-cluster-id>
export SR_ID=<schema-registry-cluster-id>

# The name of the interactive user and
# the name of a topic for the user to access.
export USER_NAME=<interactive-user-name>
export TOPIC_NAME=<kafka-topic-name>
```

<a id="ksql-rbac-register-cluster"></a>

## Use a registered cluster name

You can register your ksqlDB cluster and specify a user-friendly cluster name,
which enables creating role bindings more easily. In all of the following example
commands, you can use the cluster name instead of $KAFKA_ID and $KSQLDB_ID. For
more information, see [Cluster Registry in Confluent Platform](../../cluster-registry.md#cluster-registry).

For example, you can update the following command:

```bash
 confluent iam rbac role-binding create \
   --principal User:<cluster-owner-name> \
   --role ResourceOwner \
   $KAFKA_ID \
   --ksql-cluster-id $KSQLDB_ID \
   --resource KsqlCluster:ksql-cluster
```

Assuming your ksqlDB cluster has been registered in cluster registry with
$KAFKA_ID and $KSQLDB_ID, you can use the user-friendly name instead of the IDs.
Update the previous command by using the registered cluster name, which in this
example is `<ksqldb-cluster-name>`:

```bash
 confluent iam rbac role-binding create \
   --principal User:<cluster-owner-name> \
   --role ResourceOwner \
   --cluster-name <ksqldb-cluster-name>
   --resource KsqlCluster:ksql-cluster
```

<a id="ksql-rbac-assign-startup-roles"></a>

## Assign roles for starting ksqlDB Server

To start ksqlDB Server and connect to a secured Kafka cluster, a user must have
the following roles granted by a `UserAdmin`.

### ksqlDB cluster scope

Run the following commands to assign the `ResourceOwner` role on the ksqlDB
cluster, which binds ownership of the ksqlDB cluster’s resources to the user.
A user who has the `ResourceOwner` or `ClusterAdmin` role on a ksqlDB cluster
is a *cluster owner*.

```bash
confluent iam rbac role-binding create \
  --principal User:<cluster-owner-name> \
  --role ResourceOwner \
  $KAFKA_ID \
  --ksql-cluster-id $KSQLDB_ID \
  --resource KsqlCluster:ksql-cluster

confluent iam rbac role-binding create \
  --principal User:<cluster-owner-name> \
  --role SecurityAdmin \
  $KAFKA_CLUSTER_ID \
  --ksql-cluster-id $KSQLDB_ID
```

Run the following command to assign the `ResourceOwner` role to the ksqlDB
service principal.

```bash
confluent iam rbac role-binding create \
  --principal User:ksql \
  --role ResourceOwner \
  $KAFKA_ID \
  --ksql-cluster-id $KSQLDB_ID \
  --resource KsqlCluster:ksql-cluster
```

### Kafka cluster scope

Grant the `ResourceOwner` role to the ksqlDB service principal on the following internal
ksqlDB resources. By default, these roles are granted to the ksqlDB user named
“ksql”.

- ksqlDB command topic: `_confluent-ksql-${KSQLDB_ID}_command_topic`
- ksqlDB processing log topic: `${KSQLDB_ID}ksql_processing_log`
- Consumer groups: Prefixed with `_confluent-ksql-${KSQLDB_ID}`

#### IMPORTANT
Only grant access to the ksqlDB command topic *for accounts that have
administrator roles*. Granting access to non-admin accounts can result in a
lower-privileged RBAC user being able to escalate privileges to a
`ClusterAdmin`-like level on the associated ksqlDB cluster within the
same Organization boundary.

Also, grant the `DeveloperWrite` role to the ksqlDB service principal on the
`Transactional-Id` resource.

- `Transactional-Id` resource: `--resource Transactional-Id:${KSQLDB_ID}`

Use the following command to grant full access for the ksqlDB service principal to the
ksqlDB command topic.

```bash
# Grant full access for the ksql service principal to the ksqlDB command topic.
confluent iam rbac role-binding create \
  --principal User:ksql \
  --role ResourceOwner \
  --resource Topic:_confluent-ksql-${KSQLDB_ID}_command_topic \
  $KAFKA_ID
```

Use the following command to grant full access for the ksqlDB service principal to the
ksqlDB processing log topic.

```bash
# Grant full access for the ksql service principal to the ksqlDB processing log topic.
confluent iam rbac role-binding create \
  --principal User:ksql \
  --role ResourceOwner \
  --resource Topic:${KSQLDB_ID}ksql_processing_log \
  $KAFKA_ID
```

Use the following command to grant `DeveloperWrite` access for the ksqlDB
service principal to the `Transactional-Id` resource.

```bash
# Grant DeveloperWrite access for the ksql service principal to the Transactional-Id resource.
confluent iam rbac role-binding create \
  --principal User:ksql \
  --role DeveloperWrite \
  --resource Transactional-Id:${KSQLDB_ID} \
  $KAFKA_ID
```

Use the following command to grant full access for the ksql user to the
ksqlDB consumer groups.

```bash
# Grant full access for the ksql service principal to the ksqlDB consumer groups.
confluent iam rbac role-binding create \
  --principal User:ksql \
  --role ResourceOwner \
  --resource Group:_confluent-ksql-${KSQLDB_ID} \
  --prefix \
  $KAFKA_ID
```

## Assign role for idempotent producers

To enable idempotent producers and exactly-once semantics (EOS), the ksqlDB
service principal requires `Write` access to the Kafka cluster.

#### NOTE
Any principal used by idempotent producers must be authorized
as `Write` on the cluster. Binding either the `DeveloperWrite`
or `ResourceOwner` RBAC roles on the Kafka cluster grants `Write`
permission, but `DeveloperWrite` is the less permissive of the two roles
and is the first recommendation. Consume does not require additional Kafka
permissions to be idempotent consumers.

The following role binding ensures that `Write` has access to the
cluster:

```bash
# Grant Write access for the ksql service principal to the cluster.
confluent iam rbac role-binding create \
  --principal User:ksql \
  --role DeveloperWrite \
  --resource Cluster:kafka-cluster \
  $KAFKA_ID

# Grant Write access for the ksql service principal to the Transactional-Id resource.
confluent iam rbac role-binding create \
  --principal User:ksql \
  --role DeveloperWrite \
  --resource Transactional-Id:${KSQLDB_ID} \
  --prefix \
  $KAFKA_ID
```

## Assign roles for terminating a ksqlDB cluster

To terminate a ksqlDB cluster by calling the REST endpoint at `/ksql/terminate`,
a user must have the `DeveloperManage` role granted by a `UserAdmin`. For
more information, see [Terminate a cluster](../../../ksqldb/developer-guide/ksqldb-rest-api/terminate-endpoint.md#ksqldb-rest-api-terminate-endpoint).

### ksqlDB cluster scope

Use the following command to assign a `DeveloperManage` role on the ksqlDB
cluster.

```bash
confluent iam rbac role-binding create \
    --principal User:<cluster-owner-name> \
    --role DeveloperManage \
    $KAFKA_ID \
    --ksql-cluster-id $KSQLDB_ID \
    --resource KsqlCluster:ksql-cluster
```

<a id="ksql-rbac-assign-roles-to-contribute"></a>

## Assign roles for contributing to a ksqlDB application

To access the ksqlDB cluster for development, an interactive user must have the
following roles.

### ksqlDB cluster scope

Use the following command to assign the `DeveloperWrite` role on the ksqlDB
cluster.

```bash
# Grant write access for a user to resources on the ksqlDB cluster.
confluent iam rbac role-binding create \
    --principal User:$USER_NAME \
    --role DeveloperWrite \
    $KAFKA_ID \
    --ksql-cluster-id $KSQLDB_ID \
    --resource KsqlCluster:ksql-cluster
```

### Kafka cluster scope

Use the following command to assign the `DeveloperRead` role on the internal
consumer groups for transient queries.

```bash
# Grant read-only access for a user to the ksqlDB consumer groups.
confluent iam rbac role-binding create \
  --principal User:$USER_NAME \
  --role DeveloperRead \
  --resource Group:_confluent-ksql-${KSQLDB_ID} \
  --prefix \
  $KAFKA_ID
```

Assign the following role if the interactive user needs access to the ksqlDB
processing log.

```bash
# Grant access for a user to the processing log.
confluent iam rbac role-binding create \
  --principal User:$USER_NAME \
  --role DeveloperRead \
  --resource Topic:${KSQLDB_ID}ksql_processing_log \
  $KAFKA_CLUSTER_ID
```

<a id="config-security-ksql-grant-access"></a>

## Grant a user access to resources

In addition to the minimum necessary roles, an interactive user needs roles to
access specific resources like topics, consumer groups, and subjects.

#### IMPORTANT
When you grant roles to a user, remember to grant the same roles to the
ksqlDB service principal, which is named “ksql” by default.

### Prefixed resource names

Use the `prefix` option in the Confluent CLI to grant access to all
resources with names that start with the specified prefix string. For example,
to grant read-only access to all topics that start with `<topic-name-prefix->`,
you could use the following command.

```bash
# Grant read-only access for a user to a topic.
confluent iam rbac role-binding create \
  --principal User:$USER_NAME \
  --role DeveloperRead \
  --resource Topic:<topic-name-prefix-> \
  --prefix \
  $KAFKA_ID
```

### Roles for accessing topics, streams, and tables

Use the following Confluent CLI commands to give an interactive user the
necessary roles for creating streams and table.

SHOW or PRINT a topic
: - `ResourceOwner` role on the Kafka topic
  - `DeveloperRead` role on the Schema Registry subject, if the topic has an Avro,
    Protobuf, or JSON_SR schema
  <br/>
  This role enables an interactive user to display the specified topic by using
  the SHOW and PRINT statements. Also, users can CREATE streams and tables from
  these topics.
  <br/>
  The ksqlDB service principal doesn’t need a role on the topic for these statements.
  <br/>
  #### NOTE
  The subject’s name is the topic’s name appended with `-value`.
  <br/>
  ```bash
  # Grant read-only access for a user to read a topic.
  confluent iam rbac role-binding create \
    --principal User:$USER_NAME \
    --role ResourceOwner \
    --resource Topic:$TOPIC_NAME \
    $KAFKA_ID
  ```
  <br/>
  ```bash
  # Grant read-only access for a user to read a subject.
  confluent iam rbac role-binding create \
    --principal User:$USER_NAME \
    --role DeveloperRead \
    --resource Subject:${TOPIC_NAME}-value
    $KAFKA_ID \
    --schema-registry-cluster $SR_ID
  ```

SELECT from a stream or table
: - `ResourceOwner` role on the source topic
  - `DeveloperRead` role on the `_confluent-ksql-${KSQLDB_ID}` consumer group
  - `ResourceOwner` role on the `_confluent-ksql-${KSQLDB_ID}transient`
    transient topics, for tables
  - `DeveloperRead` role on the Schema Registry subject, if the topic has an Avro,
    Protobuf, or JSON_SR schema
  - `ResourceOwner` role on the `_confluent-ksql-<cluster-id>transient*`
    subjects, for tables that use Avro (not required for streams)
  <br/>
  These roles enable a user to read from a stream or a table by using the
  SELECT statement. If a SELECT statement contains a JOIN that uses an
  unauthorized topic, the SELECT fails with an authorization error.
  <br/>
  ```bash
  # Grant read-only access for a user to read a topic.
  confluent iam rbac role-binding create \
    --principal User:$USER_NAME \
    --role ResourceOwner \
    --resource Topic:$TOPIC_NAME \
    $KAFKA_ID
  ```
  <br/>
  ```bash
  # For tables: grant access to the transient query topics.
  # This is a limitation of ksqlDB tables. Giving this permission to
  # the prefixed topics lets the user view tables from other queries.
  confluent iam rbac role-binding create \
    --principal User:$USER_NAME \
    --role ResourceOwner \
    --resource Topic:_confluent-ksql-${KSQLDB_ID}transient \
    --prefix \
    $KAFKA_CLUSTER_ID
  <br/>
  # For tables that use Avro: grant access to the transient subjects.
  confluent iam rbac role-binding create \
    --principal User:$USER_NAME \
    --role ResourceOwner \
    --resource Subject:_confluent-ksql-${KSQLDB_ID}transient \
    --prefix \
    $KAFKA_CLUSTER_ID \
    --schema-registry-cluster $SR_ID
  ```
  <br/>
  ```bash
  # Grant read-only access for a user to read from a consumer group.
  confluent iam rbac role-binding create \
    --principal User:$USER_NAME \
    --role DeveloperRead \
    --resource Group:_confluent-ksql-${KSQLDB_ID} \
    --prefix \
    $KAFKA_ID
  ```
  <br/>
  ```bash
  # Grant read-only access for a user to read a subject.
  confluent iam rbac role-binding create \
    --principal User:$USER_NAME \
    --role DeveloperRead \
    --resource Subject:${TOPIC_NAME}-value
    $KAFKA_ID \
    --schema-registry-cluster $SR_ID
  ```

Write to a topic with INSERT
: - `DeveloperWrite` role on the Kafka topic
  - `ResourceOwner` or `DeveloperWrite` role on the Schema Registry subject,
    if the topic has an Avro, Protobuf, or JSON_SR schema
  <br/>
  These roles enable a user to write data by using INSERT statements.
  The INSERT INTO statement contains a SELECT clause that requires the user
  to have read permissions on the topic in the query.
  <br/>
  ```bash
  # Grant write access for a user to a topic.
  confluent iam rbac role-binding create \
    --principal User:$USER_NAME \
    --role DeveloperWrite \
    --resource Topic:$TOPIC_NAME \
    $KAFKA_ID
  ```
  <br/>
  ```bash
  # Grant full access for a user to create a subject and write to it.
  confluent iam rbac role-binding create \
    --principal User:$USER_NAME \
    --role ResourceOwner \
    --resource Subject:${TOPIC_NAME}-value
    $KAFKA_ID \
    --schema-registry-cluster $SR_ID
  ```

CREATE STREAM
: - `ResourceOwner` role on the source topic
  - `DeveloperRead` role on the `_confluent-ksql-${KSQLDB_ID}` consumer groups
  - `ResourceOwner` or `DeveloperWrite` role on the Schema Registry subject,
    if the source topic has an Avro, Protobuf, or JSON_SR schema
  <br/>
  These roles enable an interactive user to register a stream or table on the
  specified topic by using the CREATE STREAM statement.
  <br/>
  If the topic has an Avro, Protobuf, or JSON_SR schema, the interactive user
  and the ksqlDB service principal must have full access for the subject in Schema Registry.
  <br/>
  ```bash
  # Grant read-only access for a user to a topic.
  confluent iam rbac role-binding create \
    --principal User:$USER_NAME \
    --role ResourceOwner \
    --resource Topic:$TOPIC_NAME \
    $KAFKA_ID
  <br/>
  # Grant read-only access for the ksql service principal to a topic.
  confluent iam rbac role-binding create \
    --principal User:ksql \
    --role ResourceOwner \
    --resource Topic:$TOPIC_NAME \
    $KAFKA_ID
  ```
  <br/>
  ```bash
  # Grant read-only access for a user to the ksqlDB consumer groups.
  confluent iam rbac role-binding create \
    --principal User:$USER_NAME \
    --role DeveloperRead \
    --resource Group:_confluent-ksql-${KSQLDB_ID} \
    --prefix \
    $KAFKA_ID
  <br/>
  # Grant read-only access for the ksqlDB service principal to the ksqlDB consumer groups.
  confluent iam rbac role-binding create \
    --principal User:ksql \
    --role DeveloperRead \
    --resource Group:_confluent-ksql-${KSQLDB_ID} \
    --prefix \
    $KAFKA_ID
  ```
  <br/>
  ```bash
  # Grant full access for a user to create a subject and write to it.
  confluent iam rbac role-binding create \
    --principal User:$USER_NAME \
    --role ResourceOwner \
    --resource Subject:${TOPIC_NAME}-value \
    $KAFKA_ID \
    --schema-registry-cluster $SR_ID
  <br/>
  # Grant full access for the ksqlDB service principal to create a subject and write to it.
  confluent iam rbac role-binding create \
    --principal User:ksql \
    --role ResourceOwner \
    --resource Subject:${TOPIC_NAME}-value \
    $KAFKA_ID \
    --schema-registry-cluster $SR_ID
  ```

CREATE TABLE
: - `ResourceOwner` role on the source topic
  - `ResourceOwner` role on the `_confluent-ksql-${KSQLDB_ID}transient` transient topics
  - `ResourceOwner` or `DeveloperWrite` role on the Schema Registry subject,
    if the source topic has an Avro, Protobuf, or JSON_SR schema
  - `ResourceOwner` role on `_confluent-ksql-${KSQLDB_ID}*` subjects (for
    tables that use Avro, Protobuf, or JSON_SR)
  <br/>
  These roles enable an interactive user to register a table on the
  specified topic by using the CREATE TABLE statement.
  <br/>
  If the topic has an Avro, Protobuf, or JSON_SR schema, the interactive user
  and the ksqlDB service principal must have full access for the subject in Schema Registry.
  <br/>
  #### NOTE
  The `ResourceOwner` role on the transient topics is a limitation of KSQL
  tables. Giving this permission to the prefixed topics lets the user view
  tables from other queries.
  <br/>
  ```bash
  # Grant read-only access for a user to a topic.
  confluent iam rbac role-binding create \
    --principal User:$USER_NAME \
    --role ResourceOwner \
    --resource Topic:$TOPIC_NAME \
    $KAFKA_ID
  <br/>
  # Grant read-only access for ksql service principal to a topic.
  confluent iam rbac role-binding create \
    --principal User:ksql \
    --role ResourceOwner \
    --resource Topic:$TOPIC_NAME \
    $KAFKA_ID
  ```
  <br/>
  ```bash
  # Grant full access for a user to the transient query topics.
  # This is a limitation of ksqlDB tables. Giving this permission to
  # the prefixed topics lets the user view tables from other queries.
  confluent iam rbac role-binding create \
    --principal User:$USER_NAME \
    --role ResourceOwner \
    --resource Topic:_confluent-ksql-${KSQLDB_ID}transient \
    --prefix \
    $KAFKA_ID
  <br/>
  # Grant full access for the ksql service principal to ksqlDB transient topics.
  confluent iam rbac role-binding create \
    --principal User:ksql \
    --role ResourceOwner \
    --resource Topic:_confluent-ksql-${KSQLDB_ID}transient \
    --prefix \
    $KAFKA_ID
  ```
  <br/>
  ```bash
  # Grant full access for a user to create a subject and write to it.
  confluent iam rbac role-binding create \
    --principal User:$USER_NAME \
    --role ResourceOwner \
    --resource Subject:${TOPIC_NAME}-value \
    $KAFKA_ID \
    --schema-registry-cluster $SR_ID
  <br/>
  # Grant full access for the ksql service principal to create a subject and write to it.
  confluent iam rbac role-binding create \
    --principal User:ksql \
    --role ResourceOwner \
    --resource Subject:${TOPIC_NAME}-value \
    $KAFKA_ID \
    --schema-registry-cluster $SR_ID
  <br/>
  # For tables that use Avro, Protobuf, or JSON_SR:
  # Grant full access for the ksql service principal to all internal ksql subjects.
  confluent iam rbac role-binding create \
    --principal User:ksql \
    --role ResourceOwner \
    --resource Subject:_confluent-ksql-${KSQLDB_ID} \
    --prefix \
    $KAFKA_ID \
    --schema-registry-cluster $SR_ID
  ```

Create a stream or table with a persistent query
: - `ResourceOwner` role on the source topic
  - `ResourceOwner` role on the ksqlDB sink topic
  - `ResourceOwner` or `DeveloperWrite` role on the Schema Registry sink subject,
    if the source topic has an Avro, Protobuf, or JSON_SR schema
  - `DeveloperRead` role on `_confluent-ksql-${KSQLDB_ID}*` subjects (for
    tables that use Avro, Protobuf, or JSON_SR)
  <br/>
  These roles enable a user to create streams and tables with persistent
  queries. Because ksqlDB creates a new *sink topic*, the user must have
  sufficient permissions to create, read, and write to the sink topic. The
  `ResourceOwner` role is necessary on the sink topic, because the interactive
  user and the ksqlDB service principal need permissions to create the sink topic if it
  doesn’t exist already.
  <br/>
  #### NOTE
  The sink topic has the same name as the stream or table and is all
  uppercase.
  <br/>
  If the topic has an Avro schema, the interactive user and the ksqlDB service principal
  must have `ResourceOwner` or `DeveloperWrite` permission on the sink
  topic’s subject in Schema Registry.
  <br/>
  For tables that are created with a persistent query and use Avro, Protobuf,
  or JSON_SR the ksqlDB service principal must have `DeveloperRead` permission on
  all internal subjects.
  <br/>
  #### NOTE
  The subject’s name is the sink topic’s name appended with `-value`.
  <br/>
  ```bash
  # Grant read-only access for a user to a topic.
  confluent iam rbac role-binding create \
    --principal User:$USER_NAME \
    --role ResourceOwner \
    --resource Topic:$SOURCE_TOPIC_NAME \
    $KAFKA_ID
  <br/>
  # Grant read-only access for the ksql service principal to a topic.
  confluent iam rbac role-binding create \
    --principal User:ksql \
    --role ResourceOwner \
    --resource Topic:$SOURCE_TOPIC_NAME \
    $KAFKA_ID
  ```
  <br/>
  ```bash
  # Grant read-only access for a user to a topic.
  confluent iam rbac role-binding create \
    --principal User:$USER_NAME \
    --role ResourceOwner \
    --resource Topic:$SINK_TOPIC_NAME \
    $KAFKA_ID
  <br/>
  # Grant read-only access for the ksql service principal to a topic.
  confluent iam rbac role-binding create \
    --principal User:ksql \
    --role ResourceOwner \
    --resource Topic:$SINK_TOPIC_NAME \
    $KAFKA_ID
  ```
  <br/>
  ```bash
  # Grant full access for a user to create a subject and write to it.
  confluent iam rbac role-binding create \
    --principal User:$USER_NAME \
    --role ResourceOwner \
    --resource Subject:${SINK_TOPIC_NAME}-value \
    $KAFKA_ID \
    --schema-registry-cluster $SR_ID
  <br/>
  # Grant full access for the ksql service principal to create a subject and write to it.
  confluent iam rbac role-binding create \
    --principal User:ksql \
    --role ResourceOwner \
    --resource Subject:${SINK_TOPIC_NAME}-value \
    $KAFKA_ID \
    --schema-registry-cluster $SR_ID
  <br/>
  # For tables that use Avro, Protobuf, or JSON_SR created with a persistent query:
  # Grant read access for the ksql service principal to all internal ksql subjects.
  confluent iam rbac role-binding create \
    --principal User:ksql \
    --role DeveloperRead \
    --resource Subject:_confluent-ksql-${KSQLDB_ID} \
    --prefix \
    $KAFKA_ID \
    --schema-registry-cluster $SR_ID
  ```

Full control over a topic and schema
: - `ResourceOwner` role on the Kafka topic
  - `ResourceOwner` role on the Schema Registry subject, if the topic has an Avro,
    Protobuf, or JSON_SR schema
  <br/>
  Use the following commands to grant a user full control over a topic and its
  schema, including permissions to delete the topic and schema.
  <br/>
  ```bash
  # Grant full access for a user to manage a topic.
  confluent iam rbac role-binding create \
    --principal User:$USER_NAME \
    --role ResourceOwner \
    --resource Topic:$TOPIC_NAME \
    $KAFKA_ID
  ```
  <br/>
  ```bash
  # Grant full access for a user to manage a subject.
  confluent iam rbac role-binding create \
    --principal User:$USER_NAME \
    --role ResourceOwner \
    --resource Subject:${TOPIC_NAME}-value
    $KAFKA_ID \
    --schema-registry-cluster $SR_ID
  ```

Delete a topic
: - `DeveloperManage` role on the Kafka topic
  - `DeveloperManage` role on the Schema Registry subject, if the topic has an Avro,
    Protobuf, or JSON_SR schema
  <br/>
  These roles enable a user to delete a topic by using the DROP STREAM/TABLE
  [DELETE TOPIC] statements.
  <br/>
  Use the following commands to grant a user delete access to a topic and
  corresponding schema.
  <br/>
  ```bash
  # Grant delete access for a user to a topic.
  confluent iam rbac role-binding create \
    --principal User:$USER_NAME \
    --role DeveloperManage \
    --resource Topic:$TOPIC_NAME \
    $KAFKA_ID
  ```
  <br/>
  ```bash
  # Grant delete access for a user to a subject.
  confluent iam rbac role-binding create \
    --principal User:$USER_NAME \
    --role DeveloperManage \
    --resource Subject:${TOPIC_NAME}-value
    $KAFKA_ID \
    --schema-registry-cluster $SR_ID
  ```
