1. Manage Accounts and Access
  2. Control Access

Role-Based Access Control

Note

This feature is currently in Private Preview. In order to use this feature your Pulsar Clusters must be on the rapid channel and be on version 3.1.2.1 or greater. Contact StreamNative for it to be enabled.

Overview

Role-based access control (RBAC) allows you to control what level of access users have to your organization's resources, such as Pulsar clusters, tenants, and service accounts.

RBAC provides standardized ways to control resources in the StreamNative console as well as in Pulsar Clusters provided by StreamNative. A role can be thought of as a group of permissions. A user can be granted a role. These users that have a particular role can do certain actions and are not allowed to do others. They experience different UI experiences based on their permissions. They might not have direct access to Pulsar or are unable to perform certain operations on Pulsar. All roles are granted on an individual instance basis. The user who creates the organization is always an organization admin and is the billing account associated with that organization. This cannot be changed.

Roles

The current roles that StreamNative provides are the following:

  • admin
  • read-only
  • tenant-admin
  • basic

Organization Admin

Organization Admins have full control over everything in their organization. Users granted the Organization Admin role have the following capabilities:

  • Viewing and managing billing details
  • Viewing and managing secrets
  • Inviting users to your organization, deleting users, and modifying their roles.
  • Managing Pulsar Instances and Pulsar Clusters, including deleting Pulsar clusters.

Read Only

The read only role allows users to read information from the StreamNative Console, but disallows the modification or deletion of any resources. Users with the Read Only role have the following capabilities:

  • Peek at topics.
  • View clusters, tenants, and namespaces.
  • View users.
  • View functions and connectors.

Tenant Admin

The Tenant Admin role grants full administrative capabilities over a specific tenant. Tenant Admins have the following capabilities:

  • Create, modify, and delete namespaces within your tenant.

Basic Role

The Basic Role is the default role assigned to all users when they are invited to an organization. It cannot be removed from any user - if you need to reduce permissions further beyond this, you must delete a user from your organization. To access additional details in the console, you must assign users additional roles. The basic role grants access to the following resources in the organization:

  • Pulsar Instances (list and read access)
  • Pulsar Clusters (list and read access)

No other permissions are granted to this role.

StreamNative Cloud Resources

The resources that StreamNative provides as part of its cloud services are the following:

  • Organization
  • Organization Usage
  • Pulsar Instance
  • Pulsar Cluster
  • Secrets
  • Service Accounts
  • Generated Billing Links
  • Metrics
  • Users
  • Rolebinding

A table indicating the level of access each role has to the resources is below.

Role NameReadListCreateDeleteUpdate
adminallallallall except Organizationall
read-onlyall except Secrets, Service Accountsall except Secrets, Service Accountsnonenonenone
tenant-adminPulsar Instance, Pulsar ClusterPulsar Instance, Pulsar Clusterno cloud resources, only pulsar resourcesno cloud resources, only pulsar resourcesno cloud resources, only pulsar resources
basicPulsar Instance, Pulsar ClusterPulsar Instance, Pulsar Clusternonenonenone

Pulsar Resources

Pulsar provides some resources listed below. Tenants are the basis of the current authorization scheme for Pulsar. Pulsar Super Users are granted full access to the cluster including the ability to list tenants and manipulate them all. Individual principals (users) can be granted access to an individual tenant and then are able to manipulate the hierarchy under that tenant as shown below. They are not able to manipulate the cluster itself.

  • Super Users (Cluster Administrators)
  • Tenant
    • Can be replicated
    • Lowest current measure of Pulsar control
  • Namespace
    • policies
  • Topic
    • policies
    • Namespace Bundle
  • Message
  • Principal (access account)
  • Function
  • Sink
  • Source
  • pfSQL

A table indicating the level of access each role has to the resources is below.

