This guide covers both basic and advanced techniques for managing role bindings. Recommend to reviewing the Predefined Role for a complete list of available roles and for examples of how to binding them. You can manage role bindings by using snctl or StreamNative Terraform Provider. 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:
apiVersion: cloud.streamnative.io/v1alpha1
kind: RoleBinding
metadata:
  name: <name>
  namespace: <namespace>
spec:
  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.
  • 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, or an IdentityPool.

Create Role Bindings

You can create a role binding by using the following methods:
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>.
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.
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.
snctl apply -f rolebinding.yaml
After creating the role binding, you can verify it by running the following command:
snctl get rolebinding <name>
You should be able to see the role binding is in the Ready state.

Update Role Bindings

You can update a role binding by using the following methods:
You can use snctl edit to update a role binding directly.
snctl edit rolebinding <name>
Alternatively, you can update the file rolebinding.yaml and apply it using snctl apply.
snctl apply -f rolebinding.yaml

Delete Role Bindings

You can delete a role binding by using the following methods:
Delete a role binding:
snctl delete rolebinding <name>

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.
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 _.
snctl get rolebinding -l rolebinding.subject=user_example.com

Conditional Role Bindings

While basic role bindings simply associate a role with a user or service account, conditional role bindings provide more granular control by scoping permissions based on resource attributes. For example, you may want to restrict a topic-producer role to only work within a specific namespace. StreamNative Cloud allows you to express these conditions using below ways:
  1. Resource Name.
  2. Common Expression Language (CEL) for complex restriction.
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
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.

Using resource name:

snctl create rolebinding <role-binding-name> \
   --clusterrole topic-producer \
   --serviceaccount service-account-1 \
   --condition-instance ins-a --condition-cluster cluster-a --condition-tenant tenant-a --condition-namespace ns-a

Using CEL expression:

snctl create rolebinding <role-binding-name> \
   --clusterrole topic-producer \
   --serviceaccount service-account-1 \
   --condition-cel "srn.instance == 'ins-a' && srn.cluster == 'cluster-a' && srn.tenant == 'tenant-a' && srn.namespace == 'ns-a'"
Please use latest version of snctl and streamnative provider for Terraform when creating RoleBindings.
The Resource Name and CEL expression supports accessing resources through the following variable:
  • StreamNative Resource Name (SRN): Provides access to all resources within the hierarchy, from instance and cluster down to individual resources like tenants, namespaces, topics, and subscriptions.

StreamNative Resource Name (SRN)

A StreamNative Resource Name (SRN) uniquely identifies resources in StreamNative Cloud using a hierarchical structure. The SRN is accessed through the srn variable in CEL expressions and contains the following fields:
  • instance: The StreamNative Cloud instance
  • cluster: The Pulsar cluster
  • tenant: The tenant
  • namespace: The namespace
  • topic_domain: The topic domain (persistent or non-persistent)
  • topic_name: The name of the topic
  • subscription: The subscription name
  • servie_account: The service account name (used for “service-account-admin” role)
  • secret: The secret name (used for “secret” role)
For example, to scope a role binding to specific resources, you can create it with below arguments:
--condition-instance ins-a --condition-cluster cluster-a --condition-tenant tenant-a --condition-namespace ns-a --condition-topic-domain persistent --condition-topic-name topic-a --condition-subscription sub-a

Complex Conditional Role Bindings

CEL supports complex conditional role bindings that allow for more sophisticated access control patterns than using the resource name. For example, to bind a user as tenant-admin for multi resources:
  • Tenant: tenant-a and tenant-b
  • Cluster: cluster-a and cluster-b
  • Instance: ins-1 and ins-2
The CEL expression would be:
"(srn.instance == '' || srn.instance == 'ins-1' || srn.instance == 'ins-2') && (srn.cluster == '' || srn.cluster == 'cluster-a' || srn.cluster == 'cluster-b') && (srn.tenant == '' || srn.tenant == 'tenant-a' || srn.tenant == 'tenant-b')"