Skip to content

Commit ba1953a

Browse files
committed
Add groups to rego objects
1 parent d70911b commit ba1953a

File tree

3 files changed

+43
-24
lines changed

3 files changed

+43
-24
lines changed

coderd/rbac/authz.go

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -93,20 +93,21 @@ func NewAuthorizer() (*RegoAuthorizer, error) {
9393
}
9494

9595
type authSubject struct {
96-
ID string `json:"id"`
97-
Roles []Role `json:"roles"`
96+
ID string `json:"id"`
97+
Roles []Role `json:"roles"`
98+
Groups []string `json:"groups"`
9899
}
99100

100101
// ByRoleName will expand all roleNames into roles before calling Authorize().
101102
// This is the function intended to be used outside this package.
102103
// The role is fetched from the builtin map located in memory.
103-
func (a RegoAuthorizer) ByRoleName(ctx context.Context, subjectID string, roleNames []string, scope Scope, action Action, object Object) error {
104+
func (a RegoAuthorizer) ByRoleName(ctx context.Context, subjectID string, roleNames []string, groups []string, scope Scope, action Action, object Object) error {
104105
roles, err := RolesByNames(roleNames)
105106
if err != nil {
106107
return err
107108
}
108109

109-
err = a.Authorize(ctx, subjectID, roles, action, object)
110+
err = a.Authorize(ctx, subjectID, roles, groups, action, object)
110111
if err != nil {
111112
return err
112113
}
@@ -118,7 +119,7 @@ func (a RegoAuthorizer) ByRoleName(ctx context.Context, subjectID string, roleNa
118119
return err
119120
}
120121

121-
err = a.Authorize(ctx, subjectID, []Role{scopeRole}, action, object)
122+
err = a.Authorize(ctx, subjectID, []Role{scopeRole}, groups, action, object)
122123
if err != nil {
123124
return err
124125
}
@@ -129,14 +130,15 @@ func (a RegoAuthorizer) ByRoleName(ctx context.Context, subjectID string, roleNa
129130

130131
// Authorize allows passing in custom Roles.
131132
// This is really helpful for unit testing, as we can create custom roles to exercise edge cases.
132-
func (a RegoAuthorizer) Authorize(ctx context.Context, subjectID string, roles []Role, action Action, object Object) error {
133+
func (a RegoAuthorizer) Authorize(ctx context.Context, subjectID string, roles []Role, groups []string, action Action, object Object) error {
133134
ctx, span := tracing.StartSpan(ctx)
134135
defer span.End()
135136

136137
input := map[string]interface{}{
137138
"subject": authSubject{
138-
ID: subjectID,
139-
Roles: roles,
139+
ID: subjectID,
140+
Roles: roles,
141+
Groups: groups,
140142
},
141143
"object": object,
142144
"action": action,

coderd/rbac/object.go

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,8 @@ type Object struct {
160160
// Type is "workspace", "project", "app", etc
161161
Type string `json:"type"`
162162

163-
// map[string][]Action
164-
ACLUserList map[string][]Action ` json:"acl_user_list"`
163+
ACLUserList map[string][]Action ` json:"acl_user_list"`
164+
ACLGroupList map[string][]Action ` json:"acl_group_list"`
165165
}
166166

167167
func (z Object) RBACObject() Object {
@@ -171,36 +171,53 @@ func (z Object) RBACObject() Object {
171171
// All returns an object matching all resources of the same type.
172172
func (z Object) All() Object {
173173
return Object{
174-
Owner: "",
175-
OrgID: "",
176-
Type: z.Type,
174+
Owner: "",
175+
OrgID: "",
176+
Type: z.Type,
177+
ACLUserList: map[string][]Action{},
178+
ACLGroupList: map[string][]Action{},
177179
}
178180
}
179181

180182
// InOrg adds an org OwnerID to the resource
181183
func (z Object) InOrg(orgID uuid.UUID) Object {
182184
return Object{
183-
Owner: z.Owner,
184-
OrgID: orgID.String(),
185-
Type: z.Type,
185+
Owner: z.Owner,
186+
OrgID: orgID.String(),
187+
Type: z.Type,
188+
ACLUserList: z.ACLUserList,
189+
ACLGroupList: z.ACLGroupList,
186190
}
187191
}
188192

189193
// WithOwner adds an OwnerID to the resource
190194
func (z Object) WithOwner(ownerID string) Object {
191195
return Object{
192-
Owner: ownerID,
193-
OrgID: z.OrgID,
194-
Type: z.Type,
196+
Owner: ownerID,
197+
OrgID: z.OrgID,
198+
Type: z.Type,
199+
ACLUserList: z.ACLUserList,
200+
ACLGroupList: z.ACLGroupList,
195201
}
196202
}
197203

198204
// WithACLUserList adds an ACL list to a given object
199205
func (z Object) WithACLUserList(acl map[string][]Action) Object {
200206
return Object{
201-
Owner: z.Owner,
202-
OrgID: z.OrgID,
203-
Type: z.Type,
204-
ACLUserList: acl,
207+
Owner: z.Owner,
208+
OrgID: z.OrgID,
209+
Type: z.Type,
210+
ACLUserList: acl,
211+
ACLGroupList: z.ACLGroupList,
212+
}
213+
}
214+
215+
func (z Object) WithGroups(groups map[string][]Action) Object {
216+
return Object{
217+
Owner: z.Owner,
218+
OrgID: z.OrgID,
219+
Type: z.Type,
220+
ACLUserList: z.ACLUserList,
221+
ACLGroupList: groups,
205222
}
206223
}

coderd/rbac/policy.rego

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ allow {
176176
input.object.org_owner != ""
177177
# Only people in the org can use the team access.
178178
org_mem
179-
group := input.subject.groups[input.object.org_owner][_]
179+
group := input.subject.groups[_]
180180
perms := input.object.acl_group_list[group]
181181
# Either the input action or wildcard
182182
[input.action, "*"][_] in perms

0 commit comments

Comments
 (0)