- Notifications
You must be signed in to change notification settings - Fork925
feat: allow TemplateAdmin to delete prebuilds via auth layer#18333
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Changes fromall commits
2ba15c5
a043f92
6cae769
afc5359
b2c7bdd
f24e4ab
98576c6
9d2bf8b
d461a3d
5f896f0
f4ae6bc
998fa3b
007f3fd
f811778
ed8af65
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more abouthow customized files appear on GitHub.
Uh oh!
There was an error while loading.Please reload this page.
Some generated files are not rendered by default. Learn more abouthow customized files appear on GitHub.
Uh oh!
There was an error while loading.Please reload this page.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
package database | ||
import "github.com/google/uuid" | ||
var PrebuildsSystemUserID = uuid.MustParse("c42fdf75-3097-471c-8c33-fb52454d81c0") |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -21,7 +21,6 @@ import ( | ||
"github.com/coder/coder/v2/coderd/database/dbtime" | ||
"github.com/coder/coder/v2/coderd/httpapi/httpapiconstraints" | ||
"github.com/coder/coder/v2/coderd/httpmw/loggermw" | ||
"github.com/coder/coder/v2/coderd/rbac" | ||
"github.com/coder/coder/v2/coderd/rbac/policy" | ||
"github.com/coder/coder/v2/coderd/rbac/rolestore" | ||
@@ -150,6 +149,30 @@ func (q *querier) authorizeContext(ctx context.Context, action policy.Action, ob | ||
return nil | ||
} | ||
// authorizePrebuiltWorkspace handles authorization for workspace resource types. | ||
// prebuilt_workspaces are a subset of workspaces, currently limited to | ||
// supporting delete operations. Therefore, if the action is delete or | ||
// update and the workspace is a prebuild, a prebuilt-specific authorization | ||
// is attempted first. If that fails, it falls back to normal workspace | ||
// authorization. | ||
// Note: Delete operations of workspaces requires both update and delete | ||
// permissions. | ||
func (q *querier) authorizePrebuiltWorkspace(ctx context.Context, action policy.Action, workspace database.Workspace) error { | ||
ssncferreira marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
var prebuiltErr error | ||
// Special handling for prebuilt_workspace deletion authorization check | ||
if (action == policy.ActionUpdate || action == policy.ActionDelete) && workspace.IsPrebuild() { | ||
// Try prebuilt-specific authorization first | ||
if prebuiltErr = q.authorizeContext(ctx, action, workspace.AsPrebuild()); prebuiltErr == nil { | ||
return nil | ||
} | ||
} | ||
// Fallback to normal workspace authorization check | ||
if err := q.authorizeContext(ctx, action, workspace); err != nil { | ||
return xerrors.Errorf("authorize context: %w", errors.Join(prebuiltErr, err)) | ||
} | ||
Comment on lines +163 to +172 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. I think the normal workspace check is more likely to succeed then the prebuild. So it might be a slight optimization to flip these checks. But that will probably break some of the unit tests? No need to change this, just a thought. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Good point, I had considered that optimization as well. I believe it might require some test updates, so I'd prefer to merge this PR and address the optimization in a follow-up PR. | ||
return nil | ||
} | ||
type authContextKey struct{} | ||
// ActorFromContext returns the authorization subject from the context. | ||
@@ -399,7 +422,7 @@ var ( | ||
subjectPrebuildsOrchestrator = rbac.Subject{ | ||
Type: rbac.SubjectTypePrebuildsOrchestrator, | ||
FriendlyName: "Prebuilds Orchestrator", | ||
ID:database.PrebuildsSystemUserID.String(), | ||
Roles: rbac.Roles([]rbac.Role{ | ||
{ | ||
Identifier: rbac.RoleIdentifier{Name: "prebuilds-orchestrator"}, | ||
@@ -412,6 +435,12 @@ var ( | ||
policy.ActionCreate, policy.ActionDelete, policy.ActionRead, policy.ActionUpdate, | ||
policy.ActionWorkspaceStart, policy.ActionWorkspaceStop, | ||
}, | ||
// PrebuiltWorkspaces are a subset of Workspaces. | ||
// Explicitly setting PrebuiltWorkspace permissions for clarity. | ||
// Note: even without PrebuiltWorkspace permissions, access is still granted via Workspace permissions. | ||
rbac.ResourcePrebuiltWorkspace.Type: { | ||
policy.ActionUpdate, policy.ActionDelete, | ||
}, | ||
// Should be able to add the prebuilds system user as a member to any organization that needs prebuilds. | ||
rbac.ResourceOrganizationMember.Type: { | ||
policy.ActionCreate, | ||
@@ -3953,8 +3982,9 @@ func (q *querier) InsertWorkspaceBuild(ctx context.Context, arg database.InsertW | ||
action = policy.ActionWorkspaceStop | ||
} | ||
// Special handling for prebuilt workspace deletion | ||
if err := q.authorizePrebuiltWorkspace(ctx, action, w); err != nil { | ||
return err | ||
} | ||
// If we're starting a workspace we need to check the template. | ||
@@ -3993,8 +4023,8 @@ func (q *querier) InsertWorkspaceBuildParameters(ctx context.Context, arg databa | ||
return err | ||
} | ||
// Special handling for prebuiltworkspace deletion | ||
if err:= q.authorizePrebuiltWorkspace(ctx, policy.ActionUpdate, workspace); err!= nil { | ||
return err | ||
} | ||
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.