- Manage Security
- Control Access
- Role-Based Access Control
Role-Based Access Control (V1)
Note
This documentation covers RBAC Version 1. For information about RBAC Version 2, see RBAC.
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 Name | Read | List | Create | Delete | Update |
---|---|---|---|---|---|
admin | all | all | all | all except Organization | all |
read-only | all except Secrets, Service Accounts | all except Secrets, Service Accounts | none | none | none |
tenant-admin | Pulsar Instance, Pulsar Cluster | Pulsar Instance, Pulsar Cluster | no cloud resources, only pulsar resources | no cloud resources, only pulsar resources | no cloud resources, only pulsar resources |
basic | Pulsar Instance, Pulsar Cluster | Pulsar Instance, Pulsar Cluster | none | none | none |
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 Name | Read | List | Create | Delete | Update |
---|---|---|---|---|---|
admin | all | all | all | all | all |
read-only | all | all | none | none | none |
tenant-admin | only the tenant they administer | only the tenant they administer | only namespaces and topics in the tenant they administer | only namespaces and topics in the tenant they administer | only namespaces and topics in the tenant they administer |
basic | none | none | none | none | none |
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 Stack | Read | List | Create | Delete | Update |
---|---|---|---|---|---|
admin + any role | all | all | all | all | all |
basic+read-only+tenant-admin to one tenant | all except Secrets, ServiceAccounts | all except Secrets, ServiceAccounts | none | none | none |
Pulsar Abilities
Role Stack | Read | List | Create | Delete | Update |
---|---|---|---|---|---|
admin + any role | all | all | all | all | all |
basic+read-only+tenant-admin to one tenant | all | all | only namespaces and topics in the tenant they administer | only namespaces and topics in the tenant they administer | only 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.
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.
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
- Download snctl and login to StreamNative Cloud with your organization.
- Create a service account
- Create a role and wait for status to be ready.
- Create a role binding and wait for status to be ready.
- Configure your pulsarctl with new service account identity.
- 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
'sstatus
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
Permissions | Operation-Allowed (* means wildcard) |
---|---|
pulsar.namespaces.describe | pulsar.tenant_operation.list_namespace,pulsar.tenant_operation.get_bundle |
pulsar.namespaces.create | pulsar.tenant_operation.create_namespace |
pulsar.namespaces.delete | pulsar.tenant_operation.delete_namespace |
pulsar.namespaces.alter | pulsar.namespace_operation.add_bundle,pulsar.namespace_operation.delete_bundle,pulsar.namespace_operation.clear_backlog |
pulsar.topics.create | pulsar.namespace_operation.create_topic |
pulsar.topics.describe | pulsar.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.delete | pulsar.namespace_operation.delete_topic |
pulsar.topics.alter | pulsar.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.produce | pulsar.topic_operation.lookup,pulsar.topic_operation.produce |
pulsar.messages.consume | pulsar.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.create | pulsar.topic_operation.subscribe |
pulsar.subscriptions.delete | pulsar.topic_operation.unsubscribe,pulsar.namespace_operation.unsubscribe |
pulsar.subscriptions.alter | pulsar.topic_operation.expired_messages,pulsar.topic_operation.reset_cursor,pulsar.topic_operation.skip,pulsar.topic_operation.set_replicated_subscription_status |
pulsar.subscriptions.describe | pulsar.topic_operation.get_subscriptions,pulsar.topic_operation.get_replicated_subscription_status,pulsar.topic_operation.lookup |
pulsar.policies.describe | pulsar.policyoperation*.read |
pulsar.policies.alter | pulsar.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:
- KeyMatch: the key match mode supports using the wildcard(*) in any level of SRN to indicate ANY meaning. The operator code is 0.
- 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>