Role NameReadListCreateDeleteUpdate
adminallallallallall
read-onlyallallnonenonenone
tenant-adminonly the tenant they administeronly the tenant they administeronly namespaces and topics in the tenant they administeronly namespaces and topics in the tenant they administeronly namespaces and topics in the tenant they administer
basicnonenonenonenonenone

Roles and Role Stacking

As mentioned before, roles can be stacked. As such, when you have a role stack, you have multiple roles assigned to a user. All users have at least the basic role, so all abilities stack from there. The abilities granted may be revoked at any time in the console by removing the role associated with that user from the user console. Roles grant abilities on Pulsar as well as on our Cloud objects. An example, but not comprehensive, stack of role abilities is shown below.

Cloud Abilities

Role StackReadListCreateDeleteUpdate
admin + any roleallallallallall
basic+read-only+tenant-admin to one tenantall except Secrets, ServiceAccountsall except Secrets, ServiceAccountsnonenonenone

Pulsar Abilities

Role StackReadListCreateDeleteUpdate
admin + any roleallallallallall
basic+read-only+tenant-admin to one tenantallallonly namespaces and topics in the tenant they administeronly namespaces and topics in the tenant they administeronly namespaces and topics in the tenant they administer

As you can see from the tables, the role with the highest abilities is what is granted when stacking roles.

The Console

The console experience is different for each role. The UI items listed are reflected to the abilities that the role is granted. Some items are hidden and will never display, some things will only display if a user is granted a particular role. Some users, for example, that are tenant admins will only see certain tenants in a cluster. This is because they only have access to those tenants and no others.

PulsarCtl and Pulsar-Admin

These CLI tools use direct Pulsar permissions. These permissions will need to be granted on top of the RBAC roles granted in the console. An example of granting access to a tenant on the pulsar cluster level is shown below:

shCopy code
$ pulsarctl tenants create my-tenant --admin-roles my-tenant-admin

# The principal of my-tenant-admin needs to match the principal used in pulsarctl for this to work

UI operates on instances which include all clusters under that instance. manipulating individual clusters is not a path forward we support in the UI and unexpected behavior will occur

Inviting Users

To invite a user, go to the users page, and click on the "Invite User" button. This will open up a modal where you can enter in a user's email.

tenant admin

You must first enter a valid email in order to assign them a role. If the user is already in your organization, you cannot invite them again; you must instead modify their role.

To assign a user Tenant Admin capabilities, you must select the tenant(s) you want to give the user by clicking the + button, and selecting the tenants you want the user to administer.

tenant admin

Modifying Roles

You must be an Organization Admin to modify roles.

To modify a user's roles, go to the users page, and click on the ellipses menu (...), and click Edit Roles. This opens up the Edit Role menu, where roles can be added by clicking the checkbox next to a role.

Best Practices

  • We recommend limiting the number of Organization Admins in your Organization as much as possible.
  • As a default, we recommend giving most users the read only role.

Limitations

Currently, StreamNative RBAC does not support role assignment via snctl.

Can roles be combined? Yes - roles can be combined by assigning a user multiple roles within the invite / edit user modal.

Application Resources

Note

This feature is currently in Private Preview. In order to use this feature your Pulsar Clusters must be on the rapid channel and be on version 3.2.2.7 or greater. Contact StreamNative for it to be enabled.

Getting Started

  1. Download snctl and login to StreamNative Cloud with your organization.
  2. Create a service account
  3. Create a role and wait for status to be ready.
  4. Create a role binding and wait for status to be ready.
  5. Configure your pulsarctl with new service account identity.
  6. Enjoy the feature! :)

How to Ensure the Resource Is Ready

"wait for status to be ready" means you should Get this resource to check the status of it.

E.g:

apiVersion: cloud.streamnative.io/v1alpha1
kind: Role
generation: 6
name: application-describer
namespace: <namespace>
spec:
  permissions:
    - pulsar.namespaces.describe
    - pulsar.topics.describe
    - pulsar.subscriptions.describe
    - pulsar.policies.describe
