diff --git a/coderd/rbac/object_gen.go b/coderd/rbac/object_gen.go index 57ec0982a15ae..9ab848d795b1c 100644 --- a/coderd/rbac/object_gen.go +++ b/coderd/rbac/object_gen.go @@ -37,7 +37,8 @@ var ( // ResourceAssignRole // Valid Actions // - "ActionAssign" :: ability to assign roles - // - "ActionDelete" :: ability to delete roles + // - "ActionCreate" :: ability to create/delete/edit custom roles + // - "ActionDelete" :: ability to unassign roles // - "ActionRead" :: view what roles are assignable ResourceAssignRole = Object{ Type: "assign_role", diff --git a/coderd/rbac/policy/policy.go b/coderd/rbac/policy/policy.go index 26afb0e011ca7..2d3213264a514 100644 --- a/coderd/rbac/policy/policy.go +++ b/coderd/rbac/policy/policy.go @@ -209,7 +209,8 @@ var RBACPermissions = map[string]PermissionDefinition{ Actions: map[Action]ActionDefinition{ ActionAssign: actDef("ability to assign roles"), ActionRead: actDef("view what roles are assignable"), - ActionDelete: actDef("ability to delete roles"), + ActionDelete: actDef("ability to unassign roles"), + ActionCreate: actDef("ability to create/delete/edit custom roles"), }, }, "assign_org_role": { diff --git a/coderd/rbac/roles.go b/coderd/rbac/roles.go index 87bbce5a4ac9e..46188e0c9fa76 100644 --- a/coderd/rbac/roles.go +++ b/coderd/rbac/roles.go @@ -20,6 +20,10 @@ const ( templateAdmin string = "template-admin" userAdmin string = "user-admin" auditor string = "auditor" + // customSiteRole is a placeholder for all custom site roles. + // This is used for what roles can assign other roles. + // TODO: Make this more dynamic to allow other roles to grant. + customSiteRole string = "custom-site-role" orgAdmin string = "organization-admin" orgMember string = "organization-member" @@ -52,6 +56,8 @@ func RoleOwner() string { return roleName(owner, "") } +func CustomSiteRole() string { return roleName(customSiteRole, "") } + func RoleTemplateAdmin() string { return roleName(templateAdmin, "") } @@ -320,22 +326,24 @@ func ReloadBuiltinRoles(opts *RoleOptions) { // map[actor_role][assign_role] var assignRoles = map[string]map[string]bool{ "system": { - owner: true, - auditor: true, - member: true, - orgAdmin: true, - orgMember: true, - templateAdmin: true, - userAdmin: true, + owner: true, + auditor: true, + member: true, + orgAdmin: true, + orgMember: true, + templateAdmin: true, + userAdmin: true, + customSiteRole: true, }, owner: { - owner: true, - auditor: true, - member: true, - orgAdmin: true, - orgMember: true, - templateAdmin: true, - userAdmin: true, + owner: true, + auditor: true, + member: true, + orgAdmin: true, + orgMember: true, + templateAdmin: true, + userAdmin: true, + customSiteRole: true, }, userAdmin: { member: true, diff --git a/coderd/rbac/roles_test.go b/coderd/rbac/roles_test.go index fe589449b8884..d90f045284c5b 100644 --- a/coderd/rbac/roles_test.go +++ b/coderd/rbac/roles_test.go @@ -248,6 +248,15 @@ func TestRolePermissions(t *testing.T) { false: {otherOrgAdmin, otherOrgMember, memberMe, userAdmin}, }, }, + { + Name: "CreateCustomRole", + Actions: []policy.Action{policy.ActionCreate}, + Resource: rbac.ResourceAssignRole, + AuthorizeMap: map[bool][]authSubject{ + true: {owner}, + false: {userAdmin, orgAdmin, orgMemberMe, otherOrgAdmin, otherOrgMember, memberMe, templateAdmin}, + }, + }, { Name: "RoleAssignment", Actions: []policy.Action{policy.ActionAssign, policy.ActionDelete}, @@ -380,7 +389,7 @@ func TestRolePermissions(t *testing.T) { }, // Some admin style resources { - Name: "Licences", + Name: "Licenses", Actions: []policy.Action{policy.ActionCreate, policy.ActionRead, policy.ActionDelete}, Resource: rbac.ResourceLicense, AuthorizeMap: map[bool][]authSubject{