Skip to content

chore: implement 'use' verb to template object, read has less scope now #16075

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 our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
Jan 17, 2025

Conversation

Emyrk
Copy link
Member

@Emyrk Emyrk commented Jan 8, 2025

Closes #15891

Template use is now a verb.

  • Template admins can use all templates (org template admins same in org)
  • Members get the use perm from the everyone group in the group_acl.

use.template permission is now checked when creating a workspace. If you already have a workspace, you are able to start/stop/delete/etc the workspace even without use.template.

@@ -191,6 +191,51 @@ func TestCreateWorkspace(t *testing.T) {
require.Equal(t, http.StatusBadRequest, apiErr.StatusCode())
require.Contains(t, apiErr.Message, "doesn't exist")
})

// Auditors cannot "use" templates, they can only read them.
t.Run("Auditor", func(t *testing.T) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This passes without an error on main. Now auditors get a 403 Forbidden if they do not have use perms from somewhere else

@Emyrk Emyrk marked this pull request as ready for review January 9, 2025 17:56
Comment on lines +699 to +707
func TemplateRoleActions(role codersdk.TemplateRole) []policy.Action {
switch role {
case codersdk.TemplateRoleAdmin:
return []policy.Action{policy.WildcardSymbol}
case codersdk.TemplateRoleUse:
return []policy.Action{policy.ActionRead, policy.ActionUse}
}
return []policy.Action{}
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted to place this in codersdk, but then I'd have to import policy. And we already have codersdk.RBACAction.

TemplateRole should probably be a database enum. At present it only exists in codersdk.

@Emyrk Emyrk requested a review from spikecurtis January 10, 2025 05:13
-- Instead of trying to write a complicated SQL query to update the JSONB
-- object, a string replace is much simpler and easier to understand.
-- Both pieces of text are JSON arrays, so this safe to do.
group_acl = replace(group_acl::text, '["read"]', '["read", "use"]')::jsonb,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to have ACLs like ["read", "update"] in this list? Wouldn't those need to be updated?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No it is not. The only values a user can pass in is in this enum list:
https://github.com/coder/coder/blob/main/codersdk/templates.go#L169-L176

The admin role sets ['*']. So we only have 2 cases in the database today

@Emyrk
Copy link
Member Author

Emyrk commented Jan 10, 2025

This feels very fragile. This seems to be the only prod code path that creates a workspace, but there isn't anything enforcing this. If we add a new API endpoint, or if some other existing action can lead to a workspace being created, we could forget this check.

The db.InsertWorkspace call includes the template in its parameters, so we should be able to move this check to the dbauth layer where it is harder to accidentally omit.

The db.InsertWorkspace does require an extra db call to fetch the template again, but we do that in other places. I'll add the use check in db.InsertWorkspace.

I am also keeping the check in the api call to fail fast if the permission is missing. Not having to do all the build work if it will inevitably fail.

Comment on lines +3161 to +3171
tpl, err := q.GetTemplateByID(ctx, arg.TemplateID)
if err != nil {
return database.WorkspaceTable{}, xerrors.Errorf("verify template by id: %w", err)
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does check the template read perm again, but we cache all authz requests per ctx. So this check is going to be a cache lookup assuming it came from a normal code path.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we cache the resources themselves, or just the authz decisions?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We only cache the authz decisions. The template fetch will happen again unfortunately (from a performance POV).

@Emyrk Emyrk force-pushed the stevenmasley/use_template branch from ffee414 to 36d329c Compare January 13, 2025 12:44
@Emyrk Emyrk requested a review from spikecurtis January 16, 2025 21:39
Copy link
Contributor

@spikecurtis spikecurtis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Comment on lines +3161 to +3171
tpl, err := q.GetTemplateByID(ctx, arg.TemplateID)
if err != nil {
return database.WorkspaceTable{}, xerrors.Errorf("verify template by id: %w", err)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we cache the resources themselves, or just the authz decisions?

@Emyrk Emyrk changed the title chore: add 'use' verb to template object chore: implement 'use' verb to template object, read has less scope now Jan 17, 2025
@Emyrk Emyrk merged commit f34e6fd into main Jan 17, 2025
35 of 37 checks passed
@Emyrk Emyrk deleted the stevenmasley/use_template branch January 17, 2025 17:55
@github-actions github-actions bot locked and limited conversation to collaborators Jan 17, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Auditor Role is able to read all templates, meaning they can create a workspace from any template
2 participants