status:
  conditions:
    - lastTransitionTime: '2024-05-11T08:04:12Z'
      message: Ready
      observedGeneration: 6
      status: 'True'
      type: Ready
  • The generation means the resource current version.
  • The condition observedGeneration means applied resource version
  • The condition type Ready's status means the applied status. applied or not applied.

Role Management

Note

In the private preview stag, we will not expose role modifier permission to user. Contact StreamNative for manage role.

Snctl

  • List
snctl get role
  • Get
snctl get role <ROLE_NAME> -o yaml

Permission Matrix

PermissionsOperation-Allowed (* means wildcard)
pulsar.namespaces.describepulsar.tenant_operation.list_namespace,pulsar.tenant_operation.get_bundle
pulsar.namespaces.createpulsar.tenant_operation.create_namespace
pulsar.namespaces.deletepulsar.tenant_operation.delete_namespace
pulsar.namespaces.alterpulsar.namespace_operation.add_bundle,pulsar.namespace_operation.delete_bundle,pulsar.namespace_operation.clear_backlog
pulsar.topics.createpulsar.namespace_operation.create_topic
pulsar.topics.describepulsar.topic_operation.lookup,pulsar.topic_operation.get_topic,pulsar.topic_operation.get_topics,pulsar.topic_operation.get_bundle_range,pulsar.topic_operation.get_metadata,pulsar.topic_operation.get_backlog_size,pulsar.topic_operation.get_stats
pulsar.topics.deletepulsar.namespace_operation.delete_topic
pulsar.topics.alterpulsar.topic_operation.compact,pulsar.topic_operation.offload,pulsar.topic_operation.unload,pulsar.topic_operation.add_bundle_range,pulsar.topic_operation.terminate,pulsar.topic_operation.delete_bundle_range,pulsar.topic_operation.delete_metadata,pulsar.topic_operation.update_metadata,pulsar.namespace_operation.trim_topic,pulsar.topic_operation.trim_topic
pulsar.messages.producepulsar.topic_operation.lookup,pulsar.topic_operation.produce
pulsar.messages.consumepulsar.topic_operation.lookup,pulsar.topic_operation.consume,pulsar.topic_operation.subscribe,pulsar.namespace_operation.unsubscribe,pulsar.topic_operation.unsubscribe,pulsar.topic_operation.consume,pulsar.topic_operation.peek_messages
pulsar.subscriptions.createpulsar.topic_operation.subscribe
pulsar.subscriptions.deletepulsar.topic_operation.unsubscribe,pulsar.namespace_operation.unsubscribe
pulsar.subscriptions.alterpulsar.topic_operation.expired_messages,pulsar.topic_operation.reset_cursor,pulsar.topic_operation.skip,pulsar.topic_operation.set_replicated_subscription_status
pulsar.subscriptions.describepulsar.topic_operation.get_subscriptions,pulsar.topic_operation.get_replicated_subscription_status,pulsar.topic_operation.lookup
pulsar.policies.describepulsar.policyoperation*.read
pulsar.policies.alterpulsar.policyoperation*.write

Role Binding Management

You can bind a service account or user to specific role with permissions.

Template Example

apiVersion: cloud.streamnative.io/v1alpha1
kind: RoleBinding
metadata:
  name: client-1
  namespace: <namespace>
spec:
  roleRef:
    apiGroup: cloud.streamnative.io
    kind: Role
    name: application-describer
  subjects:
    - apiGroup: cloud.streamnative.io
      kind: ServiceAccount
      name: client-1

Snctl

  • Create
snctl create rolebinding <ROLE_BINDING_NAME> --role ROLE_NAME --serviceaccount <SERVICE_ACCOUNT_NAME>
  • List
snctl get rolebinding
  • Get
snctl get rolebinding <ROLE_BINDING_NAME> -o yaml
  • Delete
