[
https://issues.apache.org/jira/browse/CASSANDRA-7653?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14256878#comment-14256878
]
Sam Tunnicliffe commented on CASSANDRA-7653:
--------------------------------------------
I've taken another run at this, this time without the consideration of
preserving backwards compatibility in IAuthenticator/IAuthorizer.
https://github.com/beobal/cassandra/compare/7653
The concept of users is replaced by roles and in the postgres style there's no
real differentiation between the two, a user being basically an alias for a
role. As such, grants are made between roles and permissions hierarchies are
enabled. Somewhat distinct from permissions, a role may have a number of
options. Another departure from the previous implementation is that when using
custom auth components there no longer exists the requirement to create
users/roles directly in the database.
h4. CQL Syntax Changes
There are no changes to existing CQL syntax, only additional statements.
{code}
CREATE ROLE [IF NOT EXISTS] <rolename> [WITH PASSWORD <password>]
[SUPERUSER|NOSUPERUSER] [LOGIN|NOLOGIN]
ALTER ROLE <rolename> [WITH PASSWORD <password>] [SUPERUSER|NOSUPERUSER]
[LOGIN|NOLOGIN]
DROP ROLE [IF EXISTS] <rolename>
LIST ROLES [OF <rolename>] [NORECURSIVE]
{code}
The output of {{LIST ROLES}} varies depending on the privileges of the user
running the statement.
Without {{OF <rolename>}} option:
* If executed by a superuser, list all roles in the system
* If executed by a non-superuser, list all roles granted to that user
With {{OF <rolename>}} option:
* If executed by a superuser, list roles granted to for the specific role.
* If executed by a non-superuser, the executing user must be a member of the
specified role (either directly or through inheritence).
The {{NORECURSIVE}} option modifies {{LIST ROLES OF <rolename>}} statements to
include only roles granted directly to the specified role. Memberships acquired
through inheritance are excluded.
For backwards compatibility, {{CREATE USER}}, {{ALTER USER}}, {{DROP USER}} &
{{LIST USERS}} become aliases for the equivalent role-centric statements. In
the case of {{CREATE USER}} & {{ALTER USER}} statements, the role is assumed to
have {{LOGIN}} privilege. So the two following statements are equivalent:
{code}
CREATE USER foo WITH PASSWORD 'bar' NOSUPERUSER
CREATE ROLE foo WITH PASSWORD 'bar' NOSUPERUSER LOGIN
{code}
Accordingly, the {{LOGIN}} & {{NOLOGIN}} options are not permitted with
{{CREATE}} and {{ALTER USER}}.
Granting of roles is straightforward. The default internal implementation will
disallow any grant that introduces a circular relationship.
{code}
GRANT <rolename> TO <rolename>
REVOKE <rolename> FROM <rolename>
{code}
Granting and revoking of permissions to roles is unchanged, except that
conceptually the grantee is now a role, rather than a user.
h4. Code changes
h5. IRoleManager
This is a new entity with responsibility for all aspects of role management,
creation/deletion/modification as well as checking for existence during
modification operations. A number of the functions here are simply the old user
management methods previously part of IAuthenticator.
h5. IAuthenticator
The changes here are twofold: removing responsibility for user (role)
management and making SASL the primary authentication mechanism.
h5. IAuthorizer
Minimal changes to this interface, really it's just the semantics that have
changed slightly.
h4. Schema changes for Internal Implementations
h5. Authentication
As role management is now the solely the responsibility of IRoleManager,
IAuthenticator impls generally (and PasswordAuthenticator specifically) no
longer have the means to modify role info. The benefit to that is the
simplification of IAuthenticator's responsibilities, the downside is potential
coupling between IAuthenticator and IRoleManager implementations. For example,
PasswordAuthenticator no longer maintains its own credentials table, instead it
uses the roles table managed by CassandraAuthorizer.
h5. Role Management
The primary table (roles) here is an extension of the existing users table,
previously managed by PasswordAuthenticator. In addition to superuser status of
a role, the option that determines whether the role has login privileges is
held here along with the an password (if PasswordAuthenticator is enabled).
h5. Authorization
As with IAuthorizer, there are minimal changes to the schema of the table used
by CassandraAuthorizer.
h4. Upgrading
The process for converting auth data during a rolling upgrade is fairly
straightforward. As each node is restarted, it will attempt to convert any data
in the legacy tables into the new schema. Until enough nodes to satisfy the
replication strategy for the system_auth keyspace are upgraded and so have the
new schema, this conversion will fail with the failure being reported in the
system log.
During the upgrade, PasswordAuthenticator, CassandraRoleManager &
CassandraAuthorizer will continue to use the legacy tables, so clients should
experience no disruption (* see below for a caveat). Issuing DCL statements
during upgrade is not supported. Once all nodes are upgraded, an operator with
superuser privileges should drop the legacy tables, which will prompt PA, CRM
and CA to switch over to the new tables without requiring a further rolling
restart.
There is currently an issue with running with a mixed cluster during upgrades.
The python driver seems to have a problem in this scenario which both breaks
cqlsh and makes a dtest problematic. I haven't fully investigated yet, but I'm
pretty sure the problem is on the driver side as the connecting with the
java-driver to a mixed cluster doesn't display the same behaviour (I've
attached 2 smoke tests which demonstrate this). Once the cluster is fully
upgraded, authenticated connections from python function normally again.
h4. Tests
New dtest roles fixture, based on the one mentioned above by Mike:
https://github.com/beobal/cassandra-dtest/commit/5df94a9e9839fe25d67e356b41c59fca60df1dd7
I've also written a dtest for verifying the upgrade process, but it still needs
some work (there's the driver issue and the fact that switching versions in
dtest requires a committed branch in the apache repo). Current wip:
https://github.com/beobal/cassandra-dtest/commit/0a6b16f283d49d008e226e3e0ee2e95da096cbe6
> Add role based access control to Cassandra
> ------------------------------------------
>
> Key: CASSANDRA-7653
> URL: https://issues.apache.org/jira/browse/CASSANDRA-7653
> Project: Cassandra
> Issue Type: New Feature
> Components: Core
> Reporter: Mike Adamson
> Assignee: Sam Tunnicliffe
> Fix For: 3.0
>
> Attachments: 7653.patch
>
>
> The current authentication model supports granting permissions to individual
> users. While this is OK for small or medium organizations wanting to
> implement authorization, it does not work well in large organizations because
> of the overhead of having to maintain the permissions for each user.
> Introducing roles into the authentication model would allow sets of
> permissions to be controlled in one place as a role and then the role granted
> to users. Roles should also be able to be granted to other roles to allow
> hierarchical sets of permissions to be built up.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)