chore: merge provisioner key and provisioner permissions (#16628)

Provisioner key permissions were never any different than provisioners.
Merging them for a cleaner permission story until they are required (if
ever) to be seperate.

This removed `ResourceProvisionerKey` from RBAC and just uses the
existing `ResourceProvisioner`.
This commit is contained in:
Steven Masley
2025-02-24 13:31:11 -06:00
committed by GitHub
parent 8f33c6d8d1
commit e005e4e51d
14 changed files with 34 additions and 62 deletions

2
coderd/apidoc/docs.go generated
View File

@ -13730,7 +13730,6 @@ const docTemplate = `{
"organization_member", "organization_member",
"provisioner_daemon", "provisioner_daemon",
"provisioner_jobs", "provisioner_jobs",
"provisioner_keys",
"replicas", "replicas",
"system", "system",
"tailnet_coordinator", "tailnet_coordinator",
@ -13766,7 +13765,6 @@ const docTemplate = `{
"ResourceOrganizationMember", "ResourceOrganizationMember",
"ResourceProvisionerDaemon", "ResourceProvisionerDaemon",
"ResourceProvisionerJobs", "ResourceProvisionerJobs",
"ResourceProvisionerKeys",
"ResourceReplicas", "ResourceReplicas",
"ResourceSystem", "ResourceSystem",
"ResourceTailnetCoordinator", "ResourceTailnetCoordinator",

View File

@ -12419,7 +12419,6 @@
"organization_member", "organization_member",
"provisioner_daemon", "provisioner_daemon",
"provisioner_jobs", "provisioner_jobs",
"provisioner_keys",
"replicas", "replicas",
"system", "system",
"tailnet_coordinator", "tailnet_coordinator",
@ -12455,7 +12454,6 @@
"ResourceOrganizationMember", "ResourceOrganizationMember",
"ResourceProvisionerDaemon", "ResourceProvisionerDaemon",
"ResourceProvisionerJobs", "ResourceProvisionerJobs",
"ResourceProvisionerKeys",
"ResourceReplicas", "ResourceReplicas",
"ResourceSystem", "ResourceSystem",
"ResourceTailnetCoordinator", "ResourceTailnetCoordinator",

View File

@ -324,7 +324,6 @@ var (
rbac.ResourceOrganization.Type: {policy.ActionCreate, policy.ActionRead}, rbac.ResourceOrganization.Type: {policy.ActionCreate, policy.ActionRead},
rbac.ResourceOrganizationMember.Type: {policy.ActionCreate, policy.ActionDelete, policy.ActionRead}, rbac.ResourceOrganizationMember.Type: {policy.ActionCreate, policy.ActionDelete, policy.ActionRead},
rbac.ResourceProvisionerDaemon.Type: {policy.ActionCreate, policy.ActionRead, policy.ActionUpdate}, 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.ResourceUser.Type: rbac.ResourceUser.AvailableActions(),
rbac.ResourceWorkspaceDormant.Type: {policy.ActionUpdate, policy.ActionDelete, policy.ActionWorkspaceStop}, rbac.ResourceWorkspaceDormant.Type: {policy.ActionUpdate, policy.ActionDelete, policy.ActionWorkspaceStop},
rbac.ResourceWorkspace.Type: {policy.ActionUpdate, policy.ActionDelete, policy.ActionWorkspaceStart, policy.ActionWorkspaceStop, policy.ActionSSH}, rbac.ResourceWorkspace.Type: {policy.ActionUpdate, policy.ActionDelete, policy.ActionWorkspaceStart, policy.ActionWorkspaceStop, policy.ActionSSH},
@ -3192,7 +3191,7 @@ func (q *querier) InsertProvisionerJobTimings(ctx context.Context, arg database.
} }
func (q *querier) InsertProvisionerKey(ctx context.Context, arg database.InsertProvisionerKeyParams) (database.ProvisionerKey, error) { 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) { func (q *querier) InsertReplica(ctx context.Context, arg database.InsertReplicaParams) (database.Replica, error) {

View File

@ -277,8 +277,10 @@ func (p GetEligibleProvisionerDaemonsByProvisionerJobIDsRow) RBACObject() rbac.O
return p.ProvisionerDaemon.RBACObject() 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 { func (p ProvisionerKey) RBACObject() rbac.Object {
return rbac.ResourceProvisionerKeys. return rbac.ResourceProvisionerDaemon.
WithID(p.ID). WithID(p.ID).
InOrg(p.OrganizationID) InOrg(p.OrganizationID)
} }

View File

@ -206,8 +206,8 @@ var (
// ResourceProvisionerDaemon // ResourceProvisionerDaemon
// Valid Actions // Valid Actions
// - "ActionCreate" :: create a provisioner daemon // - "ActionCreate" :: create a provisioner daemon/key
// - "ActionDelete" :: delete a provisioner daemon // - "ActionDelete" :: delete a provisioner daemon/key
// - "ActionRead" :: read provisioner daemon // - "ActionRead" :: read provisioner daemon
// - "ActionUpdate" :: update a provisioner daemon // - "ActionUpdate" :: update a provisioner daemon
ResourceProvisionerDaemon = Object{ ResourceProvisionerDaemon = Object{
@ -221,15 +221,6 @@ var (
Type: "provisioner_jobs", 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 // ResourceReplicas
// Valid Actions // Valid Actions
// - "ActionRead" :: read replicas // - "ActionRead" :: read replicas
@ -355,7 +346,6 @@ func AllResources() []Objecter {
ResourceOrganizationMember, ResourceOrganizationMember,
ResourceProvisionerDaemon, ResourceProvisionerDaemon,
ResourceProvisionerJobs, ResourceProvisionerJobs,
ResourceProvisionerKeys,
ResourceReplicas, ResourceReplicas,
ResourceSystem, ResourceSystem,
ResourceTailnetCoordinator, ResourceTailnetCoordinator,

View File

@ -162,11 +162,11 @@ var RBACPermissions = map[string]PermissionDefinition{
}, },
"provisioner_daemon": { "provisioner_daemon": {
Actions: map[Action]ActionDefinition{ Actions: map[Action]ActionDefinition{
ActionCreate: actDef("create a provisioner daemon"), ActionCreate: actDef("create a provisioner daemon/key"),
// TODO: Move to use? // TODO: Move to use?
ActionRead: actDef("read provisioner daemon"), ActionRead: actDef("read provisioner daemon"),
ActionUpdate: actDef("update a provisioner daemon"), ActionUpdate: actDef("update a provisioner daemon"),
ActionDelete: actDef("delete a provisioner daemon"), ActionDelete: actDef("delete a provisioner daemon/key"),
}, },
}, },
"provisioner_jobs": { "provisioner_jobs": {
@ -174,13 +174,6 @@ var RBACPermissions = map[string]PermissionDefinition{
ActionRead: actDef("read provisioner jobs"), 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": { "organization": {
Actions: map[Action]ActionDefinition{ Actions: map[Action]ActionDefinition{
ActionCreate: actDef("create an organization"), ActionCreate: actDef("create an organization"),

View File

@ -556,15 +556,6 @@ func TestRolePermissions(t *testing.T) {
false: {setOtherOrg, memberMe, userAdmin, orgUserAdmin, orgAuditor}, false: {setOtherOrg, memberMe, userAdmin, 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", Name: "ProvisionerJobs",
Actions: []policy.Action{policy.ActionRead}, Actions: []policy.Action{policy.ActionRead},

View File

@ -28,7 +28,6 @@ const (
ResourceOrganizationMember RBACResource = "organization_member" ResourceOrganizationMember RBACResource = "organization_member"
ResourceProvisionerDaemon RBACResource = "provisioner_daemon" ResourceProvisionerDaemon RBACResource = "provisioner_daemon"
ResourceProvisionerJobs RBACResource = "provisioner_jobs" ResourceProvisionerJobs RBACResource = "provisioner_jobs"
ResourceProvisionerKeys RBACResource = "provisioner_keys"
ResourceReplicas RBACResource = "replicas" ResourceReplicas RBACResource = "replicas"
ResourceSystem RBACResource = "system" ResourceSystem RBACResource = "system"
ResourceTailnetCoordinator RBACResource = "tailnet_coordinator" ResourceTailnetCoordinator RBACResource = "tailnet_coordinator"
@ -85,7 +84,6 @@ var RBACResourceActions = map[RBACResource][]RBACAction{
ResourceOrganizationMember: {ActionCreate, ActionDelete, ActionRead, ActionUpdate}, ResourceOrganizationMember: {ActionCreate, ActionDelete, ActionRead, ActionUpdate},
ResourceProvisionerDaemon: {ActionCreate, ActionDelete, ActionRead, ActionUpdate}, ResourceProvisionerDaemon: {ActionCreate, ActionDelete, ActionRead, ActionUpdate},
ResourceProvisionerJobs: {ActionRead}, ResourceProvisionerJobs: {ActionRead},
ResourceProvisionerKeys: {ActionCreate, ActionDelete, ActionRead},
ResourceReplicas: {ActionRead}, ResourceReplicas: {ActionRead},
ResourceSystem: {ActionCreate, ActionDelete, ActionRead, ActionUpdate}, ResourceSystem: {ActionCreate, ActionDelete, ActionRead, ActionUpdate},
ResourceTailnetCoordinator: {ActionCreate, ActionDelete, ActionRead, ActionUpdate}, ResourceTailnetCoordinator: {ActionCreate, ActionDelete, ActionRead, ActionUpdate},

View File

@ -203,7 +203,6 @@ Status Code **200**
| `resource_type` | `organization_member` | | `resource_type` | `organization_member` |
| `resource_type` | `provisioner_daemon` | | `resource_type` | `provisioner_daemon` |
| `resource_type` | `provisioner_jobs` | | `resource_type` | `provisioner_jobs` |
| `resource_type` | `provisioner_keys` |
| `resource_type` | `replicas` | | `resource_type` | `replicas` |
| `resource_type` | `system` | | `resource_type` | `system` |
| `resource_type` | `tailnet_coordinator` | | `resource_type` | `tailnet_coordinator` |
@ -366,7 +365,6 @@ Status Code **200**
| `resource_type` | `organization_member` | | `resource_type` | `organization_member` |
| `resource_type` | `provisioner_daemon` | | `resource_type` | `provisioner_daemon` |
| `resource_type` | `provisioner_jobs` | | `resource_type` | `provisioner_jobs` |
| `resource_type` | `provisioner_keys` |
| `resource_type` | `replicas` | | `resource_type` | `replicas` |
| `resource_type` | `system` | | `resource_type` | `system` |
| `resource_type` | `tailnet_coordinator` | | `resource_type` | `tailnet_coordinator` |
@ -529,7 +527,6 @@ Status Code **200**
| `resource_type` | `organization_member` | | `resource_type` | `organization_member` |
| `resource_type` | `provisioner_daemon` | | `resource_type` | `provisioner_daemon` |
| `resource_type` | `provisioner_jobs` | | `resource_type` | `provisioner_jobs` |
| `resource_type` | `provisioner_keys` |
| `resource_type` | `replicas` | | `resource_type` | `replicas` |
| `resource_type` | `system` | | `resource_type` | `system` |
| `resource_type` | `tailnet_coordinator` | | `resource_type` | `tailnet_coordinator` |
@ -661,7 +658,6 @@ Status Code **200**
| `resource_type` | `organization_member` | | `resource_type` | `organization_member` |
| `resource_type` | `provisioner_daemon` | | `resource_type` | `provisioner_daemon` |
| `resource_type` | `provisioner_jobs` | | `resource_type` | `provisioner_jobs` |
| `resource_type` | `provisioner_keys` |
| `resource_type` | `replicas` | | `resource_type` | `replicas` |
| `resource_type` | `system` | | `resource_type` | `system` |
| `resource_type` | `tailnet_coordinator` | | `resource_type` | `tailnet_coordinator` |
@ -925,7 +921,6 @@ Status Code **200**
| `resource_type` | `organization_member` | | `resource_type` | `organization_member` |
| `resource_type` | `provisioner_daemon` | | `resource_type` | `provisioner_daemon` |
| `resource_type` | `provisioner_jobs` | | `resource_type` | `provisioner_jobs` |
| `resource_type` | `provisioner_keys` |
| `resource_type` | `replicas` | | `resource_type` | `replicas` |
| `resource_type` | `system` | | `resource_type` | `system` |
| `resource_type` | `tailnet_coordinator` | | `resource_type` | `tailnet_coordinator` |

View File

@ -5121,7 +5121,6 @@ Git clone makes use of this by parsing the URL from: 'Username for "https://gith
| `organization_member` | | `organization_member` |
| `provisioner_daemon` | | `provisioner_daemon` |
| `provisioner_jobs` | | `provisioner_jobs` |
| `provisioner_keys` |
| `replicas` | | `replicas` |
| `system` | | `system` |
| `tailnet_coordinator` | | `tailnet_coordinator` |

View File

@ -147,9 +147,13 @@ func (api *API) putOrgRoles(rw http.ResponseWriter, r *http.Request) {
UUID: organization.ID, UUID: organization.ID,
Valid: true, Valid: true,
}, },
SitePermissions: db2sdk.List(req.SitePermissions, sdkPermissionToDB), // Invalid permissions are filtered out. If this is changed
OrgPermissions: db2sdk.List(req.OrganizationPermissions, sdkPermissionToDB), // to throw an error, then the story of a previously valid role
UserPermissions: db2sdk.List(req.UserPermissions, sdkPermissionToDB), // 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) { if httpapi.Is404Error(err) {
httpapi.ResourceNotFound(rw) httpapi.ResourceNotFound(rw)
@ -247,6 +251,23 @@ func (api *API) deleteOrgRole(rw http.ResponseWriter, r *http.Request) {
httpapi.Write(ctx, rw, http.StatusNoContent, nil) 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 { func sdkPermissionToDB(p codersdk.Permission) database.CustomRolePermission {
return database.CustomRolePermission{ return database.CustomRolePermission{
Negate: p.Negate, Negate: p.Negate,

View File

@ -114,19 +114,14 @@ export const RBACResourceActions: Partial<
update: "update an organization member", update: "update an organization member",
}, },
provisioner_daemon: { provisioner_daemon: {
create: "create a provisioner daemon", create: "create a provisioner daemon/key",
delete: "delete a provisioner daemon", delete: "delete a provisioner daemon/key",
read: "read provisioner daemon", read: "read provisioner daemon",
update: "update a provisioner daemon", update: "update a provisioner daemon",
}, },
provisioner_jobs: { provisioner_jobs: {
read: "read provisioner jobs", read: "read provisioner jobs",
}, },
provisioner_keys: {
create: "create a provisioner key",
delete: "delete a provisioner key",
read: "read provisioner keys",
},
replicas: { replicas: {
read: "read replicas", read: "read replicas",
}, },

View File

@ -1896,7 +1896,6 @@ export type RBACResource =
| "organization_member" | "organization_member"
| "provisioner_daemon" | "provisioner_daemon"
| "provisioner_jobs" | "provisioner_jobs"
| "provisioner_keys"
| "replicas" | "replicas"
| "system" | "system"
| "tailnet_coordinator" | "tailnet_coordinator"
@ -1932,7 +1931,6 @@ export const RBACResources: RBACResource[] = [
"organization_member", "organization_member",
"provisioner_daemon", "provisioner_daemon",
"provisioner_jobs", "provisioner_jobs",
"provisioner_keys",
"replicas", "replicas",
"system", "system",
"tailnet_coordinator", "tailnet_coordinator",

View File

@ -101,11 +101,6 @@ export const MockRoles: (AssignableRoles | Role)[] = [
resource_type: "provisioner_daemon", resource_type: "provisioner_daemon",
action: "*" as RBACAction, action: "*" as RBACAction,
}, },
{
negate: false,
resource_type: "provisioner_keys",
action: "*" as RBACAction,
},
{ {
negate: false, negate: false,
resource_type: "replicas", resource_type: "replicas",