mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
feat(coderd): add tasks rbac object (#20234)
This change adds RBAC for tasks. Updates coder/internal#948 Supersedes coder/coder#20212
This commit is contained in:
Generated
+12
@@ -11932,6 +11932,11 @@ const docTemplate = `{
|
||||
"tailnet_coordinator:delete",
|
||||
"tailnet_coordinator:read",
|
||||
"tailnet_coordinator:update",
|
||||
"task:*",
|
||||
"task:create",
|
||||
"task:delete",
|
||||
"task:read",
|
||||
"task:update",
|
||||
"template:*",
|
||||
"template:create",
|
||||
"template:delete",
|
||||
@@ -12123,6 +12128,11 @@ const docTemplate = `{
|
||||
"APIKeyScopeTailnetCoordinatorDelete",
|
||||
"APIKeyScopeTailnetCoordinatorRead",
|
||||
"APIKeyScopeTailnetCoordinatorUpdate",
|
||||
"APIKeyScopeTaskAll",
|
||||
"APIKeyScopeTaskCreate",
|
||||
"APIKeyScopeTaskDelete",
|
||||
"APIKeyScopeTaskRead",
|
||||
"APIKeyScopeTaskUpdate",
|
||||
"APIKeyScopeTemplateAll",
|
||||
"APIKeyScopeTemplateCreate",
|
||||
"APIKeyScopeTemplateDelete",
|
||||
@@ -16977,6 +16987,7 @@ const docTemplate = `{
|
||||
"replicas",
|
||||
"system",
|
||||
"tailnet_coordinator",
|
||||
"task",
|
||||
"template",
|
||||
"usage_event",
|
||||
"user",
|
||||
@@ -17020,6 +17031,7 @@ const docTemplate = `{
|
||||
"ResourceReplicas",
|
||||
"ResourceSystem",
|
||||
"ResourceTailnetCoordinator",
|
||||
"ResourceTask",
|
||||
"ResourceTemplate",
|
||||
"ResourceUsageEvent",
|
||||
"ResourceUser",
|
||||
|
||||
Generated
+12
@@ -10636,6 +10636,11 @@
|
||||
"tailnet_coordinator:delete",
|
||||
"tailnet_coordinator:read",
|
||||
"tailnet_coordinator:update",
|
||||
"task:*",
|
||||
"task:create",
|
||||
"task:delete",
|
||||
"task:read",
|
||||
"task:update",
|
||||
"template:*",
|
||||
"template:create",
|
||||
"template:delete",
|
||||
@@ -10827,6 +10832,11 @@
|
||||
"APIKeyScopeTailnetCoordinatorDelete",
|
||||
"APIKeyScopeTailnetCoordinatorRead",
|
||||
"APIKeyScopeTailnetCoordinatorUpdate",
|
||||
"APIKeyScopeTaskAll",
|
||||
"APIKeyScopeTaskCreate",
|
||||
"APIKeyScopeTaskDelete",
|
||||
"APIKeyScopeTaskRead",
|
||||
"APIKeyScopeTaskUpdate",
|
||||
"APIKeyScopeTemplateAll",
|
||||
"APIKeyScopeTemplateCreate",
|
||||
"APIKeyScopeTemplateDelete",
|
||||
@@ -15499,6 +15509,7 @@
|
||||
"replicas",
|
||||
"system",
|
||||
"tailnet_coordinator",
|
||||
"task",
|
||||
"template",
|
||||
"usage_event",
|
||||
"user",
|
||||
@@ -15542,6 +15553,7 @@
|
||||
"ResourceReplicas",
|
||||
"ResourceSystem",
|
||||
"ResourceTailnetCoordinator",
|
||||
"ResourceTask",
|
||||
"ResourceTemplate",
|
||||
"ResourceUsageEvent",
|
||||
"ResourceUser",
|
||||
|
||||
@@ -219,7 +219,9 @@ var (
|
||||
rbac.ResourceUser.Type: {policy.ActionRead, policy.ActionReadPersonal, policy.ActionUpdatePersonal},
|
||||
rbac.ResourceWorkspaceDormant.Type: {policy.ActionDelete, policy.ActionRead, policy.ActionUpdate, policy.ActionWorkspaceStop},
|
||||
rbac.ResourceWorkspace.Type: {policy.ActionDelete, policy.ActionRead, policy.ActionUpdate, policy.ActionWorkspaceStart, policy.ActionWorkspaceStop, policy.ActionCreateAgent},
|
||||
rbac.ResourceApiKey.Type: {policy.WildcardSymbol},
|
||||
// Provisionerd needs to read and update tasks associated with workspaces.
|
||||
rbac.ResourceTask.Type: {policy.ActionRead, policy.ActionUpdate},
|
||||
rbac.ResourceApiKey.Type: {policy.WildcardSymbol},
|
||||
// When org scoped provisioner credentials are implemented,
|
||||
// this can be reduced to read a specific org.
|
||||
rbac.ResourceOrganization.Type: {policy.ActionRead},
|
||||
|
||||
Generated
+6
-1
@@ -197,7 +197,12 @@ CREATE TYPE api_key_scope AS ENUM (
|
||||
'workspace_agent_devcontainers:*',
|
||||
'workspace_agent_resource_monitor:*',
|
||||
'workspace_dormant:*',
|
||||
'workspace_proxy:*'
|
||||
'workspace_proxy:*',
|
||||
'task:create',
|
||||
'task:read',
|
||||
'task:update',
|
||||
'task:delete',
|
||||
'task:*'
|
||||
);
|
||||
|
||||
CREATE TYPE app_sharing_level AS ENUM (
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
-- Revert Tasks RBAC.
|
||||
-- No-op: enum values remain to avoid churn. Removing enum values requires
|
||||
-- doing a create/cast/drop cycle which is intentionally omitted here.
|
||||
@@ -0,0 +1,6 @@
|
||||
-- Tasks RBAC.
|
||||
ALTER TYPE api_key_scope ADD VALUE IF NOT EXISTS 'task:create';
|
||||
ALTER TYPE api_key_scope ADD VALUE IF NOT EXISTS 'task:read';
|
||||
ALTER TYPE api_key_scope ADD VALUE IF NOT EXISTS 'task:update';
|
||||
ALTER TYPE api_key_scope ADD VALUE IF NOT EXISTS 'task:delete';
|
||||
ALTER TYPE api_key_scope ADD VALUE IF NOT EXISTS 'task:*';
|
||||
@@ -132,6 +132,13 @@ func (w ConnectionLog) RBACObject() rbac.Object {
|
||||
return obj
|
||||
}
|
||||
|
||||
func (t Task) RBACObject() rbac.Object {
|
||||
return rbac.ResourceTask.
|
||||
WithID(t.ID).
|
||||
WithOwner(t.OwnerID.String()).
|
||||
InOrg(t.OrganizationID)
|
||||
}
|
||||
|
||||
func (s APIKeyScope) ToRBAC() rbac.ScopeName {
|
||||
switch s {
|
||||
case ApiKeyScopeCoderAll:
|
||||
|
||||
@@ -206,6 +206,11 @@ const (
|
||||
ApiKeyScopeWorkspaceAgentResourceMonitor APIKeyScope = "workspace_agent_resource_monitor:*"
|
||||
ApiKeyScopeWorkspaceDormant APIKeyScope = "workspace_dormant:*"
|
||||
ApiKeyScopeWorkspaceProxy APIKeyScope = "workspace_proxy:*"
|
||||
ApiKeyScopeTaskCreate APIKeyScope = "task:create"
|
||||
ApiKeyScopeTaskRead APIKeyScope = "task:read"
|
||||
ApiKeyScopeTaskUpdate APIKeyScope = "task:update"
|
||||
ApiKeyScopeTaskDelete APIKeyScope = "task:delete"
|
||||
ApiKeyScopeTask APIKeyScope = "task:*"
|
||||
)
|
||||
|
||||
func (e *APIKeyScope) Scan(src interface{}) error {
|
||||
@@ -431,7 +436,12 @@ func (e APIKeyScope) Valid() bool {
|
||||
ApiKeyScopeWorkspaceAgentDevcontainers,
|
||||
ApiKeyScopeWorkspaceAgentResourceMonitor,
|
||||
ApiKeyScopeWorkspaceDormant,
|
||||
ApiKeyScopeWorkspaceProxy:
|
||||
ApiKeyScopeWorkspaceProxy,
|
||||
ApiKeyScopeTaskCreate,
|
||||
ApiKeyScopeTaskRead,
|
||||
ApiKeyScopeTaskUpdate,
|
||||
ApiKeyScopeTaskDelete,
|
||||
ApiKeyScopeTask:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
@@ -626,6 +636,11 @@ func AllAPIKeyScopeValues() []APIKeyScope {
|
||||
ApiKeyScopeWorkspaceAgentResourceMonitor,
|
||||
ApiKeyScopeWorkspaceDormant,
|
||||
ApiKeyScopeWorkspaceProxy,
|
||||
ApiKeyScopeTaskCreate,
|
||||
ApiKeyScopeTaskRead,
|
||||
ApiKeyScopeTaskUpdate,
|
||||
ApiKeyScopeTaskDelete,
|
||||
ApiKeyScopeTask,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -286,6 +286,16 @@ var (
|
||||
Type: "tailnet_coordinator",
|
||||
}
|
||||
|
||||
// ResourceTask
|
||||
// Valid Actions
|
||||
// - "ActionCreate" :: create a new task
|
||||
// - "ActionDelete" :: delete task
|
||||
// - "ActionRead" :: read task data or output to view on the UI or CLI
|
||||
// - "ActionUpdate" :: edit task settings or send input to an existing task
|
||||
ResourceTask = Object{
|
||||
Type: "task",
|
||||
}
|
||||
|
||||
// ResourceTemplate
|
||||
// Valid Actions
|
||||
// - "ActionCreate" :: create a template
|
||||
@@ -430,6 +440,7 @@ func AllResources() []Objecter {
|
||||
ResourceReplicas,
|
||||
ResourceSystem,
|
||||
ResourceTailnetCoordinator,
|
||||
ResourceTask,
|
||||
ResourceTemplate,
|
||||
ResourceUsageEvent,
|
||||
ResourceUser,
|
||||
|
||||
@@ -63,6 +63,13 @@ var workspaceActions = map[Action]ActionDefinition{
|
||||
ActionDeleteAgent: "delete an existing workspace agent",
|
||||
}
|
||||
|
||||
var taskActions = map[Action]ActionDefinition{
|
||||
ActionCreate: "create a new task",
|
||||
ActionRead: "read task data or output to view on the UI or CLI",
|
||||
ActionUpdate: "edit task settings or send input to an existing task",
|
||||
ActionDelete: "delete task",
|
||||
}
|
||||
|
||||
// RBACPermissions is indexed by the type
|
||||
var RBACPermissions = map[string]PermissionDefinition{
|
||||
// Wildcard is every object, and the action "*" provides all actions.
|
||||
@@ -86,6 +93,9 @@ var RBACPermissions = map[string]PermissionDefinition{
|
||||
"workspace": {
|
||||
Actions: workspaceActions,
|
||||
},
|
||||
"task": {
|
||||
Actions: taskActions,
|
||||
},
|
||||
// Dormant workspaces have the same perms as workspaces.
|
||||
"workspace_dormant": {
|
||||
Actions: workspaceActions,
|
||||
|
||||
@@ -505,6 +505,15 @@ func TestRolePermissions(t *testing.T) {
|
||||
false: {setOtherOrg, userAdmin, memberMe, orgUserAdmin, orgAuditor, orgMemberMe},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "Task",
|
||||
Actions: crud,
|
||||
Resource: rbac.ResourceTask.WithID(uuid.New()).InOrg(orgID).WithOwner(memberMe.Actor.ID),
|
||||
AuthorizeMap: map[bool][]hasAuthSubjects{
|
||||
true: {owner, orgAdmin, orgMemberMe},
|
||||
false: {setOtherOrg, userAdmin, templateAdmin, memberMe, orgTemplateAdmin, orgUserAdmin, orgAuditor},
|
||||
},
|
||||
},
|
||||
// Some admin style resources
|
||||
{
|
||||
Name: "Licenses",
|
||||
|
||||
@@ -50,6 +50,13 @@ var externalLowLevel = map[ScopeName]struct{}{
|
||||
"user_secret:update": {},
|
||||
"user_secret:delete": {},
|
||||
"user_secret:*": {},
|
||||
|
||||
// Tasks
|
||||
"task:create": {},
|
||||
"task:read": {},
|
||||
"task:update": {},
|
||||
"task:delete": {},
|
||||
"task:*": {},
|
||||
}
|
||||
|
||||
// Public composite coder:* scopes exposed to users.
|
||||
|
||||
@@ -95,6 +95,10 @@ const (
|
||||
ScopeTailnetCoordinatorDelete ScopeName = "tailnet_coordinator:delete"
|
||||
ScopeTailnetCoordinatorRead ScopeName = "tailnet_coordinator:read"
|
||||
ScopeTailnetCoordinatorUpdate ScopeName = "tailnet_coordinator:update"
|
||||
ScopeTaskCreate ScopeName = "task:create"
|
||||
ScopeTaskDelete ScopeName = "task:delete"
|
||||
ScopeTaskRead ScopeName = "task:read"
|
||||
ScopeTaskUpdate ScopeName = "task:update"
|
||||
ScopeTemplateCreate ScopeName = "template:create"
|
||||
ScopeTemplateDelete ScopeName = "template:delete"
|
||||
ScopeTemplateRead ScopeName = "template:read"
|
||||
@@ -244,6 +248,10 @@ func (e ScopeName) Valid() bool {
|
||||
ScopeTailnetCoordinatorDelete,
|
||||
ScopeTailnetCoordinatorRead,
|
||||
ScopeTailnetCoordinatorUpdate,
|
||||
ScopeTaskCreate,
|
||||
ScopeTaskDelete,
|
||||
ScopeTaskRead,
|
||||
ScopeTaskUpdate,
|
||||
ScopeTemplateCreate,
|
||||
ScopeTemplateDelete,
|
||||
ScopeTemplateRead,
|
||||
@@ -394,6 +402,10 @@ func AllScopeNameValues() []ScopeName {
|
||||
ScopeTailnetCoordinatorDelete,
|
||||
ScopeTailnetCoordinatorRead,
|
||||
ScopeTailnetCoordinatorUpdate,
|
||||
ScopeTaskCreate,
|
||||
ScopeTaskDelete,
|
||||
ScopeTaskRead,
|
||||
ScopeTaskUpdate,
|
||||
ScopeTemplateCreate,
|
||||
ScopeTemplateDelete,
|
||||
ScopeTemplateRead,
|
||||
|
||||
Reference in New Issue
Block a user