Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RFC]support RBAC #126

Open
3 of 6 tasks
Tracked by #141
jinmingjian opened this issue Jun 14, 2021 · 7 comments
Open
3 of 6 tasks
Tracked by #141

[RFC]support RBAC #126

jinmingjian opened this issue Jun 14, 2021 · 7 comments

Comments

@jinmingjian
Copy link
Contributor

jinmingjian commented Jun 14, 2021

this will be done in some configuration file rather than DDL dialect in ClickHouse

We may reuse some existed libraries, for example, casbin-rs.

  • 1.0 BRSL(Base Resources Spec Language)
    • casbin-rs investigation(use or not use?)
    • RFC for lang
  • 2.0 In-Base Auth Implementation
    • primary user/password impl
    • popular 3rd-party auth platform
@frank-king
Copy link
Contributor

frank-king commented Jul 20, 2021

@jinmingjian I'm glad that the casbin-rs community is helping us to do this, so I update our primary plans here based on the discussions before. Please correct me if there is any problem.

Basically, we need two kinds of policies, which:

  1. describes which users have access to which databases/tables, in particular access patterns (e.g. read/write/update/...),
  2. describes which users have access to which computing resources, how many quotas, and the priorities.

These two rules might be described by:

[policy_definition]
data = user, table, action
resource = user, type, quota, priority

In addition, we need to find a way to dynamically update the policies during runtime. This might be done by a housekeeper which loads the policy file immediately after it changes. Or it would be nice if casbin-rs can support this function.

@rushitote
Copy link

rushitote commented Jul 25, 2021

@whjpji

So, this is based on my understanding of the policy requirement. I think this would need two Casbin enforcers based on the two policy requirements.

For the first case, we could simply use a Access Control List based policy if all users have not so much databases/access patterns in common. Otherwise if there are many users who have access to a specific database with the same access patterns, we could optimize it to use a RBAC model. For example, the model in this case could be:

[request_definition]
r = usr, id, act  # user, database-id, access pattern

[policy_definition]
p = usr, id, act # policy user, database-id, access pattern

[role_definition]
g = _, _

[policy_effect]
e = some(where (p.eft == allow))

[matchers]
m = g(r.usr, p.usr) && r.id == p.id && keyMatch(r.act, p.act)

And the policy could be:

p, database1_read, database1, read
p, database1_admin, database1, *
... (other policies)

g, user1, database1_read
g, user2, database1_read
g, user3, database1_admin
... (other policies)

This would mean user1 and user2 have read access to database1 while user3 has admin access to it.

For the second case, assuming quota means quota limits we can create a similar RBAC model for this which will use the priority effect. An example model could be:

[request_definition]
r = usr, quota  # user, quota used

[policy_definition]
p = priority, usr, quota, eft # policy priority, user, quota limits, effect (allow or deny)

[role_definition]
g = _, _

[policy_effect]
e = priority(p.eft) || deny

[matchers]
m = g(r.usr, p.usr) && (r.quota<p.quota)

And the policy could be:

p, 10, res1_group1, 100, allow
p, 10, res1_group2, 50, allow
... (other policies)

g, user1, res1_group1
g, user2, res1_group2
... (other policies)

So, when we send an enforcement request with user and quota used parameters - it compares if the user has access to the computing resources and if the current used quota is lesser than the quota limits. Here res1_group1 maybe some specific computing resources with quota limit of 100. And since user1 has a role as that, it would have a quota limit of 100.

This is just a rough idea, I believe this can be made better. Please correct me if anything is wrong.

(cc: @hsluoyz @hackerchai @PsiACE)

@jinmingjian
Copy link
Contributor Author

@whjpji thanks for updating detailed thoughts for this issue. I think we should have a unified model rather than two. And there are some dynamic requirements like quote here.

@jinmingjian jinmingjian changed the title support RBAC [RFC]support RBAC Jul 25, 2021
@jinmingjian
Copy link
Contributor Author

@rushitote thanks for sharing your great idea! It is a good material to reference!

@frank-king
Copy link
Contributor

Based on the current capability of TB, I have a primary plan to support access control:

  1. First to add a system.user table to store user infos (user ID, username, password, etc.). At the first handshake of the client and server, the user is verified by password.
  2. Then each query needs to be associated with a specific user, which is useful to verify whether the user has access to the queried table.
  3. Next, introduce casbin to determine whether the user should be authorized to access the table in read/write/update/delete by some policy rules. BTW, the casbin policy are better to stored in a dedicated table (like system.policy) instead of CSV, because CSV is hard to revise in runtime and will be hard to read or write when the rules become more complicated.
  4. Finally, to make the authentication actually work, connections with SSL/TLS should be introduced to secure that the user from any client is identical to the registered user in db.

@jinmingjian
Copy link
Contributor Author

@whjpji self-hosted access control is cool, and we thanks for casbin framework for policy as well:)

@frank-king
Copy link
Contributor

Blocked on #230, and I'm going to fix it first.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants