Skip to content

Commit 7f061b9

Browse files
authored
fix(coderd): add stricter authorization for provisioners endpoint (#16587)
References #16558
1 parent fbea757 commit 7f061b9

File tree

4 files changed

+23
-10
lines changed

4 files changed

+23
-10
lines changed

cli/provisioners_test.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ func TestProvisioners_Golden(t *testing.T) {
7171
})
7272
owner := coderdtest.CreateFirstUser(t, client)
7373
templateAdminClient, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID, rbac.ScopedRoleOrgTemplateAdmin(owner.OrganizationID))
74-
memberClient, member := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID)
74+
_, member := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID)
7575

7676
// Create initial resources with a running provisioner.
7777
firstProvisioner := coderdtest.NewTaggedProvisionerDaemon(t, coderdAPI, "default-provisioner", map[string]string{"owner": "", "scope": "organization"})
@@ -178,8 +178,9 @@ func TestProvisioners_Golden(t *testing.T) {
178178
t.Logf("replace[%q] = %q", id, replaceID)
179179
}
180180

181-
// Test provisioners list with member as members can access
182-
// provisioner daemons.
181+
// Test provisioners list with template admin as members are currently
182+
// unable to access provisioner jobs. In the future (with RBAC
183+
// changes), we may allow them to view _their_ jobs.
183184
t.Run("list", func(t *testing.T) {
184185
t.Parallel()
185186

@@ -190,7 +191,7 @@ func TestProvisioners_Golden(t *testing.T) {
190191
"--column", "id,created at,last seen at,name,version,tags,key name,status,current job id,current job status,previous job id,previous job status,organization",
191192
)
192193
inv.Stdout = &got
193-
clitest.SetupConfig(t, memberClient, root)
194+
clitest.SetupConfig(t, templateAdminClient, root)
194195
err := inv.Run()
195196
require.NoError(t, err)
196197

coderd/provisionerdaemons.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import (
99
"github.com/coder/coder/v2/coderd/httpapi"
1010
"github.com/coder/coder/v2/coderd/httpmw"
1111
"github.com/coder/coder/v2/coderd/provisionerdserver"
12+
"github.com/coder/coder/v2/coderd/rbac"
13+
"github.com/coder/coder/v2/coderd/rbac/policy"
1214
"github.com/coder/coder/v2/coderd/util/ptr"
1315
"github.com/coder/coder/v2/codersdk"
1416
)
@@ -31,6 +33,13 @@ func (api *API) provisionerDaemons(rw http.ResponseWriter, r *http.Request) {
3133
org = httpmw.OrganizationParam(r)
3234
)
3335

36+
// This endpoint returns information about provisioner jobs.
37+
// For now, only owners and template admins can access provisioner jobs.
38+
if !api.Authorize(r, policy.ActionRead, rbac.ResourceProvisionerJobs.InOrg(org.ID)) {
39+
httpapi.ResourceNotFound(rw)
40+
return
41+
}
42+
3443
qp := r.URL.Query()
3544
p := httpapi.NewQueryParamParser()
3645
limit := p.PositiveInt32(qp, 50, "limit")

coderd/provisionerdaemons_test.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -241,11 +241,14 @@ func TestProvisionerDaemons(t *testing.T) {
241241
require.Nil(t, daemons[0].PreviousJob)
242242
})
243243

244-
t.Run("MemberAllowed", func(t *testing.T) {
244+
// For now, this is not allowed even though the member has created a
245+
// workspace. Once member-level permissions for jobs are supported
246+
// by RBAC, this test should be updated.
247+
t.Run("MemberDenied", func(t *testing.T) {
245248
t.Parallel()
246249
ctx := testutil.Context(t, testutil.WaitMedium)
247250
daemons, err := memberClient.OrganizationProvisionerDaemons(ctx, owner.OrganizationID, nil)
248-
require.NoError(t, err)
249-
require.Len(t, daemons, 50)
251+
require.Error(t, err)
252+
require.Len(t, daemons, 0)
250253
})
251254
}

enterprise/coderd/provisionerdaemons_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -953,7 +953,7 @@ func TestGetProvisionerDaemons(t *testing.T) {
953953
org := coderdenttest.CreateOrganization(t, client, coderdenttest.CreateOrganizationOptions{
954954
IncludeProvisionerDaemon: false,
955955
})
956-
orgAdmin, _ := coderdtest.CreateAnotherUser(t, client, org.ID, rbac.ScopedRoleOrgMember(org.ID))
956+
orgTemplateAdmin, _ := coderdtest.CreateAnotherUser(t, client, org.ID, rbac.ScopedRoleOrgTemplateAdmin(org.ID))
957957

958958
daemonCreatedAt := time.Now()
959959

@@ -986,11 +986,11 @@ func TestGetProvisionerDaemons(t *testing.T) {
986986
require.NoError(t, err, "should be able to create provisioner daemon")
987987
daemonAsCreated := db2sdk.ProvisionerDaemon(pd)
988988

989-
allDaemons, err := orgAdmin.OrganizationProvisionerDaemons(ctx, org.ID, nil)
989+
allDaemons, err := orgTemplateAdmin.OrganizationProvisionerDaemons(ctx, org.ID, nil)
990990
require.NoError(t, err)
991991
require.Len(t, allDaemons, 1)
992992

993-
daemonsAsFound, err := orgAdmin.OrganizationProvisionerDaemons(ctx, org.ID, &codersdk.OrganizationProvisionerDaemonsOptions{
993+
daemonsAsFound, err := orgTemplateAdmin.OrganizationProvisionerDaemons(ctx, org.ID, &codersdk.OrganizationProvisionerDaemonsOptions{
994994
Tags: tt.tagsToFilterBy,
995995
})
996996
if tt.expectToGetDaemon {

0 commit comments

Comments
 (0)