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..e1fefada0f422 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..2aae17badfb95 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/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/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/enterprise/coderd/roles.go b/enterprise/coderd/roles.go index 227be3e4ce39e..d5af54a35b03b 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,23 @@ 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 { + continue + } + validPermissions = append(validPermissions, permission) + } + return validPermissions +} + func sdkPermissionToDB(p codersdk.Permission) database.CustomRolePermission { return database.CustomRolePermission{ Negate: p.Negate, diff --git a/site/src/api/rbacresourcesGenerated.ts b/site/src/api/rbacresourcesGenerated.ts index 437f89ec776a7..483508bc11554 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", 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",