Cassandra CQL Role-Based Access Control
Role-Based Access Control (RBAC) manages authentication and authorization through roles and permissions.
Behavioral Guarantees
Section titled “Behavioral Guarantees”What RBAC Operations Guarantee
Section titled “What RBAC Operations Guarantee”- CREATE ROLE creates a role definition stored in
system_auth.roles - GRANT permission immediately takes effect for new operations
- REVOKE permission immediately takes effect for new operations
- Role inheritance is resolved at authorization time (transitive permissions)
- DROP ROLE removes the role and cascades to revoke all grants
- Superuser roles bypass all permission checks
What RBAC Operations Do NOT Guarantee
Section titled “What RBAC Operations Do NOT Guarantee”Undefined Behavior
The following behaviors are undefined and must not be relied upon:
- Immediate enforcement across all nodes: Permission changes propagate asynchronously; brief windows of inconsistent enforcement may occur
- Existing connection state: Permission changes may not affect already-authenticated connections immediately
- Cache invalidation timing: Permission cache (
roles_validity_in_ms) may delay enforcement - Concurrent modification safety: Simultaneous role modifications may produce unexpected results
- Recovery of dropped roles: Dropped roles and their permissions are not recoverable
Permission Enforcement Contract
Section titled “Permission Enforcement Contract”| Operation | Check Location | Caching |
|---|---|---|
| Authentication | Any node | credentials_validity_in_ms |
| Authorization | Coordinator | roles_validity_in_ms |
| Permission resolution | Coordinator | permissions_validity_in_ms |
Role Hierarchy Contract
Section titled “Role Hierarchy Contract”| Scenario | Permission Resolution |
|---|---|
| Direct grant | Permission applies |
| Inherited via GRANT role | Permission applies (transitive) |
| Multiple inheritance paths | Permission applies if any path grants it |
| Revoked from parent | Permission revoked unless granted via another path |
Cache Configuration
Section titled “Cache Configuration”roles_validity_in_ms: 2000 # Role information cachepermissions_validity_in_ms: 2000 # Permission cachecredentials_validity_in_ms: 2000 # Authentication cacheFailure Semantics
Section titled “Failure Semantics”| Failure Mode | Outcome | Client Action |
|---|---|---|
UnauthorizedException | Operation denied | Request appropriate permissions |
InvalidRequestException | Invalid role or permission | Fix request syntax |
| Role not found | Operation fails | Create role or fix name |
| Circular grant attempt | Operation rejected | Redesign role hierarchy |
Version-Specific Behavior
Section titled “Version-Specific Behavior”| Version | Behavior |
|---|---|
| 2.2+ | RBAC introduced (CASSANDRA-7653), replaces per-user model |
| 3.0+ | Network authorization, improved role management |
| 5.0+ | Data masking permissions (UNMASK, SELECT_MASKED) |
| 5.0+ | Enhanced CIDR-based authorization |
History and Development
Section titled “History and Development”Background
Section titled “Background”Prior to Cassandra 2.2, authentication and authorization operated on a per-user model. Administrators created users with CREATE USER, granted permissions directly to individual users, and had no mechanism for grouping permissions or creating hierarchical access structures.
Design Goals
Section titled “Design Goals”The CASSANDRA-7653 proposal established several requirements:
- Role Unification - A single "role" concept replaces the separate notions of users and groups
- Role Inheritance - Roles can be granted to other roles, enabling hierarchical permission structures
- Backward Compatibility - Existing
CREATE USERandALTER USERsyntax continues to function - Centralized Management - Permissions defined once on a role apply to all members
Implementation Details
Section titled “Implementation Details”The RBAC implementation introduced:
| Component | Description |
|---|---|
IRoleManager | New pluggable interface for role management |
CassandraRoleManager | Default implementation storing roles in system_auth |
system_auth.roles | Replaces system_auth.users for role definitions |
system_auth.role_members | Tracks role-to-role grants |
system_auth.role_permissions | Stores permission grants |
Migration from Users to Roles
Section titled “Migration from Users to Roles”When upgrading from pre-2.2 versions:
- Existing users are automatically converted to roles with
LOGIN = true CREATE USERstatements internally executeCREATE ROLE ... WITH LOGIN = true- Permissions granted to users remain intact on the converted roles
Concepts
Section titled “Concepts”Cassandra uses roles for both authentication (users) and authorization (permission groups):
| Role Type | LOGIN | Purpose |
|---|---|---|
| User account | true | Authenticates to the cluster |
| Permission group | false | Groups permissions for assignment |
Permissions
Section titled “Permissions”Permissions control what actions a role can perform:
| Permission | Description | Applicable Resources |
|---|---|---|
ALL | All applicable permissions | Any |
ALTER | Modify schema | Keyspace, Table, Role |
AUTHORIZE | Grant/revoke permissions | Any |
CREATE | Create objects | Keyspace, Table, Function, Role |
DESCRIBE | View role details | Role |
DROP | Delete objects | Keyspace, Table, Function, Role |
EXECUTE | Execute functions | Function |
MODIFY | INSERT, UPDATE, DELETE | Keyspace, Table |
SELECT | Read data | Keyspace, Table |
UNMASK | View unmasked data | Keyspace, Table |
SELECT_MASKED | View masked data | Keyspace, Table |
Resources
Section titled “Resources”Permissions are granted on resources:
| Resource | Syntax |
|---|---|
| All keyspaces | ALL KEYSPACES |
| Keyspace | KEYSPACE keyspace_name |
| Table | [keyspace_name.]table_name |
| All functions | ALL FUNCTIONS [IN KEYSPACE keyspace_name] |
| Function | FUNCTION [keyspace_name.]func_name(arg_types) |
| All roles | ALL ROLES |
| Role | ROLE role_name |
| All MBeans | ALL MBEANS |
| MBean | MBEAN mbean_name / MBEANS pattern |
CREATE ROLE
Section titled “CREATE ROLE”Create a role for authentication and/or authorization.
Syntax
Section titled “Syntax”CREATE ROLE [ IF NOT EXISTS ] role_name [ WITH option [ AND option ... ] ]Options
Section titled “Options”| Option | Type | Default | Description |
|---|---|---|---|
PASSWORD | string | - | Authentication password |
HASHED PASSWORD | string | - | Pre-hashed password |
LOGIN | boolean | false | Whether role can authenticate |
SUPERUSER | boolean | false | Whether role has all permissions |
OPTIONS | map | {} | Authentication plugin options |
Examples
Section titled “Examples”-- User accountCREATE ROLE app_service WITH PASSWORD = 'secret123' AND LOGIN = true;
-- SuperuserCREATE ROLE admin WITH PASSWORD = 'admin_secret' AND LOGIN = true AND SUPERUSER = true;
-- Permission group (no login)CREATE ROLE read_only_access;
-- Idempotent creationCREATE ROLE IF NOT EXISTS developer WITH PASSWORD = 'dev_pwd' AND LOGIN = true;
-- With hashed password (for migration)CREATE ROLE migrated_user WITH HASHED PASSWORD = '$2a$10$...' AND LOGIN = true;Requirements
Section titled “Requirements”CREATEpermission onALL ROLES, or superuserPASSWORDrequired whenLOGIN = true
ALTER ROLE
Section titled “ALTER ROLE”Modify role properties.
Syntax
Section titled “Syntax”ALTER ROLE [ IF EXISTS ] role_name [ WITH option [ AND option ... ] ]Accepts same options as CREATE ROLE. With IF EXISTS, the statement is a no-op when the role does not exist instead of returning an error.
Examples
Section titled “Examples”-- Change passwordALTER ROLE app_service WITH PASSWORD = 'new_password';
-- Disable login (lock account)ALTER ROLE compromised_user WITH LOGIN = false;
-- Grant superuserALTER ROLE senior_dba WITH SUPERUSER = true;
-- Revoke superuserALTER ROLE former_admin WITH SUPERUSER = false;Requirements
Section titled “Requirements”ALTERpermission on the role, or superuser- Non-superusers can only change their own password
- Cannot demote the last superuser
DROP ROLE
Section titled “DROP ROLE”Remove a role.
Syntax
Section titled “Syntax”DROP ROLE [ IF EXISTS ] role_nameExamples
Section titled “Examples”DROP ROLE former_employee;DROP ROLE IF EXISTS temp_user;Requirements
Section titled “Requirements”DROPpermission on the role, or superuser- Cannot drop the last superuser
- Active sessions continue but re-authentication fails
GRANT (Permission)
Section titled “GRANT (Permission)”Grant permissions on resources to a role.
Syntax
Section titled “Syntax”GRANT ( ALL [ PERMISSIONS ] | permission ) ON resource TO role_name| Element | Values |
|---|---|
permission | CREATE, ALTER, DROP, SELECT, MODIFY, AUTHORIZE, DESCRIBE, UNMASK, SELECT_MASKED, EXECUTE |
resource | ALL KEYSPACES, KEYSPACE name, [TABLE] name, ALL ROLES, ROLE name, ALL FUNCTIONS [IN KEYSPACE name], FUNCTION name, ALL MBEANS, MBEAN name, MBEANS pattern |
Examples
Section titled “Examples”-- Read access to keyspaceGRANT SELECT ON KEYSPACE production TO analyst;
-- Read/write to tableGRANT SELECT ON orders TO app_service;GRANT MODIFY ON orders TO app_service;
-- Full access to keyspaceGRANT ALL PERMISSIONS ON KEYSPACE dev TO developer;
-- Schema management (no data access)GRANT CREATE ON ALL KEYSPACES TO schema_admin;GRANT ALTER ON ALL KEYSPACES TO schema_admin;GRANT DROP ON ALL KEYSPACES TO schema_admin;
-- Function executionGRANT EXECUTE ON FUNCTION my_ks.my_func(int) TO app_user;
-- Role managementGRANT ALTER ON ROLE app_user TO team_lead;GRANT AUTHORIZE ON ALL ROLES TO security_admin;
-- MBean access (JMX)GRANT SELECT ON ALL MBEANS TO monitoring;GRANT EXECUTE ON MBEAN 'org.apache.cassandra.db:type=StorageService' TO ops;Requirements
Section titled “Requirements”AUTHORIZEpermission on the resource, or superuser
GRANT (Role to Role)
Section titled “GRANT (Role to Role)”Grant a role to another role, creating role membership.
Syntax
Section titled “Syntax”GRANT role_name TO role_nameExamples
Section titled “Examples”-- Create permission groupsCREATE ROLE prod_read;CREATE ROLE prod_write;GRANT SELECT ON KEYSPACE production TO prod_read;GRANT MODIFY ON KEYSPACE production TO prod_write;
-- Assign groups to userCREATE ROLE app_service WITH PASSWORD = 'secret' AND LOGIN = true;GRANT prod_read TO app_service;GRANT prod_write TO app_service;
-- Hierarchical rolesCREATE ROLE junior_dev;CREATE ROLE senior_dev;GRANT junior_dev TO senior_dev; -- senior inherits junior's permissionsRequirements
Section titled “Requirements”AUTHORIZEpermission on both roles, or superuser- Circular grants not allowed
REVOKE (Permission)
Section titled “REVOKE (Permission)”Remove permissions from a role.
Syntax
Section titled “Syntax”REVOKE ( ALL [ PERMISSIONS ] | permission ) ON resource FROM role_namepermission and resource accept the same forms as in GRANT (Permission).
Examples
Section titled “Examples”-- Revoke specific permissionREVOKE MODIFY ON KEYSPACE production FROM app_service;
-- Revoke all permissions on resourceREVOKE ALL PERMISSIONS ON KEYSPACE sensitive FROM former_employee;
-- Revoke function executionREVOKE EXECUTE ON FUNCTION my_ks.my_func(int) FROM app_user;Requirements
Section titled “Requirements”AUTHORIZEpermission on the resource, or superuser- Revoking non-existent permission succeeds silently
REVOKE (Role from Role)
Section titled “REVOKE (Role from Role)”Remove role membership.
Syntax
Section titled “Syntax”REVOKE role_name FROM role_nameExamples
Section titled “Examples”-- Remove role membershipREVOKE prod_write FROM restricted_user;
-- Demote from senior to juniorREVOKE senior_dev FROM demoted_user;LIST ROLES
Section titled “LIST ROLES”Display roles and their properties.
Syntax
Section titled “Syntax”LIST ROLES [ OF role_name ] [ NORECURSIVE ]Options
Section titled “Options”| Option | Description |
|---|---|
OF role_name | Show roles granted to specified role |
NORECURSIVE | Show only direct grants, not inherited |
Examples
Section titled “Examples”-- All rolesLIST ROLES;
-- Roles granted to user (including inherited)LIST ROLES OF developer;
-- Direct grants onlyLIST ROLES OF app_user NORECURSIVE;Output
Section titled “Output” role | super | login | options------------+-------+-------+--------- cassandra | True | True | {} admin | True | True | {} app_user | False | True | {} readers | False | False | {}LIST PERMISSIONS
Section titled “LIST PERMISSIONS”Display granted permissions.
Syntax
Section titled “Syntax”LIST ( ALL [ PERMISSIONS ] | permission ) [ ON resource ] [ OF role_name [ NORECURSIVE ] ]Options
Section titled “Options”| Option | Description |
|---|---|
permission | Filter by permission type (or ALL) |
ON resource | Filter by resource |
OF role_name | Filter by role |
NORECURSIVE | Show only direct grants |
Examples
Section titled “Examples”-- All permissions in clusterLIST ALL PERMISSIONS;
-- Permissions for role (including inherited)LIST ALL PERMISSIONS OF app_service;
-- Direct grants onlyLIST ALL PERMISSIONS OF app_user NORECURSIVE;
-- Specific permission typeLIST SELECT ON KEYSPACE production;
-- Permissions on specific tableLIST ALL PERMISSIONS ON TABLE production.orders;Output
Section titled “Output” role | username | resource | permission-----------+------------+-----------------------+------------ app_user | app_user | <keyspace production> | SELECT app_user | app_user | <keyspace production> | MODIFYADD IDENTITY
Section titled “ADD IDENTITY”Associate a certificate identity with a role. Requires MutualTlsAuthenticator.
Available in Cassandra 5.0+
Syntax
Section titled “Syntax”ADD IDENTITY [ IF NOT EXISTS ] 'identity_string' TO ROLE role_nameWith IF NOT EXISTS, the statement is a no-op when the identity is already associated instead of returning an error.
Examples
Section titled “Examples”-- SPIFFE identityADD IDENTITY 'spiffe://cluster.local/ns/default/sa/app-service' TO ROLE app_service;
-- Certificate subjectADD IDENTITY 'CN=app-client,O=MyOrg' TO ROLE app_client;
-- Idempotent associationADD IDENTITY IF NOT EXISTS 'CN=app-client,O=MyOrg' TO ROLE app_client;See Mutual TLS Authentication for configuration.
DROP IDENTITY
Section titled “DROP IDENTITY”Remove a certificate identity mapping.
Available in Cassandra 5.0+
Syntax
Section titled “Syntax”DROP IDENTITY [ IF EXISTS ] 'identity_string'With IF EXISTS, the statement is a no-op when the identity does not exist instead of returning an error.
Examples
Section titled “Examples”DROP IDENTITY 'spiffe://cluster.local/ns/default/sa/app-service';DROP IDENTITY IF EXISTS 'spiffe://cluster.local/ns/default/sa/missing';Legacy User Statements
Section titled “Legacy User Statements”The pre-2.2 user-based statements remain supported as a thin layer over the role model. They are accepted for backward compatibility, but CREATE ROLE / ALTER ROLE / DROP ROLE should be preferred for new deployments.
CREATE USER
Section titled “CREATE USER”CREATE USER [ IF NOT EXISTS ] user_name [ WITH PASSWORD 'password' ] [ SUPERUSER | NOSUPERUSER ]Internally executes CREATE ROLE ... WITH LOGIN = true. SUPERUSER and NOSUPERUSER map to SUPERUSER = true|false. The default is NOSUPERUSER.
ALTER USER
Section titled “ALTER USER”ALTER USER [ IF EXISTS ] user_name [ WITH PASSWORD 'password' ] [ SUPERUSER | NOSUPERUSER ]DROP USER
Section titled “DROP USER”DROP USER [ IF EXISTS ] user_nameLIST USERS
Section titled “LIST USERS”LIST USERSReturns the subset of roles where LOGIN = true.
Examples
Section titled “Examples”CREATE USER IF NOT EXISTS app_user WITH PASSWORD 'secret' NOSUPERUSER;ALTER USER app_user WITH PASSWORD 'rotated_secret';ALTER USER IF EXISTS app_user SUPERUSER;DROP USER IF EXISTS legacy_user;LIST USERS;System Tables
Section titled “System Tables”Role and permission data is stored in system_auth:
| Table | Contents |
|---|---|
roles | Role definitions |
role_permissions | Permission grants |
role_members | Role-to-role grants |
identity_to_role | Certificate identity mappings (5.0+) |
-- View all rolesSELECT * FROM system_auth.roles;
-- View permissions for a roleSELECT * FROM system_auth.role_permissionsWHERE role = 'app_service';
-- View role membershipsSELECT * FROM system_auth.role_members;References
Section titled “References”JIRA Tickets
Section titled “JIRA Tickets”| Ticket | Description |
|---|---|
| CASSANDRA-547 | Original pluggable authentication framework (0.6) |
| CASSANDRA-7653 | Role-based access control implementation (2.2) |
| CASSANDRA-8394 | Cassandra 3.0 auth subsystem rework |
| CASSANDRA-7557 | UDF permissions |
| CASSANDRA-8082 | Fine-grained permissions |
| CASSANDRA-10091 | JMX authentication/authorization |
| CASSANDRA-18554 | mTLS authenticators (5.0) |
| CEP | Description |
|---|---|
| CEP-16 | CQLSH authentication plugin support |
| CEP-34 | mTLS client and internode authenticators |
| CEP-50 | Authentication negotiation (in progress) |
Related Documentation
Section titled “Related Documentation”| Topic | Description |
|---|---|
| CQL Security Overview | Security features summary |
| Dynamic Data Masking | Column-level data masking |
| Authentication | Authenticator configuration |
| Authorization | Authorizer configuration |