Authorization controls WHAT you can do - like having different keys for different doors!
Remember the Difference:
# AUTHENTICATION: "WHO are you?"
$ cqlsh -u alice -p "password"
Connected! ← Identity verified ✅# AUTHORIZATION: "WHAT can you do?"
cqlsh> SELECT * FROM users;
Unauthorized: User alice has no SELECT permission ← Access denied ❌
The Problem Without Authorization:
# With authentication but NO authorization:# Every user can do EVERYTHING!# Junior developer alice logs in
$ cqlsh -u alice -p "password"
Connected!
# Can drop production keyspace! 😱
cqlsh> DROP KEYSPACE production;
Applied ← DISASTER!# Can read sensitive data!
cqlsh> SELECT * FROM credit_cards;
← Security breach!
With Authorization Enabled:
# alice has limited permissions
$ cqlsh -u alice -p "password"# Can only SELECT from allowed tables
cqlsh> SELECT * FROM analytics.reports;
← Allowed! ✅# Cannot drop anything
cqlsh> DROP KEYSPACE production;
Unauthorized: User alice has no DROP permission
← Blocked! ✅# Cannot read sensitive data
cqlsh> SELECT * FROM credit_cards;
Unauthorized: User alice has no SELECT permission on
← Protected! ✅
Principle of Least Privilege
Give users ONLY the minimum permissions they need to do their job!
Junior developer needs SELECT on analytics tables? Give ONLY that. Not DROP, not access to all keyspaces!
🛠️ Cassandra Authorizers
Choose your authorization system!
⚠️
AllowAllAuthorizer
Default - Insecure
Configuration:
authorizer: AllowAllAuthorizer
Behavior:
❌ No permission checks
❌ Everyone can do everything
✅ Only for dev/testing
❌ NEVER use in production
✅
CassandraAuthorizer
Recommended - Full RBAC
Configuration:
authorizer: CassandraAuthorizer
Features:
✅ Fine-grained permissions
✅ Role-based access control
✅ Keyspace/table-level control
✅ Production ready
Enabling CassandraAuthorizer
# Edit cassandra.yaml on ALL nodes
$ sudo vim /etc/cassandra/cassandra.yaml
# Change authorizer (usually right after authenticator)
authenticator: PasswordAuthenticator
authorizer: CassandraAuthorizer ← Change from AllowAllAuthorizer# Save and rolling restart
$ sudo systemctl restart cassandra
# Wait for node to be UN, then repeat on other nodes# Verify authorization enabled
$ cqlsh -u cassandra -p "password"# Superuser still has all permissions
cqlsh> SELECT * FROM system_auth.role_permissions;
# You'll see: Empty (superusers bypass permissions)# Regular users will now need permissions!
📜 Permission Types in Cassandra
All available permissions!
Data Permissions
Permission
What It Allows
Example
SELECT
Read data from tables
SELECT * FROM users;
MODIFY
Insert, update, delete data
INSERT INTO users ...; UPDATE users ...; DELETE FROM users ...;
Schema Permissions
Permission
What It Allows
Example
CREATE
Create keyspaces, tables, indexes
CREATE KEYSPACE ...; CREATE TABLE ...;
ALTER
Modify keyspaces, tables
ALTER TABLE users ADD email text;
DROP
Delete keyspaces, tables
DROP TABLE users;
Execution Permissions
Permission
What It Allows
Example
EXECUTE
Execute user-defined functions
SELECT my_udf(col) FROM table;
Role Management Permissions
Permission
What It Allows
Example
AUTHORIZE
Grant/revoke permissions
GRANT SELECT ON users TO alice;
DESCRIBE
View permissions
LIST ALL PERMISSIONS;
Special Permission
ALL PERMISSIONS grants all of the above permissions at once!
# Grant everything at keyspace levelGRANTALLPERMISSIONSON KEYSPACE my_keyspace TO alice;
# Equivalent to granting:GRANTSELECT, MODIFY, CREATE, ALTER, DROP, AUTHORIZEON KEYSPACE my_keyspace TO alice;
⚡ GRANT & REVOKE Commands
Complete permission management!
Granting Permissions
# ===== KEYSPACE-LEVEL PERMISSIONS =====# Grant SELECT on entire keyspaceGRANTSELECTON KEYSPACE analytics TO alice;
← alice can read ALL tables in analytics keyspace# Grant multiple permissionsGRANTSELECT, MODIFYON KEYSPACE analytics TO bob;
← bob can read and write to analytics# Grant all permissions on keyspaceGRANTALLPERMISSIONSON KEYSPACE analytics TO admin_user;
← admin_user has full control over analytics# ===== TABLE-LEVEL PERMISSIONS =====# Grant SELECT on specific tableGRANTSELECTON analytics.reports TO alice;
← alice can only read reports table# Grant MODIFY on specific tableGRANTMODIFYON analytics.logs TO logger_app;
← logger_app can insert/update/delete in logs# Grant CREATE (for creating tables in keyspace)GRANTCREATEON KEYSPACE dev_space TO developer;
← developer can create new tables in dev_space# ===== ALL KEYSPACES =====# Grant permission across ALL keyspacesGRANTSELECTONALL KEYSPACES TO readonly_admin;
← readonly_admin can read from any keyspace# ===== ROLE MANAGEMENT =====# Grant permission to manage rolesGRANTAUTHORIZEON KEYSPACE analytics TO team_lead;
← team_lead can grant/revoke permissions on analytics# Grant permission on specific roleGRANT data_writer TO alice;
← alice inherits all permissions from data_writer role
Revoking Permissions
# ===== REVOKE PERMISSIONS =====# Revoke SELECT from keyspaceREVOKESELECTON KEYSPACE analytics FROM alice;
← alice can no longer read from analytics# Revoke multiple permissionsREVOKESELECT, MODIFYON KEYSPACE analytics FROM bob;
# Revoke all permissionsREVOKEALLPERMISSIONSON KEYSPACE analytics FROM old_user;
# Revoke from specific tableREVOKEMODIFYON analytics.logs FROM logger_app;
# Revoke role membershipREVOKE data_writer FROM alice;
← alice loses permissions inherited from data_writer
Viewing Permissions
# List all permissions in the systemLISTALLPERMISSIONS;
# Output:
role | username | resource | permission
-------+----------+---------------------+------------
alice | alice | | SELECT
bob | bob | | SELECT
bob | bob | | MODIFY
# List permissions for specific userLISTALLPERMISSIONSOF alice;
# List permissions on specific resourceLISTALLPERMISSIONSON KEYSPACE analytics;
# List permissions on specific tableLISTALLPERMISSIONSON analytics.reports;
# Check if user has specific permissionLISTALLPERMISSIONSOF alice NORECURSIVE;
← Shows only direct permissions (not inherited from roles)
👥 Role-Based Access Control (RBAC)
Create role hierarchies for easier management!
Why Use Roles?
Instead of granting permissions to each user individually, create roles with permissions and assign users to roles!
✅ Easier management: Grant permissions once to role, add users to role
✅ Consistency: All users in role have same permissions
✅ Scalability: Add new users easily by assigning role
✅ Role hierarchies: Roles can inherit from other roles
Creating Role Hierarchy
# ===== STEP 1: CREATE BASE ROLES =====# Read-only role (can only SELECT)CREATEROLE readonly WITHLOGIN = false;
GRANTSELECTON KEYSPACE analytics TO readonly;
# Data writer role (can SELECT and MODIFY)CREATEROLE data_writer WITHLOGIN = false;
GRANTSELECT, MODIFYON KEYSPACE analytics TO data_writer;
# Admin role (full control)CREATEROLE admin_role WITHLOGIN = false;
GRANTALLPERMISSIONSON KEYSPACE analytics TO admin_role;
# ===== STEP 2: CREATE USERS =====# Junior analyst (read-only)CREATEROLE alice WITHPASSWORD = 'alice_pass'ANDLOGIN = true;
# Senior engineer (can write data)CREATEROLE bob WITHPASSWORD = 'bob_pass'ANDLOGIN = true;
# Team lead (admin access)CREATEROLE charlie WITHPASSWORD = 'charlie_pass'ANDLOGIN = true;
# ===== STEP 3: ASSIGN ROLES TO USERS =====GRANT readonly TO alice;
← alice inherits SELECT permission from readonly roleGRANT data_writer TO bob;
← bob inherits SELECT + MODIFY from data_writer roleGRANT admin_role TO charlie;
← charlie inherits ALL PERMISSIONS from admin_role# ===== RESULT: Easy Permission Management! =====# Want to add new junior analyst?CREATEROLE diana WITHPASSWORD = 'diana_pass'ANDLOGIN = true;
GRANT readonly TO diana;
← Done! Diana automatically gets readonly permissions# Promote alice to data writer?REVOKE readonly FROM alice;
GRANT data_writer TO alice;
← Alice now has write access!
Advanced: Nested Roles
# Roles can inherit from other roles!# Base role: Can read users tableCREATEROLE user_reader WITHLOGIN = false;
GRANTSELECTON app.users TO user_reader;
# Extended role: Can read AND write usersCREATEROLE user_manager WITHLOGIN = false;
GRANT user_reader TO user_manager; ← Inherit SELECT from user_readerGRANTMODIFYON app.users TO user_manager; ← Add MODIFY# Top role: Full controlCREATEROLE user_admin WITHLOGIN = false;
GRANT user_manager TO user_admin; ← Inherit SELECT + MODIFYGRANTDROP, ALTERON app.users TO user_admin; ← Add DROP + ALTER# Assign to usersCREATEROLE eve WITHPASSWORD = 'eve_pass'ANDLOGIN = true;
GRANT user_admin TO eve;
# eve now has: SELECT, MODIFY, DROP, ALTER on app.users!# (Inherited through role hierarchy)
Viewing Role Hierarchy
# List all rolesLISTROLES;
# See what roles a user hasLISTROLESOF alice;
# Output:
role | super | login | options
----------+-------+-------+---------
alice | False | True | {}
readonly | False | False | {}
← alice has readonly role# See all permissions (including inherited)LISTALLPERMISSIONSOF alice;
← Shows permissions from alice AND from readonly role
💼 Real-World Authorization Scenarios
Complete permission setups!
Scenario 1: E-Commerce Application
# Context: E-commerce with different services# Services: web_frontend, order_service, inventory_service, analytics# ===== STEP 1: CREATE KEYSPACES =====CREATE KEYSPACE ecommerce WITH replication = {
'class': 'NetworkTopologyStrategy', 'dc1': '3'
};
USE ecommerce;
CREATE TABLE users (...);
CREATE TABLE orders (...);
CREATE TABLE inventory (...);
CREATE TABLE analytics_events (...);
# ===== STEP 2: CREATE SERVICE ROLES =====# Web frontend: Read users, create ordersCREATEROLE web_frontend
WITHPASSWORD = 'web_secret_key'ANDLOGIN = true;
GRANTSELECTON ecommerce.users TO web_frontend;
GRANTSELECT, MODIFYON ecommerce.orders TO web_frontend;
GRANTSELECTON ecommerce.inventory TO web_frontend;
# Order service: Full access to ordersCREATEROLE order_service
WITHPASSWORD = 'order_secret_key'ANDLOGIN = true;
GRANTSELECT, MODIFYON ecommerce.orders TO order_service;
GRANTSELECT, MODIFYON ecommerce.inventory TO order_service;
# Inventory service: Manage inventoryCREATEROLE inventory_service
WITHPASSWORD = 'inventory_secret_key'ANDLOGIN = true;
GRANTSELECT, MODIFYON ecommerce.inventory TO inventory_service;
# Analytics: Read-only access to everythingCREATEROLE analytics_service
WITHPASSWORD = 'analytics_secret_key'ANDLOGIN = true;
GRANTSELECTON KEYSPACE ecommerce TO analytics_service;
GRANTMODIFYON ecommerce.analytics_events TO analytics_service;
# ===== STEP 3: VERIFY PERMISSIONS =====LISTALLPERMISSIONS;
# Result: Each service has exactly what it needs!# - web_frontend: Can't modify inventory directly# - order_service: Can't access users# - inventory_service: Can't access orders# - analytics: Read-only, except can write events
Scenario 2: Data Team Hierarchy
# Context: Data team with different seniority levels# Team: Interns, Junior Analysts, Senior Analysts, Data Engineers, Team Lead# ===== CREATE KEYSPACE =====CREATE KEYSPACE data_warehouse WITH replication = {
'class': 'NetworkTopologyStrategy', 'dc1': '3'
};
USE data_warehouse;
CREATE TABLE raw_data (...);
CREATE TABLE processed_data (...);
CREATE TABLE reports (...);
# ===== CREATE ROLE HIERARCHY =====# Level 1: Interns (read reports only)CREATEROLE intern_role WITHLOGIN = false;
GRANTSELECTON data_warehouse.reports TO intern_role;
# Level 2: Junior Analyst (read all, write reports)CREATEROLE junior_analyst WITHLOGIN = false;
GRANT intern_role TO junior_analyst; ← Inherit intern permissionsGRANTSELECTON data_warehouse.raw_data TO junior_analyst;
GRANTSELECTON data_warehouse.processed_data TO junior_analyst;
GRANTMODIFYON data_warehouse.reports TO junior_analyst;
# Level 3: Senior Analyst (read all, write processed + reports)CREATEROLE senior_analyst WITHLOGIN = false;
GRANT junior_analyst TO senior_analyst; ← Inherit junior permissionsGRANTMODIFYON data_warehouse.processed_data TO senior_analyst;
# Level 4: Data Engineer (full data access)CREATEROLE data_engineer WITHLOGIN = false;
GRANT senior_analyst TO data_engineer; ← Inherit senior permissionsGRANTMODIFYON data_warehouse.raw_data TO data_engineer;
GRANTCREATE, ALTERON KEYSPACE data_warehouse TO data_engineer;
# Level 5: Team Lead (full control)CREATEROLE team_lead WITHLOGIN = false;
GRANT data_engineer TO team_lead; ← Inherit engineer permissionsGRANTALLPERMISSIONSON KEYSPACE data_warehouse TO team_lead;
# ===== ASSIGN USERS TO ROLES =====# InternsCREATEROLE intern_alice WITHPASSWORD = 'pass1'ANDLOGIN = true;
GRANT intern_role TO intern_alice;
# Junior AnalystsCREATEROLE analyst_bob WITHPASSWORD = 'pass2'ANDLOGIN = true;
GRANT junior_analyst TO analyst_bob;
# Senior AnalystsCREATEROLE senior_carol WITHPASSWORD = 'pass3'ANDLOGIN = true;
GRANT senior_analyst TO senior_carol;
# Data EngineersCREATEROLE engineer_dave WITHPASSWORD = 'pass4'ANDLOGIN = true;
GRANT data_engineer TO engineer_dave;
# Team LeadCREATEROLE lead_eve WITHPASSWORD = 'pass5'ANDLOGIN = true;
GRANT team_lead TO lead_eve;
# ===== PROMOTION EXAMPLE =====# Bob gets promoted from Junior to Senior AnalystREVOKE junior_analyst FROM analyst_bob;
GRANT senior_analyst TO analyst_bob;
← Bob now has senior permissions! Easy!
Scenario 3: Emergency - Revoking Compromised User
# EMERGENCY: User 'alice' credentials compromised!# Need to immediately revoke all access# STEP 1: Disable login immediately
$ cqlsh -u cassandra -p "admin_password"
cqlsh> ALTERROLE alice WITHLOGIN = false;
← alice can no longer connect!# Test: alice tries to connect
$ cqlsh -u alice -p "password"
Authentication failed ← Blocked! ✅# STEP 2: Check what permissions alice had
cqlsh> LISTALLPERMISSIONSOF alice;
# Output:
role | resource | permission
-------+---------------------+------------
alice | | SELECT
alice | | MODIFY
# STEP 3: Revoke all permissions
cqlsh> REVOKEALLPERMISSIONSON KEYSPACE analytics FROM alice;
# STEP 4: Create new user with same role
cqlsh> CREATEROLE alice_new
WITHPASSWORD = 'new_secure_password_xyz'ANDLOGIN = true;
GRANTSELECT, MODIFYON KEYSPACE analytics TO alice_new;
# STEP 5: Update applications# Update app configs to use alice_new instead of alice# STEP 6: Delete old compromised user
cqlsh> DROPROLE alice;
# RESULT: Attacker locked out, new secure credentials in place!
🔧 Troubleshooting Authorization Issues
Fix permission problems!
❌ "Unauthorized: User has no permission"
# ERROR:
cqlsh> SELECT * FROM users;
Unauthorized: User alice has no SELECT permission on
# DIAGNOSIS: Check user's permissions
cqlsh> LISTALLPERMISSIONSOF alice;
# Empty result → No permissions!# FIX: Grant appropriate permission
cqlsh> GRANTSELECTON my_keyspace.users TO alice;
# Or grant at keyspace level:
cqlsh> GRANTSELECTON KEYSPACE my_keyspace TO alice;
# Test:
cqlsh> SELECT * FROM users;
← Works! ✅
❌ User Has Permission But Still Gets "Unauthorized"
# SYMPTOM: Permissions look correct but still denied# CHECK 1: Permissions on correct resource?
cqlsh> LISTALLPERMISSIONSOF alice;
role | resource | permission
-------+--------------------------+------------
alice | | SELECT
# ← Oops! Permission on wrong keyspace!# FIX: Grant on correct resource
cqlsh> GRANTSELECTON KEYSPACE correct_keyspace TO alice;
# CHECK 2: Authorization enabled?
$ grep authorizer /etc/cassandra/cassandra.yaml
authorizer: AllowAllAuthorizer ← Still allows all!# FIX: Enable CassandraAuthorizer
authorizer: CassandraAuthorizer
$ sudo systemctl restart cassandra
❌ Can't Grant Permissions (Not Authorized)
# ERROR:
cqlsh> GRANTSELECTON users TO bob;
Unauthorized: User alice has no AUTHORIZE permission
# CAUSE: Need AUTHORIZE permission to grant permissions# FIX 1: Grant AUTHORIZE permission (as superuser)
$ cqlsh -u cassandra -p "admin_pass"
cqlsh> GRANTAUTHORIZEON KEYSPACE my_keyspace TO alice;
# Now alice can grant permissions on my_keyspace# FIX 2: Make user a superuser (full control)
cqlsh> ALTERROLE alice WITHSUPERUSER = true;
← alice can now do anything (be careful!)
❌ Permission Not Taking Effect Immediately
# SYMPTOM: Just granted permission but user still denied# CAUSE: Permission cache not updated# In cassandra.yaml:
permissions_validity_in_ms: 2000← Default: 2 seconds
permissions_update_interval_in_ms: 1000# SOLUTION 1: Wait 2-3 seconds# Permissions will be refreshed automatically# SOLUTION 2: Reconnect user's session# Disconnect and reconnect cqlsh# SOLUTION 3: Reduce cache time (in cassandra.yaml)
permissions_validity_in_ms: 500← 500ms# Restart Cassandra# For production, 2000ms is usually fine# Lower values increase load on system_auth
💡 Best Practices
Authorization done right!
✅
DO
Use least privilege principle
Create role hierarchies
Grant at keyspace level when possible
Use roles instead of direct permissions
Document permission structure
Regular permission audits
Revoke when users leave
Separate prod/dev permissions
Test permissions in dev first
Use descriptive role names
❌
DON'T
Give everyone ALL PERMISSIONS
Make everyone a SUPERUSER
Grant more than needed
Share user accounts
Grant AUTHORIZE carelessly
Forget to revoke old permissions
Use same credentials prod/dev
Grant directly without roles
Skip permission testing
Leave default AllowAllAuthorizer
Production Permission Strategy
✅ Enable CassandraAuthorizer: In cassandra.yaml on all nodes
✅ Design role hierarchy: Base roles → Team roles → Users
✅ Minimum permissions: Only what's needed for the job
✅ Service accounts: One per application/service
✅ Admin separation: Limited superusers, most use roles
✅ Regular audits: Review permissions quarterly
✅ Offboarding process: Revoke access when users leave
✅ Monitoring: Alert on permission changes
✅ Documentation: Maintain role/permission map
✅ Testing: Verify permissions work before prod
Permission Planning Template
Use this template for new users/services:
# 1. IDENTIFY NEEDS# What does this user/service need to do?# - Read from which tables?# - Write to which tables?# - Create/alter/drop anything?# 2. FIND/CREATE APPROPRIATE ROLE# Does existing role fit? If not, create new one# 3. GRANT MINIMUM PERMISSIONS# Start small, add more if needed# 4. TEST THOROUGHLY# Verify can do required tasks# Verify CANNOT do unauthorized tasks# 5. DOCUMENT# Record role assignment and reason# 6. REVIEW REGULARLY# Quarterly: Does user still need these permissions?
🎉 You're an Authorization Expert!
Congratulations! You now know how to control access with fine-grained permissions!
🎓 What You Learned:
🔍 Authorization basics: Control WHAT users can do
🛠️ Authorizers: AllowAll (insecure) vs CassandraAuthorizer (secure)