1
1
package authz
2
- import future.keywords
2
+ import rego.v1
3
+
3
4
# A great playground: https://play.openpolicyagent.org/
4
5
# Helpful cli commands to debug.
5
6
# opa eval --format=pretty 'data.authz.allow' -d policy.rego -i input.json
@@ -29,12 +30,12 @@ import future.keywords
29
30
30
31
# bool_flip lets you assign a value to an inverted bool.
31
32
# You cannot do 'x := !false', but you can do 'x := bool_flip(false)'
32
- bool_flip (b) = flipped {
33
+ bool_flip (b) = flipped if {
33
34
b
34
35
flipped = false
35
36
}
36
37
37
- bool_flip (b) = flipped {
38
+ bool_flip (b) = flipped if {
38
39
not b
39
40
flipped = true
40
41
}
@@ -43,17 +44,17 @@ bool_flip(b) = flipped {
43
44
# -1: {false, true} or {false}
44
45
# 0: {}
45
46
# 1: {true}
46
- number (set) = c {
47
+ number (set) = c if {
47
48
count (set) == 0
48
49
c := 0
49
50
}
50
51
51
- number (set) = c {
52
+ number (set) = c if {
52
53
false in set
53
54
c := - 1
54
55
}
55
56
56
- number (set) = c {
57
+ number (set) = c if {
57
58
not false in set
58
59
set[_]
59
60
c := 1
@@ -67,7 +68,7 @@ site := site_allow(input.subject.roles)
67
68
default scope_site := 0
68
69
scope_site := site_allow ([input.subject.scope])
69
70
70
- site_allow (roles) := num {
71
+ site_allow (roles) := num if {
71
72
# allow is a set of boolean values without duplicates.
72
73
allow := { x |
73
74
# Iterate over all site permissions in all roles
@@ -102,7 +103,7 @@ scope_org := org_allow([input.scope])
102
103
# The reason we calculate this for all orgs, and not just the input.object.org_owner
103
104
# is that sometimes the input.object.org_owner is unknown. In those cases
104
105
# we have a list of org_ids that can we use in a SQL 'WHERE' clause.
105
- org_allow_set (roles) := allow_set {
106
+ org_allow_set (roles) := allow_set if {
106
107
allow_set := { id: num |
107
108
id := org_members[_]
108
109
set := { x |
@@ -115,7 +116,7 @@ org_allow_set(roles) := allow_set {
115
116
}
116
117
}
117
118
118
- org_allow (roles) := num {
119
+ org_allow (roles) := num if {
119
120
# If the object has "any_org" set to true, then use the other
120
121
# org_allow block.
121
122
not input.object.any_org
@@ -135,7 +136,7 @@ org_allow(roles) := num {
135
136
# This is useful for UI elements when we want to conclude, "Can the user create
136
137
# a new template in any organization?"
137
138
# It is easier than iterating over every organization the user is apart of.
138
- org_allow (roles) := num {
139
+ org_allow (roles) := num if {
139
140
input.object.any_org # if this is false, this code block is not used
140
141
allow := org_allow_set (roles)
141
142
@@ -159,24 +160,24 @@ org_allow(roles) := num {
159
160
160
161
# 'org_mem' is set to true if the user is an org member
161
162
# If 'any_org' is set to true, use the other block to determine org membership.
162
- org_mem := true {
163
+ org_mem := true if {
163
164
not input.object.any_org
164
165
input.object.org_owner != " "
165
166
input.object.org_owner in org_members
166
167
}
167
168
168
- org_mem := true {
169
+ org_mem := true if {
169
170
input.object.any_org
170
171
count (org_members) > 0
171
172
}
172
173
173
- org_ok {
174
+ org_ok if {
174
175
org_mem
175
176
}
176
177
177
178
# If the object has no organization, then the user is also considered part of
178
179
# the non-existent org.
179
- org_ok {
180
+ org_ok if {
180
181
input.object.org_owner == " "
181
182
not input.object.any_org
182
183
}
@@ -188,7 +189,7 @@ user := user_allow(input.subject.roles)
188
189
default user_scope := 0
189
190
scope_user := user_allow ([input.scope])
190
191
191
- user_allow (roles) := num {
192
+ user_allow (roles) := num if {
192
193
input.object.owner != " "
193
194
input.subject.id = input.object.owner
194
195
allow := { x |
@@ -202,11 +203,11 @@ user_allow(roles) := num {
202
203
203
204
# Scope allow_list is a list of resource IDs explicitly allowed by the scope.
204
205
# If the list is '*', then all resources are allowed.
205
- scope_allow_list {
206
+ scope_allow_list if {
206
207
" *" in input.subject.scope.allow_list
207
208
}
208
209
209
- scope_allow_list {
210
+ scope_allow_list if {
210
211
# If the wildcard is listed in the allow_list, we do not care about the
211
212
# object.id. This line is included to prevent partial compilations from
212
213
# ever needing to include the object.id.
@@ -226,16 +227,16 @@ scope_allow_list {
226
227
# Allow query:
227
228
# data.authz.role_allow = true data.authz.scope_allow = true
228
229
229
- role_allow {
230
+ role_allow if {
230
231
site = 1
231
232
}
232
233
233
- role_allow {
234
+ role_allow if {
234
235
not site = - 1
235
236
org = 1
236
237
}
237
238
238
- role_allow {
239
+ role_allow if {
239
240
not site = - 1
240
241
not org = - 1
241
242
# If we are not a member of an org, and the object has an org, then we are
@@ -244,18 +245,18 @@ role_allow {
244
245
user = 1
245
246
}
246
247
247
- scope_allow {
248
+ scope_allow if {
248
249
scope_allow_list
249
250
scope_site = 1
250
251
}
251
252
252
- scope_allow {
253
+ scope_allow if {
253
254
scope_allow_list
254
255
not scope_site = - 1
255
256
scope_org = 1
256
257
}
257
258
258
- scope_allow {
259
+ scope_allow if {
259
260
scope_allow_list
260
261
not scope_site = - 1
261
262
not scope_org = - 1
@@ -266,15 +267,15 @@ scope_allow {
266
267
}
267
268
268
269
# ACL for users
269
- acl_allow {
270
+ acl_allow if {
270
271
# Should you have to be a member of the org too?
271
272
perms := input.object.acl_user_list[input.subject.id]
272
273
# Either the input action or wildcard
273
274
[input.action, " *" ][_] in perms
274
275
}
275
276
276
277
# ACL for groups
277
- acl_allow {
278
+ acl_allow if {
278
279
# If there is no organization owner, the object cannot be owned by an
279
280
# org_scoped team.
280
281
org_mem
@@ -285,7 +286,7 @@ acl_allow {
285
286
}
286
287
287
288
# ACL for 'all_users' special group
288
- acl_allow {
289
+ acl_allow if {
289
290
org_mem
290
291
perms := input.object.acl_group_list[input.object.org_owner]
291
292
[input.action, " *" ][_] in perms
@@ -296,13 +297,13 @@ acl_allow {
296
297
# The role or the ACL must allow the action. Scopes can be used to limit,
297
298
# so scope_allow must always be true.
298
299
299
- allow {
300
+ allow if {
300
301
role_allow
301
302
scope_allow
302
303
}
303
304
304
305
# ACL list must also have the scope_allow to pass
305
- allow {
306
+ allow if {
306
307
acl_allow
307
308
scope_allow
308
309
}
0 commit comments