feat: Implement allow_list for scopes for resource specific permissions (#5769)

* feat: Implement allow_list for scopes for resource specific permissions

Feature that adds an allow_list for scopes to specify particular resources.
This enables workspace agent tokens to use the same RBAC system as users.

- Add ID to compileSQL matchers
* Plumb through WithID on rbac objects
* Rename Scope -> ScopeName
* Update input.json with scope allow_list

Co-authored-by: Cian Johnston <cian@coder.com>
This commit is contained in:
Steven Masley
2023-01-19 13:41:36 -06:00
committed by GitHub
parent f0df0686f9
commit 08cce81ac8
25 changed files with 445 additions and 153 deletions

View File

@ -35,7 +35,7 @@ func (g Group) Auditable(users []User) AuditableGroup {
const AllUsersGroup = "Everyone"
func (s APIKeyScope) ToRBAC() rbac.Scope {
func (s APIKeyScope) ToRBAC() rbac.ScopeName {
switch s {
case APIKeyScopeAll:
return rbac.ScopeAll
@ -46,9 +46,14 @@ func (s APIKeyScope) ToRBAC() rbac.Scope {
}
}
func (k APIKey) RBACObject() rbac.Object {
return rbac.ResourceAPIKey.WithIDString(k.ID).
WithOwner(k.UserID.String())
}
func (t Template) RBACObject() rbac.Object {
obj := rbac.ResourceTemplate
return obj.InOrg(t.OrganizationID).
return rbac.ResourceTemplate.WithID(t.ID).
InOrg(t.OrganizationID).
WithACLUserList(t.UserACL).
WithGroupACL(t.GroupACL)
}
@ -59,42 +64,61 @@ func (TemplateVersion) RBACObject(template Template) rbac.Object {
}
func (g Group) RBACObject() rbac.Object {
return rbac.ResourceGroup.InOrg(g.OrganizationID)
return rbac.ResourceGroup.WithID(g.ID).
InOrg(g.OrganizationID)
}
func (w Workspace) RBACObject() rbac.Object {
return rbac.ResourceWorkspace.InOrg(w.OrganizationID).WithOwner(w.OwnerID.String())
return rbac.ResourceWorkspace.WithID(w.ID).
InOrg(w.OrganizationID).
WithOwner(w.OwnerID.String())
}
func (w Workspace) ExecutionRBAC() rbac.Object {
return rbac.ResourceWorkspaceExecution.InOrg(w.OrganizationID).WithOwner(w.OwnerID.String())
return rbac.ResourceWorkspaceExecution.
WithID(w.ID).
InOrg(w.OrganizationID).
WithOwner(w.OwnerID.String())
}
func (w Workspace) ApplicationConnectRBAC() rbac.Object {
return rbac.ResourceWorkspaceApplicationConnect.InOrg(w.OrganizationID).WithOwner(w.OwnerID.String())
return rbac.ResourceWorkspaceApplicationConnect.
WithID(w.ID).
InOrg(w.OrganizationID).
WithOwner(w.OwnerID.String())
}
func (m OrganizationMember) RBACObject() rbac.Object {
return rbac.ResourceOrganizationMember.InOrg(m.OrganizationID)
return rbac.ResourceOrganizationMember.
WithID(m.UserID).
InOrg(m.OrganizationID)
}
func (o Organization) RBACObject() rbac.Object {
return rbac.ResourceOrganization.InOrg(o.ID)
return rbac.ResourceOrganization.
WithID(o.ID).
InOrg(o.ID)
}
func (ProvisionerDaemon) RBACObject() rbac.Object {
return rbac.ResourceProvisionerDaemon
func (p ProvisionerDaemon) RBACObject() rbac.Object {
return rbac.ResourceProvisionerDaemon.WithID(p.ID)
}
func (f File) RBACObject() rbac.Object {
return rbac.ResourceFile.WithOwner(f.CreatedBy.String())
return rbac.ResourceFile.
WithID(f.ID).
WithOwner(f.CreatedBy.String())
}
// RBACObject returns the RBAC object for the site wide user resource.
// If you are trying to get the RBAC object for the UserData, use
// rbac.ResourceUserData
func (User) RBACObject() rbac.Object {
return rbac.ResourceUser
// u.UserDataRBACObject() instead.
func (u User) RBACObject() rbac.Object {
return rbac.ResourceUser.WithID(u.ID)
}
func (u User) UserDataRBACObject() rbac.Object {
return rbac.ResourceUser.WithID(u.ID).WithOwner(u.ID.String())
}
func (License) RBACObject() rbac.Object {