feat(coderd/agentapi): support terraform-defined subagent ids (#21837)

Update `coderd/agentapi` to handle pre-created sub agents
This commit is contained in:
Danielle Maywood
2026-02-04 15:33:48 +00:00
committed by GitHub
parent 29b1aea736
commit af0e171595
27 changed files with 432 additions and 40 deletions
+3
View File
@@ -370,6 +370,7 @@ var (
// - "ActionWorkspaceStart" :: allows starting a workspace
// - "ActionWorkspaceStop" :: allows stopping a workspace
// - "ActionUpdate" :: edit workspace settings (scheduling, permissions, parameters)
// - "ActionUpdateAgent" :: update an existing workspace agent
ResourceWorkspace = Object{
Type: "workspace",
}
@@ -403,6 +404,7 @@ var (
// - "ActionWorkspaceStart" :: allows starting a workspace
// - "ActionWorkspaceStop" :: allows stopping a workspace
// - "ActionUpdate" :: edit workspace settings (scheduling, permissions, parameters)
// - "ActionUpdateAgent" :: update an existing workspace agent
ResourceWorkspaceDormant = Object{
Type: "workspace_dormant",
}
@@ -480,6 +482,7 @@ func AllActions() []policy.Action {
policy.ActionShare,
policy.ActionUnassign,
policy.ActionUpdate,
policy.ActionUpdateAgent,
policy.ActionUpdatePersonal,
policy.ActionUse,
policy.ActionViewInsights,
+2
View File
@@ -27,6 +27,7 @@ const (
ActionCreateAgent Action = "create_agent"
ActionDeleteAgent Action = "delete_agent"
ActionUpdateAgent Action = "update_agent"
ActionShare Action = "share"
)
@@ -63,6 +64,7 @@ var workspaceActions = map[Action]ActionDefinition{
ActionCreateAgent: "create a new workspace agent",
ActionDeleteAgent: "delete an existing workspace agent",
ActionUpdateAgent: "update an existing workspace agent",
// Sharing a workspace
ActionShare: "share a workspace with other users or groups",
+3 -2
View File
@@ -290,7 +290,7 @@ func ReloadBuiltinRoles(opts *RoleOptions) {
// This adds back in the Workspace permissions.
Permissions(map[string][]policy.Action{
ResourceWorkspace.Type: ownerWorkspaceActions,
ResourceWorkspaceDormant.Type: {policy.ActionRead, policy.ActionDelete, policy.ActionCreate, policy.ActionUpdate, policy.ActionWorkspaceStop, policy.ActionCreateAgent, policy.ActionDeleteAgent},
ResourceWorkspaceDormant.Type: {policy.ActionRead, policy.ActionDelete, policy.ActionCreate, policy.ActionUpdate, policy.ActionWorkspaceStop, policy.ActionCreateAgent, policy.ActionDeleteAgent, policy.ActionUpdateAgent},
// PrebuiltWorkspaces are a subset of Workspaces.
// Explicitly setting PrebuiltWorkspace permissions for clarity.
// Note: even without PrebuiltWorkspace permissions, access is still granted via Workspace permissions.
@@ -434,7 +434,7 @@ func ReloadBuiltinRoles(opts *RoleOptions) {
// Org admins should not have workspace exec perms.
organizationID.String(): {
Org: append(allPermsExcept(ResourceWorkspace, ResourceWorkspaceDormant, ResourcePrebuiltWorkspace, ResourceAssignRole, ResourceUserSecret, ResourceBoundaryUsage), Permissions(map[string][]policy.Action{
ResourceWorkspaceDormant.Type: {policy.ActionRead, policy.ActionDelete, policy.ActionCreate, policy.ActionUpdate, policy.ActionWorkspaceStop, policy.ActionCreateAgent, policy.ActionDeleteAgent},
ResourceWorkspaceDormant.Type: {policy.ActionRead, policy.ActionDelete, policy.ActionCreate, policy.ActionUpdate, policy.ActionWorkspaceStop, policy.ActionCreateAgent, policy.ActionDeleteAgent, policy.ActionUpdateAgent},
ResourceWorkspace.Type: slice.Omit(ResourceWorkspace.AvailableActions(), policy.ActionApplicationConnect, policy.ActionSSH),
// PrebuiltWorkspaces are a subset of Workspaces.
// Explicitly setting PrebuiltWorkspace permissions for clarity.
@@ -972,6 +972,7 @@ func OrgMemberPermissions(workspaceSharingDisabled bool) (
policy.ActionWorkspaceStop,
policy.ActionCreateAgent,
policy.ActionDeleteAgent,
policy.ActionUpdateAgent,
},
// Can read their own organization member record.
ResourceOrganizationMember.Type: {
+10 -1
View File
@@ -294,6 +294,15 @@ func TestRolePermissions(t *testing.T) {
false: {setOtherOrg, memberMe, userAdmin, templateAdmin, orgTemplateAdmin, orgUserAdmin, orgAuditor, orgAdminBanWorkspace},
},
},
{
Name: "UpdateWorkspaceAgent",
Actions: []policy.Action{policy.ActionUpdateAgent},
Resource: rbac.ResourceWorkspace.WithID(workspaceID).InOrg(orgID).WithOwner(currentUser.String()),
AuthorizeMap: map[bool][]hasAuthSubjects{
true: {owner, orgAdmin, orgAdminBanWorkspace},
false: {setOtherOrg, memberMe, userAdmin, templateAdmin, orgTemplateAdmin, orgUserAdmin, orgAuditor},
},
},
{
Name: "ShareMyWorkspace",
Actions: []policy.Action{policy.ActionShare},
@@ -563,7 +572,7 @@ func TestRolePermissions(t *testing.T) {
},
{
Name: "WorkspaceDormant",
Actions: append(crud, policy.ActionWorkspaceStop, policy.ActionCreateAgent, policy.ActionDeleteAgent),
Actions: append(crud, policy.ActionWorkspaceStop, policy.ActionCreateAgent, policy.ActionDeleteAgent, policy.ActionUpdateAgent),
Resource: rbac.ResourceWorkspaceDormant.WithID(uuid.New()).InOrg(orgID).WithOwner(memberMe.Actor.ID),
AuthorizeMap: map[bool][]hasAuthSubjects{
true: {orgAdmin, owner},
+6
View File
@@ -135,6 +135,7 @@ const (
ScopeWorkspaceStart ScopeName = "workspace:start"
ScopeWorkspaceStop ScopeName = "workspace:stop"
ScopeWorkspaceUpdate ScopeName = "workspace:update"
ScopeWorkspaceUpdateAgent ScopeName = "workspace:update_agent"
ScopeWorkspaceAgentDevcontainersCreate ScopeName = "workspace_agent_devcontainers:create"
ScopeWorkspaceAgentResourceMonitorCreate ScopeName = "workspace_agent_resource_monitor:create"
ScopeWorkspaceAgentResourceMonitorRead ScopeName = "workspace_agent_resource_monitor:read"
@@ -150,6 +151,7 @@ const (
ScopeWorkspaceDormantStart ScopeName = "workspace_dormant:start"
ScopeWorkspaceDormantStop ScopeName = "workspace_dormant:stop"
ScopeWorkspaceDormantUpdate ScopeName = "workspace_dormant:update"
ScopeWorkspaceDormantUpdateAgent ScopeName = "workspace_dormant:update_agent"
ScopeWorkspaceProxyCreate ScopeName = "workspace_proxy:create"
ScopeWorkspaceProxyDelete ScopeName = "workspace_proxy:delete"
ScopeWorkspaceProxyRead ScopeName = "workspace_proxy:read"
@@ -293,6 +295,7 @@ func (e ScopeName) Valid() bool {
ScopeWorkspaceStart,
ScopeWorkspaceStop,
ScopeWorkspaceUpdate,
ScopeWorkspaceUpdateAgent,
ScopeWorkspaceAgentDevcontainersCreate,
ScopeWorkspaceAgentResourceMonitorCreate,
ScopeWorkspaceAgentResourceMonitorRead,
@@ -308,6 +311,7 @@ func (e ScopeName) Valid() bool {
ScopeWorkspaceDormantStart,
ScopeWorkspaceDormantStop,
ScopeWorkspaceDormantUpdate,
ScopeWorkspaceDormantUpdateAgent,
ScopeWorkspaceProxyCreate,
ScopeWorkspaceProxyDelete,
ScopeWorkspaceProxyRead,
@@ -452,6 +456,7 @@ func AllScopeNameValues() []ScopeName {
ScopeWorkspaceStart,
ScopeWorkspaceStop,
ScopeWorkspaceUpdate,
ScopeWorkspaceUpdateAgent,
ScopeWorkspaceAgentDevcontainersCreate,
ScopeWorkspaceAgentResourceMonitorCreate,
ScopeWorkspaceAgentResourceMonitorRead,
@@ -467,6 +472,7 @@ func AllScopeNameValues() []ScopeName {
ScopeWorkspaceDormantStart,
ScopeWorkspaceDormantStop,
ScopeWorkspaceDormantUpdate,
ScopeWorkspaceDormantUpdateAgent,
ScopeWorkspaceProxyCreate,
ScopeWorkspaceProxyDelete,
ScopeWorkspaceProxyRead,