snctl delete rolebinding <ROLE_BINDING_NAME>
  • Apply
snctl apply -f role_binding_name.yaml

Role Binding With Condition Management

With RBAC Conditions, you can choose to grant access to principals only if specified conditions are met. For example, you could grant access only to specific tenants or namespaces.

Template Example

apiVersion: cloud.streamnative.io/v1alpha1
kind: RoleBinding
metadata:
  name: client-1
  namespace: <namespace>
spec:
  roleRef:
    apiGroup: cloud.streamnative.io
    kind: Role
    name: application-describer
  subjects:
    - apiGroup: cloud.streamnative.io
      kind: ServiceAccount
      name: client-1
  conditionGroup:
    relation: 1 # and
    conditions:
      - type: 0 # srn
        operator: 0 # key-match
        srn:
          tenant: public

Snctl

  • Create
snctl create rolebinding <ROLE_BINDING_NAME> --role ROLE_NAME --serviceaccount <SERVICE_ACCOUNT_NAME>

based on the command we have several optional options for binding condition:

--srn-instance string           condition srn instance
--srn-cluster string            condition srn cluster
--srn-tenant string             condition srn tenant
--srn-namespace string          condition srn namespace
--srn-topic string              condition srn topic name
--srn-topic-domain string       condition srn topic domain
--srn-subscription string       condition srn subscription name
  • Get
snctl get rolebinding <ROLE_BINDING_NAME> -o yaml
  • Delete
snctl delete rolebinding <ROLE_BINDING_NAME>
  • Apply
snctl apply -f role_binding_name.yaml

Condition Concept

Conditions are specified in the role bindings of a resource's allow policy. When a condition exists, the access request is granted only if the condition expression is evaluated as true. Each condition expression is a set of logic statements that specify one or more attributes to check.

Condition Format

{
  relation: <relation_code>
  conditions: [
    {
      type: <condition_type_code>,
      operator: <condition_type_suported_operator>,
      <condition_entity_key>: <condition_entity_body>
    }
  ]
  relationGroups: [
    {
      relation: <relation_code>
      conditions: [
        {
          type: <condition_type_code>,
          operator: <condition_type_suported_operator>,
          <condition_entity_key>: <condition_entity_body>
        }
      ]
      relationGroups: [
        {
          ...
        }
        // here's recursive, the structure will be a tree
      ]
    }
  ]
}

The condition format includes several parts:

  • Relation: the relation defines the logical relationship between conditions.
    • The AND(1) relation needs all the conditions to be TRUE.
    • The OR(0) relation only needs one of the conditions to be TURE.
  • Conditions: the set of conditions. You can check here to get supported conditions and format.
  • RelationGroups(not supported yet): This field allowed us to create a logical tree. For example, some users might need a condition expression like this - (conditionA && conditionB) || (conditionC && condition D)

Conditions

StreamNative Resource Name Condition

Type: SRN(0)

The StreamNative Resource Name condition’s type is SRN, whose type code is 0.

Operator: key_match(0) / regex_match(1)

The condition supports two operators:

  1. KeyMatch: the key match mode supports using the wildcard(*) in any level of SRN to indicate ANY meaning. The operator code is 0.
  2. RegexMatch: the regex match mode supports regex expression to match in any level of SRN. The operator code is 1. (not supported yet)

The SRN is a unified resource name to indicate a specific resource. The format looks like this:

// json format
{
 "schema":"srn",
 "version": "v1",
 "organization": "<organization>",
 "instance": "<instance>",
 "cluster" : "<cluster>",
 "tenant"  : "<tenant>",
 "namespace": "<namespace>",
 "topicDomain" : "<topic_domain>(persistent/non-persistent)",
 "topicName" : "<topic_name>"
}

// string format

srn://v1/<organization>/<instance>/<cluster>/<tenant>/<namespace>/<topic_domain>/<topic_name>
Previous
Authorization and ACL