From 0e0cd2323d0854c1ff3a9e07659ccd8255e67414 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Wed, 19 Feb 2025 11:25:15 -0600 Subject: [PATCH 1/6] chore: merge provisioner key and provisioner permissions --- coderd/apidoc/docs.go | 2 -- coderd/apidoc/swagger.json | 2 -- coderd/database/dbauthz/dbauthz.go | 3 +-- coderd/database/modelmethods.go | 4 +++- coderd/rbac/object_gen.go | 14 ++------------ coderd/rbac/policy/policy.go | 11 ++--------- codersdk/rbacresources_gen.go | 2 -- docs/reference/api/members.md | 5 ----- docs/reference/api/schemas.md | 1 - site/src/api/rbacresourcesGenerated.ts | 9 ++------- site/src/api/typesGenerated.ts | 2 -- 11 files changed, 10 insertions(+), 45 deletions(-) diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index 089f98d0f1f49..8788cb13abbc2 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -13702,7 +13702,6 @@ const docTemplate = `{ "organization_member", "provisioner_daemon", "provisioner_jobs", - "provisioner_keys", "replicas", "system", "tailnet_coordinator", @@ -13738,7 +13737,6 @@ const docTemplate = `{ "ResourceOrganizationMember", "ResourceProvisionerDaemon", "ResourceProvisionerJobs", - "ResourceProvisionerKeys", "ResourceReplicas", "ResourceSystem", "ResourceTailnetCoordinator", diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index c2e40ac88ebdf..cd873ec2956b2 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -12395,7 +12395,6 @@ "organization_member", "provisioner_daemon", "provisioner_jobs", - "provisioner_keys", "replicas", "system", "tailnet_coordinator", @@ -12431,7 +12430,6 @@ "ResourceOrganizationMember", "ResourceProvisionerDaemon", "ResourceProvisionerJobs", - "ResourceProvisionerKeys", "ResourceReplicas", "ResourceSystem", "ResourceTailnetCoordinator", diff --git a/coderd/database/dbauthz/dbauthz.go b/coderd/database/dbauthz/dbauthz.go index 9e616dd79dcbc..2a0e34b3c82a4 100644 --- a/coderd/database/dbauthz/dbauthz.go +++ b/coderd/database/dbauthz/dbauthz.go @@ -324,7 +324,6 @@ var ( rbac.ResourceOrganization.Type: {policy.ActionCreate, policy.ActionRead}, rbac.ResourceOrganizationMember.Type: {policy.ActionCreate, policy.ActionDelete, policy.ActionRead}, rbac.ResourceProvisionerDaemon.Type: {policy.ActionCreate, policy.ActionRead, policy.ActionUpdate}, - rbac.ResourceProvisionerKeys.Type: {policy.ActionCreate, policy.ActionRead, policy.ActionDelete}, rbac.ResourceUser.Type: rbac.ResourceUser.AvailableActions(), rbac.ResourceWorkspaceDormant.Type: {policy.ActionUpdate, policy.ActionDelete, policy.ActionWorkspaceStop}, rbac.ResourceWorkspace.Type: {policy.ActionUpdate, policy.ActionDelete, policy.ActionWorkspaceStart, policy.ActionWorkspaceStop, policy.ActionSSH}, @@ -3196,7 +3195,7 @@ func (q *querier) InsertProvisionerJobTimings(ctx context.Context, arg database. } func (q *querier) InsertProvisionerKey(ctx context.Context, arg database.InsertProvisionerKeyParams) (database.ProvisionerKey, error) { - return insert(q.log, q.auth, rbac.ResourceProvisionerKeys.InOrg(arg.OrganizationID).WithID(arg.ID), q.db.InsertProvisionerKey)(ctx, arg) + return insert(q.log, q.auth, rbac.ResourceProvisionerDaemon.InOrg(arg.OrganizationID).WithID(arg.ID), q.db.InsertProvisionerKey)(ctx, arg) } func (q *querier) InsertReplica(ctx context.Context, arg database.InsertReplicaParams) (database.Replica, error) { diff --git a/coderd/database/modelmethods.go b/coderd/database/modelmethods.go index 171c0454563de..803cfbf01ced2 100644 --- a/coderd/database/modelmethods.go +++ b/coderd/database/modelmethods.go @@ -277,8 +277,10 @@ func (p GetEligibleProvisionerDaemonsByProvisionerJobIDsRow) RBACObject() rbac.O return p.ProvisionerDaemon.RBACObject() } +// RBACObject for a provisioner key is the same as a provisioner daemon. +// Keys == provisioners from a RBAC perspective. func (p ProvisionerKey) RBACObject() rbac.Object { - return rbac.ResourceProvisionerKeys. + return rbac.ResourceProvisionerDaemon. WithID(p.ID). InOrg(p.OrganizationID) } diff --git a/coderd/rbac/object_gen.go b/coderd/rbac/object_gen.go index e5323225120b5..f8032d6cc589d 100644 --- a/coderd/rbac/object_gen.go +++ b/coderd/rbac/object_gen.go @@ -206,8 +206,8 @@ var ( // ResourceProvisionerDaemon // Valid Actions - // - "ActionCreate" :: create a provisioner daemon - // - "ActionDelete" :: delete a provisioner daemon + // - "ActionCreate" :: create a provisioner daemon key + // - "ActionDelete" :: delete a provisioner daemon/key // - "ActionRead" :: read provisioner daemon // - "ActionUpdate" :: update a provisioner daemon ResourceProvisionerDaemon = Object{ @@ -221,15 +221,6 @@ var ( Type: "provisioner_jobs", } - // ResourceProvisionerKeys - // Valid Actions - // - "ActionCreate" :: create a provisioner key - // - "ActionDelete" :: delete a provisioner key - // - "ActionRead" :: read provisioner keys - ResourceProvisionerKeys = Object{ - Type: "provisioner_keys", - } - // ResourceReplicas // Valid Actions // - "ActionRead" :: read replicas @@ -355,7 +346,6 @@ func AllResources() []Objecter { ResourceOrganizationMember, ResourceProvisionerDaemon, ResourceProvisionerJobs, - ResourceProvisionerKeys, ResourceReplicas, ResourceSystem, ResourceTailnetCoordinator, diff --git a/coderd/rbac/policy/policy.go b/coderd/rbac/policy/policy.go index c06a2117cb4e9..390ff5ad05b0b 100644 --- a/coderd/rbac/policy/policy.go +++ b/coderd/rbac/policy/policy.go @@ -162,11 +162,11 @@ var RBACPermissions = map[string]PermissionDefinition{ }, "provisioner_daemon": { Actions: map[Action]ActionDefinition{ - ActionCreate: actDef("create a provisioner daemon"), + ActionCreate: actDef("create a provisioner daemon key"), // TODO: Move to use? ActionRead: actDef("read provisioner daemon"), ActionUpdate: actDef("update a provisioner daemon"), - ActionDelete: actDef("delete a provisioner daemon"), + ActionDelete: actDef("delete a provisioner daemon/key"), }, }, "provisioner_jobs": { @@ -174,13 +174,6 @@ var RBACPermissions = map[string]PermissionDefinition{ ActionRead: actDef("read provisioner jobs"), }, }, - "provisioner_keys": { - Actions: map[Action]ActionDefinition{ - ActionCreate: actDef("create a provisioner key"), - ActionRead: actDef("read provisioner keys"), - ActionDelete: actDef("delete a provisioner key"), - }, - }, "organization": { Actions: map[Action]ActionDefinition{ ActionCreate: actDef("create an organization"), diff --git a/codersdk/rbacresources_gen.go b/codersdk/rbacresources_gen.go index f4d7790d40b76..f2751ac0334aa 100644 --- a/codersdk/rbacresources_gen.go +++ b/codersdk/rbacresources_gen.go @@ -28,7 +28,6 @@ const ( ResourceOrganizationMember RBACResource = "organization_member" ResourceProvisionerDaemon RBACResource = "provisioner_daemon" ResourceProvisionerJobs RBACResource = "provisioner_jobs" - ResourceProvisionerKeys RBACResource = "provisioner_keys" ResourceReplicas RBACResource = "replicas" ResourceSystem RBACResource = "system" ResourceTailnetCoordinator RBACResource = "tailnet_coordinator" @@ -85,7 +84,6 @@ var RBACResourceActions = map[RBACResource][]RBACAction{ ResourceOrganizationMember: {ActionCreate, ActionDelete, ActionRead, ActionUpdate}, ResourceProvisionerDaemon: {ActionCreate, ActionDelete, ActionRead, ActionUpdate}, ResourceProvisionerJobs: {ActionRead}, - ResourceProvisionerKeys: {ActionCreate, ActionDelete, ActionRead}, ResourceReplicas: {ActionRead}, ResourceSystem: {ActionCreate, ActionDelete, ActionRead, ActionUpdate}, ResourceTailnetCoordinator: {ActionCreate, ActionDelete, ActionRead, ActionUpdate}, diff --git a/docs/reference/api/members.md b/docs/reference/api/members.md index a3a38457c6631..6daaaaeea736f 100644 --- a/docs/reference/api/members.md +++ b/docs/reference/api/members.md @@ -203,7 +203,6 @@ Status Code **200** | `resource_type` | `organization_member` | | `resource_type` | `provisioner_daemon` | | `resource_type` | `provisioner_jobs` | -| `resource_type` | `provisioner_keys` | | `resource_type` | `replicas` | | `resource_type` | `system` | | `resource_type` | `tailnet_coordinator` | @@ -366,7 +365,6 @@ Status Code **200** | `resource_type` | `organization_member` | | `resource_type` | `provisioner_daemon` | | `resource_type` | `provisioner_jobs` | -| `resource_type` | `provisioner_keys` | | `resource_type` | `replicas` | | `resource_type` | `system` | | `resource_type` | `tailnet_coordinator` | @@ -529,7 +527,6 @@ Status Code **200** | `resource_type` | `organization_member` | | `resource_type` | `provisioner_daemon` | | `resource_type` | `provisioner_jobs` | -| `resource_type` | `provisioner_keys` | | `resource_type` | `replicas` | | `resource_type` | `system` | | `resource_type` | `tailnet_coordinator` | @@ -661,7 +658,6 @@ Status Code **200** | `resource_type` | `organization_member` | | `resource_type` | `provisioner_daemon` | | `resource_type` | `provisioner_jobs` | -| `resource_type` | `provisioner_keys` | | `resource_type` | `replicas` | | `resource_type` | `system` | | `resource_type` | `tailnet_coordinator` | @@ -925,7 +921,6 @@ Status Code **200** | `resource_type` | `organization_member` | | `resource_type` | `provisioner_daemon` | | `resource_type` | `provisioner_jobs` | -| `resource_type` | `provisioner_keys` | | `resource_type` | `replicas` | | `resource_type` | `system` | | `resource_type` | `tailnet_coordinator` | diff --git a/docs/reference/api/schemas.md b/docs/reference/api/schemas.md index d13a46ed9b365..5d0babb19ef64 100644 --- a/docs/reference/api/schemas.md +++ b/docs/reference/api/schemas.md @@ -5116,7 +5116,6 @@ Git clone makes use of this by parsing the URL from: 'Username for "https://gith | `organization_member` | | `provisioner_daemon` | | `provisioner_jobs` | -| `provisioner_keys` | | `replicas` | | `system` | | `tailnet_coordinator` | diff --git a/site/src/api/rbacresourcesGenerated.ts b/site/src/api/rbacresourcesGenerated.ts index 437f89ec776a7..33a35550ca152 100644 --- a/site/src/api/rbacresourcesGenerated.ts +++ b/site/src/api/rbacresourcesGenerated.ts @@ -114,19 +114,14 @@ export const RBACResourceActions: Partial< update: "update an organization member", }, provisioner_daemon: { - create: "create a provisioner daemon", - delete: "delete a provisioner daemon", + create: "create a provisioner daemon key", + delete: "delete a provisioner daemon/key", read: "read provisioner daemon", update: "update a provisioner daemon", }, provisioner_jobs: { read: "read provisioner jobs", }, - provisioner_keys: { - create: "create a provisioner key", - delete: "delete a provisioner key", - read: "read provisioner keys", - }, replicas: { read: "read replicas", }, diff --git a/site/src/api/typesGenerated.ts b/site/src/api/typesGenerated.ts index 34fe3360601af..28b02be5bd41f 100644 --- a/site/src/api/typesGenerated.ts +++ b/site/src/api/typesGenerated.ts @@ -1886,7 +1886,6 @@ export type RBACResource = | "organization_member" | "provisioner_daemon" | "provisioner_jobs" - | "provisioner_keys" | "replicas" | "system" | "tailnet_coordinator" @@ -1922,7 +1921,6 @@ export const RBACResources: RBACResource[] = [ "organization_member", "provisioner_daemon", "provisioner_jobs", - "provisioner_keys", "replicas", "system", "tailnet_coordinator", From 1abff51c392cb37629e6d0be7aedf75654e62c40 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Wed, 19 Feb 2025 11:51:39 -0600 Subject: [PATCH 2/6] chore: filter out invalid permissions on custom role push --- enterprise/coderd/roles.go | 28 +++++++++++++++++-- .../pages/UsersPage/storybookData/roles.ts | 5 ---- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/enterprise/coderd/roles.go b/enterprise/coderd/roles.go index 227be3e4ce39e..9d55ec7bfb7c0 100644 --- a/enterprise/coderd/roles.go +++ b/enterprise/coderd/roles.go @@ -147,9 +147,13 @@ func (api *API) putOrgRoles(rw http.ResponseWriter, r *http.Request) { UUID: organization.ID, Valid: true, }, - SitePermissions: db2sdk.List(req.SitePermissions, sdkPermissionToDB), - OrgPermissions: db2sdk.List(req.OrganizationPermissions, sdkPermissionToDB), - UserPermissions: db2sdk.List(req.UserPermissions, sdkPermissionToDB), + // Invalid permissions are filtered out. If this is changed + // to throw an error, then the story of a previously valid role + // now being invalid has to be addressed. Coder can change permissions, + // objects, and actions at any time. + SitePermissions: db2sdk.List(filterInvalidPermissions(req.SitePermissions), sdkPermissionToDB), + OrgPermissions: db2sdk.List(filterInvalidPermissions(req.OrganizationPermissions), sdkPermissionToDB), + UserPermissions: db2sdk.List(filterInvalidPermissions(req.UserPermissions), sdkPermissionToDB), }) if httpapi.Is404Error(err) { httpapi.ResourceNotFound(rw) @@ -247,6 +251,24 @@ func (api *API) deleteOrgRole(rw http.ResponseWriter, r *http.Request) { httpapi.Write(ctx, rw, http.StatusNoContent, nil) } +func filterInvalidPermissions(permissions []codersdk.Permission) []codersdk.Permission { + // Filter out any invalid permissions + var validPermissions []codersdk.Permission + for _, permission := range permissions { + err := (&rbac.Permission{ + Negate: permission.Negate, + ResourceType: string(permission.ResourceType), + Action: policy.Action(permission.Action), + }).Valid() + if err == nil { + validPermissions = append(validPermissions, permission) + } else { + fmt.Println(err.Error()) + } + } + return validPermissions +} + func sdkPermissionToDB(p codersdk.Permission) database.CustomRolePermission { return database.CustomRolePermission{ Negate: p.Negate, diff --git a/site/src/pages/UsersPage/storybookData/roles.ts b/site/src/pages/UsersPage/storybookData/roles.ts index 069625dbaa9ce..66228a00f794b 100644 --- a/site/src/pages/UsersPage/storybookData/roles.ts +++ b/site/src/pages/UsersPage/storybookData/roles.ts @@ -101,11 +101,6 @@ export const MockRoles: (AssignableRoles | Role)[] = [ resource_type: "provisioner_daemon", action: "*" as RBACAction, }, - { - negate: false, - resource_type: "provisioner_keys", - action: "*" as RBACAction, - }, { negate: false, resource_type: "replicas", From 0f1526373f1b20a53de253e5e65d1f49d414b33f Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Wed, 19 Feb 2025 11:58:52 -0600 Subject: [PATCH 3/6] linting --- coderd/rbac/roles_test.go | 9 --------- enterprise/coderd/roles.go | 11 +++++------ 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/coderd/rbac/roles_test.go b/coderd/rbac/roles_test.go index db0d9832579fc..1307c8ab7a6ac 100644 --- a/coderd/rbac/roles_test.go +++ b/coderd/rbac/roles_test.go @@ -555,15 +555,6 @@ func TestRolePermissions(t *testing.T) { false: {setOtherOrg, memberMe, userAdmin, orgTemplateAdmin, orgUserAdmin, orgAuditor}, }, }, - { - Name: "ProvisionerKeys", - Actions: []policy.Action{policy.ActionCreate, policy.ActionRead, policy.ActionDelete}, - Resource: rbac.ResourceProvisionerKeys.InOrg(orgID), - AuthorizeMap: map[bool][]hasAuthSubjects{ - true: {owner, orgAdmin}, - false: {setOtherOrg, memberMe, orgMemberMe, userAdmin, templateAdmin, orgTemplateAdmin, orgUserAdmin, orgAuditor}, - }, - }, { Name: "ProvisionerJobs", Actions: []policy.Action{policy.ActionRead}, diff --git a/enterprise/coderd/roles.go b/enterprise/coderd/roles.go index 9d55ec7bfb7c0..d5af54a35b03b 100644 --- a/enterprise/coderd/roles.go +++ b/enterprise/coderd/roles.go @@ -255,16 +255,15 @@ func filterInvalidPermissions(permissions []codersdk.Permission) []codersdk.Perm // Filter out any invalid permissions var validPermissions []codersdk.Permission for _, permission := range permissions { - err := (&rbac.Permission{ + err := rbac.Permission{ Negate: permission.Negate, ResourceType: string(permission.ResourceType), Action: policy.Action(permission.Action), - }).Valid() - if err == nil { - validPermissions = append(validPermissions, permission) - } else { - fmt.Println(err.Error()) + }.Valid() + if err != nil { + continue } + validPermissions = append(validPermissions, permission) } return validPermissions } From aee32893fd10e313e373e0be460193e293d5a6cb Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Wed, 19 Feb 2025 12:44:34 -0600 Subject: [PATCH 4/6] Update site/src/api/rbacresourcesGenerated.ts Co-authored-by: Cian Johnston --- site/src/api/rbacresourcesGenerated.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/src/api/rbacresourcesGenerated.ts b/site/src/api/rbacresourcesGenerated.ts index 33a35550ca152..483508bc11554 100644 --- a/site/src/api/rbacresourcesGenerated.ts +++ b/site/src/api/rbacresourcesGenerated.ts @@ -114,7 +114,7 @@ export const RBACResourceActions: Partial< update: "update an organization member", }, provisioner_daemon: { - create: "create a provisioner daemon key", + create: "create a provisioner daemon/key", delete: "delete a provisioner daemon/key", read: "read provisioner daemon", update: "update a provisioner daemon", From ccc3afa839c784b1b05a3b5e2593c72b6ef6a662 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Wed, 19 Feb 2025 12:44:43 -0600 Subject: [PATCH 5/6] Update coderd/rbac/policy/policy.go Co-authored-by: Cian Johnston --- coderd/rbac/policy/policy.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coderd/rbac/policy/policy.go b/coderd/rbac/policy/policy.go index 390ff5ad05b0b..2aae17badfb95 100644 --- a/coderd/rbac/policy/policy.go +++ b/coderd/rbac/policy/policy.go @@ -162,7 +162,7 @@ var RBACPermissions = map[string]PermissionDefinition{ }, "provisioner_daemon": { Actions: map[Action]ActionDefinition{ - ActionCreate: actDef("create a provisioner daemon key"), + ActionCreate: actDef("create a provisioner daemon/key"), // TODO: Move to use? ActionRead: actDef("read provisioner daemon"), ActionUpdate: actDef("update a provisioner daemon"), From a6fcd520a7d1c3ce6853f73f612a507e45410420 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Wed, 19 Feb 2025 14:15:15 -0600 Subject: [PATCH 6/6] make gen --- coderd/rbac/object_gen.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coderd/rbac/object_gen.go b/coderd/rbac/object_gen.go index f8032d6cc589d..e1fefada0f422 100644 --- a/coderd/rbac/object_gen.go +++ b/coderd/rbac/object_gen.go @@ -206,7 +206,7 @@ var ( // ResourceProvisionerDaemon // Valid Actions - // - "ActionCreate" :: create a provisioner daemon key + // - "ActionCreate" :: create a provisioner daemon/key // - "ActionDelete" :: delete a provisioner daemon/key // - "ActionRead" :: read provisioner daemon // - "ActionUpdate" :: update a provisioner daemon