> ## Documentation Index
> Fetch the complete documentation index at: https://docs.streamnative.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Manage Role Bindings on StreamNative Cloud

This guide covers both basic and advanced techniques for managing role bindings. Recommend to reviewing the [Predefined Role](/cloud/security/access/rbac/manage-rbac-roles) for a complete list of available roles and for examples of how to binding them.

You can manage role bindings by using [snctl](/tools/cli/snctl/snctl-overview) or [StreamNative Terraform Provider](https://registry.terraform.io/providers/streamnative/streamnative/latest/docs). Support for the Cloud Console will be available soon.

## Role Bindings

Role bindings are used to bind roles to principals. They are defined as `RoleBinding` resources in the Cloud API. The schema is as follows:

```yaml theme={null}
apiVersion: cloud.streamnative.io/v1alpha1
kind: RoleBinding
metadata:
  name: <name>
  namespace: <namespace>
spec:
  resourceNameRestriction:
    common:
      instance: <instanceName>
      cluster: <clusterID>
      tenant: <tenantName>
      namespace: <namespaceName>
  roleRef:
    apiGroup: cloud.streamnative.io
    kind: ClusterRole
    name: <roleName>
  subjects:
    - apiGroup: cloud.streamnative.io
      kind: <subject type> # User, ServiceAccount, Identity Pool
      name: <subject name>
```

* `roleRef`: Reference to the **[Predefined Role](/cloud/security/access/rbac/manage-rbac-roles)**.
* `subjects`: List of subjects (also known as principals) to be bound to the role. It can be a \[**User Account**]]\(/cloud/security/authentication/user-accounts), a [**ServiceAccount**](/cloud/security/authentication/service-accounts/service-accounts), or an [**IdentityPool**](/cloud/security/authentication/oidc-identity-providers/manage-oidc-identity-pools).
* `resourceNameRestriction`: Optional field to restrict the role binding to specific resources. It can be used to limit the scope of the role binding to a specific resource. Refer to the [Conditional Role Bindings](#conditional-role-bindings) section for more details.

## Create Role Bindings

You can create a role binding by using the following methods:

<Tabs>
  <Tab title="snctl">
    You can create a role binding by running the following command to bind a predefined role `<predefined-role-name>` to a service account `<service-account-name>`.

    ```bash theme={null}
    snctl create rolebinding <role-binding-name> \
      --clusterrole <predefined-role-name> \
      --serviceaccount <service-account-name>
    ```

    Alternatively, you can prepare the manifest file `rolebinding.yaml` to bind a predefined role to a service account.

    ```yaml theme={null}
    apiVersion: cloud.streamnative.io/v1alpha1
    kind: RoleBinding
    metadata:
      name: <name>
      namespace: <namespace>
    spec:
      roleRef:
        apiGroup: cloud.streamnative.io
        kind: ClusterRole
        name: <predefined-role-name>
      subjects:
        - apiGroup: cloud.streamnative.io
          kind: ServiceAccount
          name: <service-account-name>
    ```

    Then apply it using `snctl apply`.

    ```bash theme={null}
    snctl apply -f rolebinding.yaml
    ```

    After creating the role binding, you can verify it by running the following command:

    ```bash theme={null}
    snctl get rolebinding <name>
    ```

    You should be able to see the role binding is in the `Ready` state.
  </Tab>

  <Tab title="Terraform">
    You can create a role binding by preparing the role binding definition in the Terraform configuration and applying the changes. Below is an example of binding a predefined role to a service account.

    ```hcl theme={null}
    terraform {
      required_providers {
        streamnative = {
          source = "streamnative/streamnative"
        }
      }
    }


    provider "streamnative" {
        # Please replace path use your own key file path
        key_file_path = "/path/to/your/service/account/key.json"
    }


    resource "streamnative_service_account" "metrics-account" {
      organization = "<organization-id>"
      name = "<service-account-name>"
      admin = false
    }


    resource "streamnative_rolebinding" "metrics-viewer" {
      organization          = "<organization-id>"
      name                  = "metrics-viewer"
      cluster_role_name     = "<predefined-role-name>"
      service_account_names = ["<service-account-name>"]
    }
    ```

    Please replace the placeholders with your actual values.

    * `<organization-id>`: The ID of your organization.
    * `<predefined-role-name>`: The name of the predefined role.
    * `<service-account-name>`: The name of the service account.

    After preparing the Terraform configuration, you can apply the changes using the following command:

    ```bash theme={null}
    terraform init
    terraform validate
    terraform plan
    terraform apply
    ```
  </Tab>
</Tabs>

## Update Role Bindings

You can update a role binding by using the following methods:

<Tabs>
  <Tab title="snctl">
    You can use `snctl edit` to update a role binding directly.

    ```bash theme={null}
    snctl edit rolebinding <name>
    ```

    Alternatively, you can update the file `rolebinding.yaml` and apply it using `snctl apply`.

    ```bash theme={null}
    snctl apply -f rolebinding.yaml
    ```
  </Tab>

  <Tab title="Terraform">
    You can update the role binding definition in the Terraform configuration and apply the changes.
  </Tab>
</Tabs>

## Delete Role Bindings

You can delete a role binding by using the following methods:

<Tabs>
  <Tab title="snctl">
    Delete a role binding:

    ```bash theme={null}
    snctl delete rolebinding <name>
    ```
  </Tab>

  <Tab title="Terraform">
    You can simply remove the role binding definition from the Terraform configuration and apply the changes.
  </Tab>
</Tabs>

## Query Role Bindings

You can efficiently query for RoleBinding resources by using a label selector with the -l flag.

### Search Role Bindings By Role Name

To find all Role Bindings associated with a specific role, use the `rolebinding.role` label.

-`${role_name}` refers to a [predefined role](/cloud/security/access/rbac/manage-rbac-roles#quick-reference).

```bash theme={null}
snctl get rolebinding -l rolebinding.role=tenant-admin
```

### Search Role Bindings By Account Name

To find all Role Bindings assigned to a specific user or service account, use the `rolebinding.subject` label.

The value for the `rolebinding.subject` label must be a sanitized version of the account name. You must replace the **@** symbol with an underscore **\_**.

```bash theme={null}
snctl get rolebinding -l rolebinding.subject=user_example.com
```

## Conditional Role Bindings

While basic role bindings associate a role with an account across the entire organization, conditional role bindings provide more granular control by scoping permissions to specific resources.

For example, you may want to restrict a `topic-producer` role to only work within a specific namespace, or on topics with names that start with a certain prefix. StreamNative Cloud allows you to express these conditions by specifying resource attributes.

The following example shows how to bind the `topic-producer` role to a service account named `service-account-1` with conditions that limit its access to:

* Instance: `ins-a`
* Cluster: `cluster-a`
* Tenant: `tenant-a`
* Namespace: `ns-a`

<Tabs>
  <Tab title="snctl">
    ```bash theme={null}
    snctl create rolebinding <role-binding-name> \
       --clusterrole topic-producer \
       --serviceaccount service-account-1 \
       --resource-common-instance ins-a \
       --resource-common-cluster cluster-a \
       --resource-common-tenant tenant-a \
       --resource-common-namespace ns-a
    ```
  </Tab>

  <Tab title="Terraform">
    ```hcl theme={null}
    resource "streamnative_rolebinding" "user-a-topic-xxx-producer" {
      organization          = "<organization-id>"
      name                  = "<role-binding-name>"
      cluster_role_name     = "topic-producer"
      service_account_names = ["service-account-1"]

      resource_name_restriction {
        common_instance  = "ins-a"
        common_cluster   = "cluster-a"
        common_tenant    = "tenant-a"
        common_namespace = "ns-a"
      }
    }
    ```
  </Tab>
</Tabs>

With these conditions, `service-account-1` can only produce messages to topics within the specified namespace (`tenant-a/ns-a`) on that particular instance and cluster.

### Available Resource Attributes

You can set conditions on the following resource attributes when creating a role binding.

| snctl CLI Flag                         | Terraform Attribute         | Description                                         |
| -------------------------------------- | --------------------------- | --------------------------------------------------- |
| `--resource-common-organization`       | `common_organization`       | The organization name                               |
| `--resource-common-instance`           | `common_instance`           | The StreamNative Cloud instance                     |
| `--resource-common-cluster`            | `common_cluster`            | The Pulsar cluster                                  |
| `--resource-common-tenant`             | `common_tenant`             | The tenant                                          |
| `--resource-common-namespace`          | `common_namespace`          | The namespace                                       |
| `--resource-common-topic`              | `common_topic`              | The topic name                                      |
| `--resource-pulsar-topic-domain`       | `pulsar_topic_domain`       | The topic domain (`persistent` or `non-persistent`) |
| `--resource-pulsar-subscription-name`  | `pulsar_subscription_name`  | The subscription name                               |
| `--resource-kafka-consumerGroup-name`  | `kafka_consumergroup_name`  | The Kafka consumer group name                       |
| `--resource-kafka-transaction-id`      | `kafka_transaction_id`      | The Kafka transaction ID                            |
| `--resource-schema-subject`            | `schema_subject`            | The schema subject                                  |
| `--resource-cloud-serviceAccount-name` | `cloud_serviceaccount_name` | The service account name                            |
| `--resource-cloud-apikey-name`         | `cloud_apikey_name`         | The API key name                                    |
| `--resource-cloud-secret-name`         | `cloud_secret_name`         | The secret name                                     |
| `--resource-cloud-catalog-name`        | `cloud_catalog_name`        | The lakehouse catalog name                          |
| `--resource-cloud-connection-name`     | `cloud_connection_name`     | The connection name                                 |
| `--resource-cloud-environment-name`    | `cloud_environment_name`    | The environment name                                |

### Advanced Conditions with Functions

For more sophisticated access control, you can use functions within the resource condition values to match patterns. This is useful for granting permissions to a group of resources, such as all topics with a specific prefix.

The following functions are supported:

* `startsWith('prefix')`: Matches resources that start with the given prefix.
* `endsWith('suffix')`: Matches resources that end with the given suffix.
* `matches('regex')`: Matches resources using a regular expression. The syntax follows Google's [RE2 syntax](https://github.com/google/re2/wiki/Syntax).
