// role_name ::= identifier | string= Security
[[cql-roles]]
= Database Roles

CQL uses database roles to represent users and group of users.
Syntactically, a role is defined by:

[source, bnf]
----
include::cassandra:example$BNF/role_name.bnf[]
----


[[create-role-statement]]
== CREATE ROLE

Creating a role uses the `CREATE ROLE` statement:

[source, bnf]
----
include::cassandra:example$BNF/create_role_statement.bnf[]
----

For instance:

[source,cql]
----
include::cassandra:example$CQL/create_role.cql[]
----

By default roles do not possess `LOGIN` privileges or `SUPERUSER`
status.

xref:cassandra:developing/cql/security.adoc#cql-permissions[Permissions] on database resources are granted to
roles; types of resources include keyspaces, tables, functions and roles
themselves. Roles may be granted to other roles to create hierarchical
permissions structures; in these hierarchies, permissions and
`SUPERUSER` status are inherited, but the `LOGIN` privilege is not.

If a role has the `LOGIN` privilege, clients may identify as that role
when connecting. For the duration of that connection, the client will
acquire any roles and privileges granted to that role.

Only a client with with the `CREATE` permission on the database roles
resource may issue `CREATE ROLE` requests (see the
xref:cassandra:developing/cql/security.adoc#cql-permissions[relevant section]), unless the client is a
`SUPERUSER`. Role management in Cassandra is pluggable and custom
implementations may support only a subset of the listed options.

Role names should be quoted if they contain non-alphanumeric characters.

=== Setting credentials for internal authentication

Use the `WITH PASSWORD` clause to set a password for internal
authentication, enclosing the password in single quotation marks.

If internal authentication has not been set up or the role does not have
`LOGIN` privileges, the `WITH PASSWORD` clause is not necessary.

USE `WITH HASHED PASSWORD` to provide the jBcrypt hashed password directly. See the `hash_password` tool.

=== Restricting connections to specific datacenters

If a `network_authorizer` has been configured, you can restrict login
roles to specific datacenters with the `ACCESS TO DATACENTERS` clause
followed by a set literal of datacenters the user can access. Not
specifiying datacenters implicitly grants access to all datacenters. The
clause `ACCESS TO ALL DATACENTERS` can be used for explicitness, but
there's no functional difference.

=== Restricting connections from specific CIDR groups

If a `cidr_authorizer` has been configured, you can restrict roles to login
only from specific regions, aka CIDR groups, with the `ACCESS FROM CIDRS` clause
followed by a set literal of CIDR groups the user can access from. Not
specifying CIDR groups implicitly grants access from all CIDR groups. The
clause `ACCESS FROM ALL CIDRS` can be used for explicitness, but there's no
functional difference. This clause can be also be used to remove any CIDR
groups restrictions. Valid CIDR groups should be used with `ACCESS FROM CIDRS`
clause. `nodetool list-cidrgroups` command can be used to see available CIDR groups
in the Cluster.

=== Creating a role conditionally

Attempting to create an existing role results in an invalid query
condition unless the `IF NOT EXISTS` option is used. If the option is
used and the role exists, the statement is a no-op:

[source,cql]
----
include::cassandra:example$CQL/create_role_ifnotexists.cql[]
----

[[alter-role-statement]]
== ALTER ROLE

Altering a role options uses the `ALTER ROLE` statement:

[source, bnf]
----
include::cassandra:example$BNF/alter_role_statement.bnf[]
----

For example:

[source,cql]
----
include::cassandra:example$CQL/alter_role.cql[]
----
If the role does not exist, the statement will return an error, unless `IF EXISTS` is used in which case the operation is a no-op.

USE `WITH HASHED PASSWORD` to provide the jBcrypt hashed password directly. See the `hash_password` tool.

=== Restricting connections to specific datacenters

If a `network_authorizer` has been configured, you can restrict login
roles to specific datacenters with the `ACCESS TO DATACENTERS` clause
followed by a set literal of datacenters the user can access. To remove
any data center restrictions, use the `ACCESS TO ALL DATACENTERS`
clause.

=== Restricting connections from specific CIDR groups

If a `cidr_authorizer` has been configured, you can restrict roles to login
only from specific regions, aka CIDR groups, with the `ACCESS FROM CIDRS` clause
followed by a set literal of CIDR groups the user can access from. Not
specifying CIDR groups implicitly grants access from all CIDR groups. The
clause `ACCESS FROM ALL CIDRS` can be used for explicitness, but there's no
functional difference. This clause can be also be used to remove any CIDR
groups restrictions. Valid CIDR groups should be used with `ACCESS FROM CIDRS`
clause. `nodetool list-cidrgroups` command can be used to see available CIDR groups
in the Cluster.

=== Conditions on executing `ALTER ROLE` statements:

* a client must have `SUPERUSER` status to alter the `SUPERUSER` status
of another role
* a client cannot alter the `SUPERUSER` status of any role it currently
holds
* a client can only modify certain properties of the role with which it
identified at login (e.g. `PASSWORD`)
* to modify properties of a role, the client must be granted `ALTER`
`permission <cql-permissions>` on that role

[[drop-role-statement]]
== DROP ROLE

Dropping a role uses the `DROP ROLE` statement:

[source, bnf]
----
include::cassandra:example$BNF/drop_role_statement.bnf[]
----

`DROP ROLE` requires the client to have `DROP`
`permission <cql-permissions>` on the role in question. In addition,
client may not `DROP` the role with which it identified at login.
Finally, only a client with `SUPERUSER` status may `DROP` another
`SUPERUSER` role.

Attempting to drop a role which does not exist results in an invalid
query condition unless the `IF EXISTS` option is used. If the option is
used and the role does not exist the statement is a no-op.

[NOTE]
====
DROP ROLE intentionally does not terminate any open user sessions.
Currently connected sessions will remain connected and will retain the
ability to perform any database actions which do not require
xref:cassandra:managing/operating/security.adoc#authorization[authorization].
However, if authorization is enabled, xref:cassandra:developing/cql/security.adoc#cql-permissions[permissions] of the dropped role are also revoked,
subject to the xref:cassandra:managing/operating/security.adoc#auth-caching[caching options] configured in xref:cassandra:managing/configuration/cass_yaml_file.adoc[cassandra-yaml] file.
Should a dropped role be subsequently recreated and have new xref:cassandra:developing/cql/security.adoc#grant-permission-statement[permissions] or
xref:cassandra:developing/cql/security.adoc#grant-role-statement[roles] granted to it, any client sessions still
connected will acquire the newly granted permissions and roles.
====

[[grant-role-statement]]
== GRANT ROLE

Granting a role to another uses the `GRANT ROLE` statement:

[source, bnf]
----
include::cassandra:example$BNF/grant_role_statement.bnf[]
----

For example:

[source,cql]
----
include::cassandra:example$CQL/grant_role.cql[]
----

This statement grants the `report_writer` role to `alice`. Any
permissions granted to `report_writer` are also acquired by `alice`.

Roles are modelled as a directed acyclic graph, so circular grants are
not permitted. The following examples result in error conditions:

[source,cql]
----
include::cassandra:example$CQL/role_error.cql[]
----

[[revoke-role-statement]]
== REVOKE ROLE

Revoking a role uses the `REVOKE ROLE` statement:

[source, bnf]
----
include::cassandra:example$BNF/revoke_role_statement.bnf[]
----

For example:

[source,cql]
----
include::cassandra:example$CQL/revoke_role.cql[]
----

This statement revokes the `report_writer` role from `alice`. Any
permissions that `alice` has acquired via the `report_writer` role are
also revoked.

[[list-roles-statement]]
== LIST ROLES

All the known roles (in the system or granted to specific role) can be
listed using the `LIST ROLES` statement:

[source, bnf]
----
include::cassandra:example$BNF/list_roles_statement.bnf[]
----

For instance:

[source,cql]
----
include::cassandra:example$CQL/list_roles.cql[]
----

returns all known roles in the system, this requires `DESCRIBE`
permission on the database roles resource.

This example enumerates all roles granted to `alice`, including those transitively
acquired:

[source,cql]
----
include::cassandra:example$CQL/list_roles_of.cql[]
----

This example lists all roles directly granted to `bob` without including any of the
transitively acquired ones:

[source,cql]
----
include::cassandra:example$CQL/list_roles_nonrecursive.cql[]
----

[[list-superusers-statement]]
== LIST SUPERUSERS

All the known roles (including transitively acquired) with superuser privilege can be listed using the `LIST SUPERUSERS` statement:

[source, bnf]
----
include::cassandra:example$BNF/list_superusers_statement.bnf[]
----

This command requires `DESCRIBE` permission on all roles of the database.

== Users

Prior to the introduction of roles in Cassandra 2.2, authentication and
authorization were based around the concept of a `USER`. For backward
compatibility, the legacy syntax has been preserved with `USER` centric
statements becoming synonyms for the `ROLE` based equivalents. In other
words, creating/updating a user is just a different syntax for
creating/updating a role.

[[create-user-statement]]
=== CREATE USER

Creating a user uses the `CREATE USER` statement:

[source, bnf]
----
include::cassandra:example$BNF/create_user_statement.bnf[]
----

For example:

[source,cql]
----
include::cassandra:example$CQL/create_user.cql[]
----

The `CREATE USER` command is equivalent to `CREATE ROLE` where the `LOGIN` option is `true`.
So, the following pairs of statements are equivalent:

[source,cql]
----
include::cassandra:example$CQL/create_user_role.cql[]
----

[[alter-user-statement]]
=== ALTER USER

Altering the options of a user uses the `ALTER USER` statement:

[source, bnf]
----
include::cassandra:example$BNF/alter_user_statement.bnf[]
----
If the role does not exist, the statement will return an error, unless `IF EXISTS` is used in which case the operation is a no-op.
For example:

[source,cql]
----
include::cassandra:example$CQL/alter_user.cql[]
----

[[drop-user-statement]]
=== DROP USER

Dropping a user uses the `DROP USER` statement:

[source, bnf]
----
include::cassandra:example$BNF/drop_user_statement.bnf[]
----

[[list-users-statement]]
=== LIST USERS

Existing users can be listed using the `LIST USERS` statement:

[source, bnf]
----
include::cassandra:example$BNF/list_users_statement.bnf[]
----

Note that this statement is equivalent to xref:cassandra:developing/cql/security.adoc#list-roles-statement[LIST ROLES], but only roles with the `LOGIN` privilege are included in the output.

[[databaseIdentity]]
=== Database Identities

[[AddIdentityStmt]]
==== ADD IDENTITY

_Syntax:_

[source,bnf]
::= ADD IDENTITY [ IF NOT EXISTS ] id_name TO ROLE role_name

_Sample:_

[source,sql]
ADD IDENTITY 'id1' TO ROLE 'role1';

Only a user with privileges to add roles can add identities.

Role names & Identity names should be quoted if they contain non-alphanumeric characters.

[[addIdentityConditional]]
===== Adding an identity conditionally

Attempting to add an existing identity results in an invalid query
condition unless the `IF NOT EXISTS` option is used. If the option is
used and the identity exists, the statement is a no-op.

[source,sql]
ADD IDENTITY [ IF NOT EXISTS ] 'id1' TO ROLE 'role1';

[[dropIdentityStmt]]
==== DROP IDENTITY

_Syntax:_

[source,bnf]
::= DROP IDENTITY [ IF EXISTS ]

_Sample:_

[source,sql]
----
DROP IDENTITY 'testIdentity';
DROP IDENTITY IF EXISTS 'testIdentity';
----

Only a user with privileges to drop roles can remove identities

Attempting to drop an identity which does not exist results in an invalid
query condition unless the `IF EXISTS` option is used. If the option is
used and the identity does not exist the statement is a no-op.

[[dataControl]]
== Data Control

[[cql-permissions]]
=== Permissions

Permissions on resources are granted to roles; there are several
different types of resources in Cassandra and each type is modelled
hierarchically:

* The hierarchy of Data resources, Keyspaces and Tables has the
structure `ALL KEYSPACES` -> `KEYSPACE` -> `TABLE`.
* Function resources have the structure `ALL FUNCTIONS` -> `KEYSPACE` ->
`FUNCTION`
* Resources representing roles have the structure `ALL ROLES` -> `ROLE`
* Resources representing JMX ObjectNames, which map to sets of
MBeans/MXBeans, have the structure `ALL MBEANS` -> `MBEAN`

Permissions can be granted at any level of these hierarchies and they
flow downwards. So granting a permission on a resource higher up the
chain automatically grants that same permission on all resources lower
down. For example, granting `SELECT` on a `KEYSPACE` automatically
grants it on all `TABLES` in that `KEYSPACE`. Likewise, granting a
permission on `ALL FUNCTIONS` grants it on every defined function,
regardless of which keyspace it is scoped in. It is also possible to
grant permissions on all functions scoped to a particular keyspace.

Modifications to permissions are visible to existing client sessions;
that is, connections need not be re-established following permissions
changes.

The full set of available permissions is:

* `CREATE`
* `ALTER`
* `DROP`
* `SELECT`
* `MODIFY`
* `AUTHORIZE`
* `DESCRIBE`
* `EXECUTE`
* `UNMASK`
* `SELECT_MASKED`

Not all permissions are applicable to every type of resource. For
instance, `EXECUTE` is only relevant in the context of functions or
mbeans; granting `EXECUTE` on a resource representing a table is
nonsensical. Attempting to `GRANT` a permission on resource to which it
cannot be applied results in an error response. The following
illustrates which permissions can be granted on which types of resource,
and which statements are enabled by that permission.

[cols=",,",options="header",]
|===
|Permission |Resource |Operations

| `CREATE` | `ALL KEYSPACES` | `CREATE KEYSPACE` and `CREATE TABLE` in any keyspace

| `CREATE` | `KEYSPACE` | `CREATE TABLE` in specified keyspace

| `CREATE` | `ALL FUNCTIONS` | `CREATE FUNCTION` in any keyspace and `CREATE AGGREGATE` in any keyspace

| `CREATE` | `ALL FUNCTIONS IN KEYSPACE` | `CREATE FUNCTION` and `CREATE AGGREGATE` in specified keyspace

| `CREATE` | `ALL ROLES` | `CREATE ROLE`

| `ALTER` | `ALL KEYSPACES` | `ALTER KEYSPACE` and `ALTER TABLE` in any keyspace

| `ALTER` | `KEYSPACE` | `ALTER KEYSPACE` and `ALTER TABLE` in specified keyspace

| `ALTER` | `TABLE` | `ALTER TABLE`

| `ALTER` | `ALL FUNCTIONS` | `CREATE FUNCTION` and `CREATE AGGREGATE`: replacing any existing

| `ALTER` | `ALL FUNCTIONS IN KEYSPACE` | `CREATE FUNCTION` and `CREATE AGGREGATE`: replacing existing in specified keyspace

| `ALTER` | `FUNCTION` | `CREATE FUNCTION` and `CREATE AGGREGATE`: replacing existing

| `ALTER` | `ALL ROLES` | `ALTER ROLE` on any role

| `ALTER` | `ROLE` | `ALTER ROLE`

| `DROP` | `ALL KEYSPACES` | `DROP KEYSPACE` and `DROP TABLE` in any keyspace

| `DROP` | `KEYSPACE` | `DROP TABLE` in specified keyspace

| `DROP` | `TABLE` | `DROP TABLE`

| `DROP` | `ALL FUNCTIONS` | `DROP FUNCTION` and `DROP AGGREGATE` in any keyspace

| `DROP` | `ALL FUNCTIONS IN KEYSPACE` | `DROP FUNCTION` and `DROP AGGREGATE` in specified keyspace

| `DROP` | `FUNCTION` | `DROP FUNCTION`

| `DROP` | `ALL ROLES` | `DROP ROLE` on any role

| `DROP` | `ROLE` | `DROP ROLE`

| `SELECT` | `ALL KEYSPACES` | `SELECT` on any table

| `SELECT` | `KEYSPACE` | `SELECT` on any table in specified keyspace

| `SELECT` | `TABLE` | `SELECT` on specified table

| `SELECT` | `ALL MBEANS` | Call getter methods on any mbean

| `SELECT` | `MBEANS` | Call getter methods on any mbean matching a wildcard pattern

| `SELECT` | `MBEAN` | Call getter methods on named mbean

| `MODIFY` | `ALL KEYSPACES` | `INSERT`, `UPDATE`, `DELETE` and `TRUNCATE` on any table

| `MODIFY` | `KEYSPACE` | `INSERT`, `UPDATE`, `DELETE` and `TRUNCATE` on any table in specified
keyspace

| `MODIFY` | `TABLE` | `INSERT`, `UPDATE`, `DELETE` and `TRUNCATE` on specified table

| `MODIFY` | `ALL MBEANS` | Call setter methods on any mbean

| `MODIFY` | `MBEANS` | Call setter methods on any mbean matching a wildcard pattern

| `MODIFY` | `MBEAN` | Call setter methods on named mbean

| `AUTHORIZE` | `ALL KEYSPACES` | `GRANT PERMISSION` and `REVOKE PERMISSION` on any table

| `AUTHORIZE` | `KEYSPACE` | `GRANT PERMISSION` and `REVOKE PERMISSION` on any table in specified keyspace

| `AUTHORIZE` | `TABLE` | `GRANT PERMISSION` and `REVOKE PERMISSION` on specified table

| `AUTHORIZE` | `ALL FUNCTIONS` | `GRANT PERMISSION` and `REVOKE PERMISSION` on any function

| `AUTHORIZE` | `ALL FUNCTIONS IN KEYSPACE` | `GRANT PERMISSION` and `REVOKE PERMISSION` in specified keyspace

| `AUTHORIZE` | `FUNCTION` | `GRANT PERMISSION` and `REVOKE PERMISSION` on specified function

| `AUTHORIZE` | `ALL MBEANS` | `GRANT PERMISSION` and `REVOKE PERMISSION` on any mbean

| `AUTHORIZE` | `MBEANS` | `GRANT PERMISSION` and `REVOKE PERMISSION` on any mbean matching a wildcard pattern

| `AUTHORIZE` | `MBEAN` | `GRANT PERMISSION` and `REVOKE PERMISSION` on named mbean

| `AUTHORIZE` | `ALL ROLES` | `GRANT ROLE` and `REVOKE ROLE` on any role

| `AUTHORIZE` | `ROLES` | `GRANT ROLE` and `REVOKE ROLE` on specified roles

| `DESCRIBE` | `ALL ROLES` | `LIST ROLES` on all roles or only roles granted to another, specified role

| `DESCRIBE` | `ALL MBEANS` | Retrieve metadata about any mbean from the platform's MBeanServer


| `DESCRIBE` | `MBEANS` | Retrieve metadata about any mbean matching a wildcard patter from the
platform's MBeanServer

| `DESCRIBE` | `MBEAN` | Retrieve metadata about a named mbean from the platform's MBeanServer

| `EXECUTE` | `ALL FUNCTIONS` | `SELECT`, `INSERT` and `UPDATE` using any function, and use of any
function in `CREATE AGGREGATE`

| `EXECUTE` | `ALL FUNCTIONS IN KEYSPACE` | `SELECT`, `INSERT` and `UPDATE` using any function in specified keyspace
and use of any function in keyspace in `CREATE AGGREGATE`

| `EXECUTE` | `FUNCTION` | `SELECT`, `INSERT` and `UPDATE` using specified function and use of the function in `CREATE AGGREGATE`

| `EXECUTE` | `ALL MBEANS` | Execute operations on any mbean

| `EXECUTE` | `MBEANS` | Execute operations on any mbean matching a wildcard pattern

| `EXECUTE` | `MBEAN` | Execute operations on named mbean

|`UNMASK` |`ALL KEYSPACES` | See the clear contents of masked columns on any table

|`UNMASK` |`KEYSPACE` | See the clear contents of masked columns on any table in keyspace

|`UNMASK` |`TABLE` | See the clear contents of masked columns on the specified table

|`SELECT_MASKED` | `ALL KEYSPACES` | `SELECT` restricting masked columns on any table

|`SELECT_MASKED` | `KEYSPACE` | `SELECT` restricting masked columns on any table in specified keyspace

|`SELECT_MASKED` | `TABLE` | `SELECT` restricting masked columns on the specified table
|===

[[grant-permission-statement]]
=== GRANT PERMISSION

Granting a permission uses the `GRANT PERMISSION` statement:

[source, bnf]
----
include::cassandra:example$BNF/grant_permission_statement.bnf[]
----

For example:

[source,cql]
----
include::cassandra:example$CQL/grant_perm.cql[]
----

This example gives any user with the role `data_reader` permission to execute
`SELECT` statements on any table across all keyspaces:

[source,cql]
----
include::cassandra:example$CQL/grant_modify.cql[]
----

To give any user with the role `data_writer` permission to perform
`UPDATE`, `INSERT`, `UPDATE`, `DELETE` and `TRUNCATE` queries on all
tables in the `keyspace1` keyspace:

[source,cql]
----
include::cassandra:example$CQL/grant_drop.cql[]
----

To give any user with the `schema_owner` role permissions to `DROP` a specific
`keyspace1.table1`:

[source,cql]
----
include::cassandra:example$CQL/grant_execute.cql[]
----

This command grants any user with the `report_writer` role permission to execute
`SELECT`, `INSERT` and `UPDATE` queries which use the function
`keyspace1.user_function( int )`:

[source,cql]
----
include::cassandra:example$CQL/grant_describe.cql[]
----

This grants any user with the `role_admin` role permission to view any
and all roles in the system with a `LIST ROLES` statement.

==== GRANT PERMISSION FOR ALL TABLES IN A KEYSPACE

Granting permission to all tables and user types in a keyspace uses 
`GRANT <permission-name>` statement:

[source,bnf]
----
include::example$BNF/grant_permission_all_tables_statement.bnf[]
----

For example:

[source,cql]
----
include::example$CQL/grant_drop_all_tables.cql[]
----

This command grants any user with the `user_name` role permission to execute
`DROP` statements on all the tables across the keyspace `keyspace_name`

[source,cql]
----
include::example$CQL/grant_alter_all_tables.cql[]
----

This command grants any user with the `user_name` role permission to execute
`ALTER` statements on all the tables across the keyspace `keyspace_name`

[source,cql]
----
include::example$CQL/grant_modify_all_tables.cql[]
----

This command grants any user with the `user_name` role permission to execute
`MODIFY` statements on all the tables across the keyspace `keyspace_name`

==== GRANT ALL

When the `GRANT ALL` form is used, the appropriate set of permissions is
determined automatically based on the target resource.

==== Automatic Granting

When a resource is created, via a `CREATE KEYSPACE`, `CREATE TABLE`,
`CREATE FUNCTION`, `CREATE AGGREGATE` or `CREATE ROLE` statement, the
creator (the role the database user who issues the statement is
identified as), is automatically granted all applicable permissions on
the new resource.

[[revoke-permission-statement]]
=== REVOKE PERMISSION

Revoking a permission from a role uses the `REVOKE PERMISSION`
statement:

[source, bnf]
----
include::cassandra:example$BNF/revoke_permission_statement.bnf[]
----

For example:

[source,cql]
----
include::cassandra:example$CQL/revoke_perm.cql[]
----

Because of their function in normal driver operations, certain tables
cannot have their `SELECT` permissions revoked. The
following tables will be available to all authorized users regardless of
their assigned role:

[source,cql]
----
include::cassandra:example$CQL/no_revoke.cql[]
----

[[list-permissions-statement]]
=== LIST PERMISSIONS

Listing granted permissions uses the `LIST PERMISSIONS` statement:

[source, bnf]
----
include::cassandra:example$BNF/list_permissions_statement.bnf[]
----

For example:

[source,cql]
----
include::cassandra:example$CQL/list_perm.cql[]
----

Show all permissions granted to `alice`, including those acquired
transitively from any other roles:

[source,cql]
----
include::cassandra:example$CQL/list_all_perm.cql[]
----

Show all permissions on `keyspace1.table1` granted to `bob`, including
those acquired transitively from any other roles. This also includes any
permissions higher up the resource hierarchy which can be applied to
`keyspace1.table1`. For example, should `bob` have `ALTER` permission on
`keyspace1`, that would be included in the results of this query. Adding
the `NORECURSIVE` switch restricts the results to only those permissions
which were directly granted to `bob` or one of `bob`'s roles:

[source,cql]
----
include::cassandra:example$CQL/list_select_perm.cql[]
----

Show any permissions granted to `carlos` or any roles assigned to `carlos`,
limited to `SELECT` permissions on any resource.
