Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 813270d

Browse files
chore: bump github.com/open-policy-agent/opa from 0.70.0 to 1.0.0 (#16013)
Opting into rego v1. Rego v1 requires `if` for all rule statements. This PR updates the dependencies and the rego policy itself. Golang imports upgraded for opa/rego --------- Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
1 parent 4495db8 commit 813270d

File tree

7 files changed

+127
-107
lines changed

7 files changed

+127
-107
lines changed

coderd/rbac/authz.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import (
1212

1313
"github.com/ammario/tlru"
1414
"github.com/open-policy-agent/opa/ast"
15-
"github.com/open-policy-agent/opa/rego"
15+
"github.com/open-policy-agent/opa/v1/rego"
1616
"github.com/prometheus/client_golang/prometheus"
1717
"github.com/prometheus/client_golang/prometheus/promauto"
1818
"go.opentelemetry.io/otel/attribute"

coderd/rbac/error.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ import (
66
"flag"
77
"fmt"
88

9-
"github.com/open-policy-agent/opa/rego"
109
"github.com/open-policy-agent/opa/topdown"
10+
"github.com/open-policy-agent/opa/v1/rego"
1111
"golang.org/x/xerrors"
1212

1313
"github.com/coder/coder/v2/coderd/httpapi/httpapiconstraints"

coderd/rbac/policy.rego

Lines changed: 84 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package authz
2-
import future.keywords
2+
3+
import rego.v1
4+
35
# A great playground: https://play.openpolicyagent.org/
46
# Helpful cli commands to debug.
57
# opa eval --format=pretty 'data.authz.allow' -d policy.rego -i input.json
@@ -29,67 +31,74 @@ import future.keywords
2931

3032
# bool_flip lets you assign a value to an inverted bool.
3133
# You cannot do 'x := !false', but you can do 'x := bool_flip(false)'
32-
bool_flip(b) = flipped {
33-
b
34-
flipped = false
34+
bool_flip(b) := flipped if {
35+
b
36+
flipped = false
3537
}
3638

37-
bool_flip(b) = flipped {
38-
not b
39-
flipped = true
39+
bool_flip(b) := flipped if {
40+
not b
41+
flipped = true
4042
}
4143

4244
# number is a quick way to get a set of {true, false} and convert it to
4345
# -1: {false, true} or {false}
4446
# 0: {}
4547
# 1: {true}
46-
number(set) = c {
48+
number(set) := c if {
4749
count(set) == 0
48-
c := 0
50+
c := 0
4951
}
5052

51-
number(set) = c {
53+
number(set) := c if {
5254
false in set
53-
c := -1
55+
c := -1
5456
}
5557

56-
number(set) = c {
58+
number(set) := c if {
5759
not false in set
5860
set[_]
59-
c := 1
61+
c := 1
6062
}
6163

6264
# site, org, and user rules are all similar. Each rule should return a number
6365
# from [-1, 1]. The number corresponds to "negative", "abstain", and "positive"
6466
# for the given level. See the 'allow' rules for how these numbers are used.
65-
default site = 0
67+
default site := 0
68+
6669
site := site_allow(input.subject.roles)
70+
6771
default scope_site := 0
72+
6873
scope_site := site_allow([input.subject.scope])
6974

70-
site_allow(roles) := num {
75+
site_allow(roles) := num if {
7176
# allow is a set of boolean values without duplicates.
72-
allow := { x |
77+
allow := {x |
7378
# Iterate over all site permissions in all roles
74-
perm := roles[_].site[_]
75-
perm.action in [input.action, "*"]
79+
perm := roles[_].site[_]
80+
perm.action in [input.action, "*"]
7681
perm.resource_type in [input.object.type, "*"]
82+
7783
# x is either 'true' or 'false' if a matching permission exists.
78-
x := bool_flip(perm.negate)
79-
}
80-
num := number(allow)
84+
x := bool_flip(perm.negate)
85+
}
86+
num := number(allow)
8187
}
8288

8389
# org_members is the list of organizations the actor is apart of.
84-
org_members := { orgID |
90+
org_members := {orgID |
8591
input.subject.roles[_].org[orgID]
8692
}
8793

8894
# org is the same as 'site' except we need to iterate over each organization
8995
# that the actor is a member of.
90-
default org = 0
96+
default org := 0
97+
9198
org := org_allow(input.subject.roles)
99+
92100
default scope_org := 0
101+
93102
scope_org := org_allow([input.scope])
94103

95104
# org_allow_set is a helper function that iterates over all orgs that the actor
@@ -102,10 +111,10 @@ scope_org := org_allow([input.scope])
102111
# The reason we calculate this for all orgs, and not just the input.object.org_owner
103112
# is that sometimes the input.object.org_owner is unknown. In those cases
104113
# we have a list of org_ids that can we use in a SQL 'WHERE' clause.
105-
org_allow_set(roles) := allow_set {
106-
allow_set := { id: num |
114+
org_allow_set(roles) := allow_set if {
115+
allow_set := {id: num |
107116
id := org_members[_]
108-
set := { x |
117+
set := {x |
109118
perm := roles[_].org[id][_]
110119
perm.action in [input.action, "*"]
111120
perm.resource_type in [input.object.type, "*"]
@@ -115,7 +124,7 @@ org_allow_set(roles) := allow_set {
115124
}
116125
}
117126

118-
org_allow(roles) := num {
127+
org_allow(roles) := num if {
119128
# If the object has "any_org" set to true, then use the other
120129
# org_allow block.
121130
not input.object.any_org
@@ -135,78 +144,82 @@ org_allow(roles) := num {
135144
# This is useful for UI elements when we want to conclude, "Can the user create
136145
# a new template in any organization?"
137146
# It is easier than iterating over every organization the user is apart of.
138-
org_allow(roles) := num {
147+
org_allow(roles) := num if {
139148
input.object.any_org # if this is false, this code block is not used
140149
allow := org_allow_set(roles)
141150

142-
143151
# allow is a map of {"<org_id>": <number>}. We only care about values
144152
# that are 1, and ignore the rest.
145153
num := number([
146-
keep |
147-
# for every value in the mapping
148-
value := allow[_]
149-
# only keep values > 0.
150-
# 1 = allow, 0 = abstain, -1 = deny
151-
# We only need 1 explicit allow to allow the action.
152-
# deny's and abstains are intentionally ignored.
153-
value > 0
154-
# result set is a set of [true,false,...]
155-
# which "number()" will convert to a number.
156-
keep := true
154+
keep |
155+
# for every value in the mapping
156+
value := allow[_]
157+
158+
# only keep values > 0.
159+
# 1 = allow, 0 = abstain, -1 = deny
160+
# We only need 1 explicit allow to allow the action.
161+
# deny's and abstains are intentionally ignored.
162+
value > 0
163+
164+
# result set is a set of [true,false,...]
165+
# which "number()" will convert to a number.
166+
keep := true
157167
])
158168
}
159169

160170
# 'org_mem' is set to true if the user is an org member
161171
# If 'any_org' is set to true, use the other block to determine org membership.
162-
org_mem := true {
172+
org_mem if {
163173
not input.object.any_org
164174
input.object.org_owner != ""
165175
input.object.org_owner in org_members
166176
}
167177

168-
org_mem := true {
178+
org_mem if {
169179
input.object.any_org
170180
count(org_members) > 0
171181
}
172182

173-
org_ok {
183+
org_ok if {
174184
org_mem
175185
}
176186

177187
# If the object has no organization, then the user is also considered part of
178188
# the non-existent org.
179-
org_ok {
189+
org_ok if {
180190
input.object.org_owner == ""
181191
not input.object.any_org
182192
}
183193

184194
# User is the same as the site, except it only applies if the user owns the object and
185195
# the user is apart of the org (if the object has an org).
186-
default user = 0
196+
default user := 0
197+
187198
user := user_allow(input.subject.roles)
199+
188200
default user_scope := 0
201+
189202
scope_user := user_allow([input.scope])
190203

191-
user_allow(roles) := num {
192-
input.object.owner != ""
193-
input.subject.id = input.object.owner
194-
allow := { x |
195-
perm := roles[_].user[_]
196-
perm.action in [input.action, "*"]
204+
user_allow(roles) := num if {
205+
input.object.owner != ""
206+
input.subject.id = input.object.owner
207+
allow := {x |
208+
perm := roles[_].user[_]
209+
perm.action in [input.action, "*"]
197210
perm.resource_type in [input.object.type, "*"]
198-
x := bool_flip(perm.negate)
199-
}
200-
num := number(allow)
211+
x := bool_flip(perm.negate)
212+
}
213+
num := number(allow)
201214
}
202215

203216
# Scope allow_list is a list of resource IDs explicitly allowed by the scope.
204217
# If the list is '*', then all resources are allowed.
205-
scope_allow_list {
218+
scope_allow_list if {
206219
"*" in input.subject.scope.allow_list
207220
}
208221

209-
scope_allow_list {
222+
scope_allow_list if {
210223
# If the wildcard is listed in the allow_list, we do not care about the
211224
# object.id. This line is included to prevent partial compilations from
212225
# ever needing to include the object.id.
@@ -226,66 +239,70 @@ scope_allow_list {
226239
# Allow query:
227240
# data.authz.role_allow = true data.authz.scope_allow = true
228241

229-
role_allow {
242+
role_allow if {
230243
site = 1
231244
}
232245

233-
role_allow {
246+
role_allow if {
234247
not site = -1
235248
org = 1
236249
}
237250

238-
role_allow {
251+
role_allow if {
239252
not site = -1
240253
not org = -1
254+
241255
# If we are not a member of an org, and the object has an org, then we are
242256
# not authorized. This is an "implied -1" for not being in the org.
243257
org_ok
244258
user = 1
245259
}
246260

247-
scope_allow {
261+
scope_allow if {
248262
scope_allow_list
249263
scope_site = 1
250264
}
251265

252-
scope_allow {
266+
scope_allow if {
253267
scope_allow_list
254268
not scope_site = -1
255269
scope_org = 1
256270
}
257271

258-
scope_allow {
272+
scope_allow if {
259273
scope_allow_list
260274
not scope_site = -1
261275
not scope_org = -1
276+
262277
# If we are not a member of an org, and the object has an org, then we are
263278
# not authorized. This is an "implied -1" for not being in the org.
264279
org_ok
265280
scope_user = 1
266281
}
267282

268283
# ACL for users
269-
acl_allow {
284+
acl_allow if {
270285
# Should you have to be a member of the org too?
271286
perms := input.object.acl_user_list[input.subject.id]
287+
272288
# Either the input action or wildcard
273289
[input.action, "*"][_] in perms
274290
}
275291

276292
# ACL for groups
277-
acl_allow {
293+
acl_allow if {
278294
# If there is no organization owner, the object cannot be owned by an
279295
# org_scoped team.
280296
org_mem
281297
group := input.subject.groups[_]
282298
perms := input.object.acl_group_list[group]
299+
283300
# Either the input action or wildcard
284301
[input.action, "*"][_] in perms
285302
}
286303

287304
# ACL for 'all_users' special group
288-
acl_allow {
305+
acl_allow if {
289306
org_mem
290307
perms := input.object.acl_group_list[input.object.org_owner]
291308
[input.action, "*"][_] in perms
@@ -296,13 +313,13 @@ acl_allow {
296313
# The role or the ACL must allow the action. Scopes can be used to limit,
297314
# so scope_allow must always be true.
298315

299-
allow {
316+
allow if {
300317
role_allow
301318
scope_allow
302319
}
303320

304321
# ACL list must also have the scope_allow to pass
305-
allow {
322+
allow if {
306323
acl_allow
307324
scope_allow
308325
}

coderd/rbac/regosql/compile.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import (
55
"strings"
66

77
"github.com/open-policy-agent/opa/ast"
8-
"github.com/open-policy-agent/opa/rego"
8+
"github.com/open-policy-agent/opa/v1/rego"
99
"golang.org/x/xerrors"
1010

1111
"github.com/coder/coder/v2/coderd/rbac/regosql/sqltypes"

coderd/rbac/regosql/compile_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import (
44
"testing"
55

66
"github.com/open-policy-agent/opa/ast"
7-
"github.com/open-policy-agent/opa/rego"
7+
"github.com/open-policy-agent/opa/v1/rego"
88
"github.com/stretchr/testify/require"
99

1010
"github.com/coder/coder/v2/coderd/rbac/regosql"

0 commit comments

Comments
 (0)