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",
"provisioner_daemon",
"provisioner_jobs",
"provisioner_keys",
"replicas",
"system",
"tailnet_coordinator",
@ -13766,7 +13765,6 @@ const docTemplate = `{
"ResourceOrganizationMember",
"ResourceProvisionerDaemon",
"ResourceProvisionerJobs",
"ResourceProvisionerKeys",
"ResourceReplicas",
"ResourceSystem",
"ResourceTailnetCoordinator",

View File

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

View File

@ -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},
@ -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) {
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) {

View File

@ -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)
}

View File

@ -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,

View File

@ -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"),

View File

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

View File

@ -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},

View File

@ -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` |

View File

@ -5121,7 +5121,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` |

View File

@ -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,

View File

@ -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",
},

View File

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

View File

@ -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",