Skip to content

Commit 4593b2d

Browse files
gen1us2kvinckr
authored andcommitted
fix: added rbac guide for keto
1 parent 14fb5ba commit 4593b2d

File tree

1 file changed

+231
-3
lines changed

1 file changed

+231
-3
lines changed

docs/keto/guides/rbac.mdx

+231-3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,234 @@
22
title: Role Based Access Control (RBAC)
33
---
44

5-
This guide will explain how to implement RBAC using Ory Keto. It's still work in
6-
progress. If you happened to figure this out yourself, please open a PR to add
7-
your findings on this page.
5+
This guide will explain how to implement RBAC using Ory Keto.
6+
7+
:::warning
8+
9+
Implementing RBAC currently is possible, but requires some workarounds. This
10+
guide enables RBAC support with Keto but native support is still work in
11+
progress. Follow the progress in
12+
[this issue](https://github.com/ory/keto/issues/598)
13+
:::
14+
15+
[Role Based Access Control (RBAC)](https://en.wikipedia.org/wiki/Role-based_access_control)
16+
maps subjects to roles and roles to permissions. The goal of (H)RBAC is to make
17+
permission management convenient by grouping subjects in roles and assigning
18+
permissions roles. This type of access control is common in web applications
19+
where one often encounters roles such as "administrator", "moderator", and so
20+
on.
21+
22+
In **Hierarchical Role Based Access Control (HRBAC)** roles can inherit
23+
permissions from other roles. The "administrator" role, for example, could
24+
inherit all permissions from the "moderator" role. This reduces duplication and
25+
management complexity around defining privileges.
26+
27+
Let's assume that we are building a reporting application and need to have three
28+
groups of users with different access levels.
29+
We have the following group of reports in our application.
30+
31+
- Financial performance reports
32+
- Marketing performance reports
33+
- Community performance reports
34+
35+
This time we model the access rights using (H)RBAC and the roles
36+
`community`, `marketing`, `finance` and `admin`:
37+
38+
The role `admin` inherits all privileges from `finance`, `marketing` and `community`
39+
40+
(H)RBAC is everywhere. If you ever installed a forum software such as
41+
[phpBB](https://www.phpbb.com/support/docs/en/3.1/ug/adminguide/permissions_roles/)
42+
or [Wordpress](https://codex.wordpress.org/Roles_and_Capabilities), you have
43+
definitely encountered ACL, (H)RBAC, or both.
44+
45+
(H)RBAC reduces management complexity and overhead with large user bases.
46+
Sometimes however, even (H)RBAC is not enough. An example is when you need to
47+
express ownership (e.g. `Dilan` can only modify his own reports), have
48+
attributes (e.g. `Dilan` needs to have access only during work hours),
49+
or in multi-tenant environments.
50+
51+
**Benefits:**
52+
53+
- Reduces management complexity when many identities share similar permissions.
54+
- Role hierarchies can reduce redundancy even further.
55+
- Is well established and easily understood by many developers as it is a
56+
de-facto standard for web applications.
57+
58+
**Shortcomings:**
59+
60+
- Has no concept of context:
61+
- There is no concept of ownership: _Dan is the author of article "Hello
62+
World" and is thus allowed to update it_.
63+
- There is no concept of environment: _Dan is allowed to access accounting
64+
services when the request comes from IP 10.0.0.3_.
65+
- There is no concept of tenants: _Dan is allowed to access resources on the
66+
"dan's test" tenant_.
67+
68+
## Using RBAC with Ory Keto
69+
70+
We need to have three groups, `finance`, `marketing`, `community`. Also, we need
71+
to have two namespaces: `reports` to manage access control and `groups` to add
72+
users to this group
73+
74+
Let's add namespaces to Keto config.
75+
[here](https://www.ory.sh/docs/keto/reference/configuration)
76+
77+
```yaml
78+
# ...
79+
namespaces:
80+
- id: 0
81+
name: groups
82+
- id: 1
83+
name: reports
84+
#...
85+
```
86+
87+
We can have two types of permission to access reports for granularity. Let's
88+
assume that we need `edit` and `view` access to the reports.
89+
90+
```keto-relation-tuples
91+
// View only access for finance department
92+
reports:finance#view@(groups:finance#member)
93+
// View only access for community department
94+
reports:community#view@(groups:community#member)
95+
// View only access for marketing department
96+
reports:marketing#view@(groups:marketing#member)
97+
// Edit access for admin group
98+
reports:finance#edit@(groups:admin#member)
99+
reports:community#edit@(groups:admin#member)
100+
reports:marketing#edit@(groups:admin#member)
101+
reports:finance#view@(groups:admin#member)
102+
reports:community#view@(groups:admin#member)
103+
reports:marketing#view@(groups:admin#member)
104+
```
105+
106+
Let's assume that we have four people in our organization. Lila is CFO and needs
107+
access to financial reports, Hadley works in marketing, and Dilan works as a
108+
community manager. Neel is an admin of a system and needs to have edit
109+
permissions for reports.
110+
111+
```keto-relation-tuples
112+
groups:finance#member@Lila
113+
groups:community#member@Dilan
114+
groups:marketing#member@Hadley
115+
groups:admin#member@Neel
116+
```
117+
118+
## Creating Relation Tuples
119+
120+
Let's copy all permissions we created to a `policies.rts` file with the
121+
following content.
122+
123+
```keto-relation-tuples
124+
reports:finance#view@(groups:finance#member)
125+
reports:community#view@(groups:community#member)
126+
reports:marketing#view@(groups:marketing#member)
127+
reports:finance#edit@(groups:admin#member)
128+
reports:community#edit@(groups:admin#member)
129+
reports:marketing#edit@(groups:admin#member)
130+
reports:finance#view@(groups:admin#member)
131+
reports:community#view@(groups:admin#member)
132+
reports:marketing#view@(groups:admin#member)
133+
groups:finance#member@Lila
134+
groups:community#member@Dilan
135+
groups:marketing#member@Hadley
136+
groups:admin#member@Neel
137+
```
138+
139+
140+
Then we can run
141+
142+
```bash
143+
keto relation-tuple parse policies.rts --format json | \
144+
keto relation-tuple create - >/dev/null \
145+
&& echo "Successfully created tuple" \
146+
|| echo "Encountered error"
147+
```
148+
149+
150+
Since Dilan works as a community manager, the following check examples show that
151+
he has access only to community reports
152+
153+
```bash
154+
keto check Dilan view reports finance
155+
Denied
156+
keto check Dilan view reports community
157+
Allowed
158+
keto check Dilan edit reports community
159+
Denied
160+
```
161+
162+
Now Dilan decided to also work with marketing. Therefore we need to update his
163+
permissions and add him to the marketing group.
164+
165+
```keto-relation-tuples
166+
groups:marketing#member@Dilan
167+
```
168+
169+
Now he also has access to marketing reports:
170+
171+
```
172+
keto check Dilan view reports marketing
173+
Allowed
174+
```
175+
176+
## Display all objects a User has access to
177+
178+
The example below shows you how to get a list of objects Dilan has access to
179+
180+
```bash
181+
# Get all groups for Dilan
182+
curl -s http://localhost:4466/relation-tuples\?subject_id\=Dilan\&relation\=member | jq
183+
{
184+
"relation_tuples": [
185+
{
186+
"namespace": "groups",
187+
"object": "community",
188+
"relation": "member",
189+
"subject_id": "Dilan"
190+
},
191+
{
192+
"namespace": "groups",
193+
"object": "marketing",
194+
"relation": "member",
195+
"subject_id": "Dilan"
196+
}
197+
],
198+
"next_page_token": ""
199+
}
200+
201+
# Get permissions to objects for marketing group
202+
curl -s http://localhost:4466/relation-tuples\?subject_set.namespace\=groups\&subject_set.relation\=member\&subject_set.object\=marketing | jq
203+
{
204+
"relation_tuples": [
205+
{
206+
"namespace": "reports",
207+
"object": "marketing",
208+
"relation": "view",
209+
"subject_set": {
210+
"namespace": "groups",
211+
"object": "marketing",
212+
"relation": "member"
213+
}
214+
}
215+
],
216+
"next_page_token": ""
217+
}
218+
# Get permissions to objects for community group
219+
curl -s http://localhost:4466/relation-tuples\?subject_set.namespace\=groups\&subject_set.relation\=member\&subject_set.object\=marketing | jq
220+
{
221+
"relation_tuples": [
222+
{
223+
"namespace": "reports",
224+
"object": "marketing",
225+
"relation": "view",
226+
"subject_set": {
227+
"namespace": "groups",
228+
"object": "marketing",
229+
"relation": "member"
230+
}
231+
}
232+
],
233+
"next_page_token": ""
234+
}
235+
```

0 commit comments

Comments
 (0)