Skip to content

Commit 7c9cb92

Browse files
committed
refactor(dbauthz): add authz for system-level functions
- Introduces rbac.ResourceSystem - Grants system.* to system and provisionerd rbac subjects
1 parent fe10ba1 commit 7c9cb92

File tree

5 files changed

+312
-157
lines changed

5 files changed

+312
-157
lines changed

coderd/database/dbauthz/dbauthz.go

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -115,17 +115,16 @@ func ActorFromContext(ctx context.Context) (rbac.Subject, bool) {
115115
return a, ok
116116
}
117117

118-
// AsProvisionerd returns a context with an actor that has permissions required
119-
// for provisionerd to function.
120-
func AsProvisionerd(ctx context.Context) context.Context {
121-
return context.WithValue(ctx, authContextKey{}, rbac.Subject{
118+
var (
119+
subjectProvisionerd = rbac.Subject{
122120
ID: uuid.Nil.String(),
123121
Roles: rbac.Roles([]rbac.Role{
124122
{
125123
Name: "provisionerd",
126124
DisplayName: "Provisioner Daemon",
127125
Site: rbac.Permissions(map[string][]rbac.Action{
128126
rbac.ResourceFile.Type: {rbac.ActionRead},
127+
rbac.ResourceSystem.Type: {rbac.WildcardSymbol},
129128
rbac.ResourceTemplate.Type: {rbac.ActionRead, rbac.ActionUpdate},
130129
rbac.ResourceUser.Type: {rbac.ActionRead},
131130
rbac.ResourceWorkspace.Type: {rbac.ActionRead, rbac.ActionUpdate, rbac.ActionDelete},
@@ -135,14 +134,8 @@ func AsProvisionerd(ctx context.Context) context.Context {
135134
},
136135
}),
137136
Scope: rbac.ScopeAll,
138-
},
139-
)
140-
}
141-
142-
// AsAutostart returns a context with an actor that has permissions required
143-
// for autostart to function.
144-
func AsAutostart(ctx context.Context) context.Context {
145-
return context.WithValue(ctx, authContextKey{}, rbac.Subject{
137+
}
138+
subjectAutostart = rbac.Subject{
146139
ID: uuid.Nil.String(),
147140
Roles: rbac.Roles([]rbac.Role{
148141
{
@@ -157,14 +150,8 @@ func AsAutostart(ctx context.Context) context.Context {
157150
},
158151
}),
159152
Scope: rbac.ScopeAll,
160-
},
161-
)
162-
}
163-
164-
// AsSystemRestricted returns a context with an actor that has permissions
165-
// required for various system operations (login, logout, metrics cache).
166-
func AsSystemRestricted(ctx context.Context) context.Context {
167-
return context.WithValue(ctx, authContextKey{}, rbac.Subject{
153+
}
154+
subjectSystemRestricted = rbac.Subject{
168155
ID: uuid.Nil.String(),
169156
Roles: rbac.Roles([]rbac.Role{
170157
{
@@ -175,6 +162,7 @@ func AsSystemRestricted(ctx context.Context) context.Context {
175162
rbac.ResourceAPIKey.Type: {rbac.ActionCreate, rbac.ActionUpdate, rbac.ActionDelete},
176163
rbac.ResourceGroup.Type: {rbac.ActionCreate, rbac.ActionUpdate},
177164
rbac.ResourceRoleAssignment.Type: {rbac.ActionCreate},
165+
rbac.ResourceSystem.Type: {rbac.WildcardSymbol},
178166
rbac.ResourceOrganization.Type: {rbac.ActionCreate},
179167
rbac.ResourceOrganizationMember.Type: {rbac.ActionCreate},
180168
rbac.ResourceOrgRoleAssignment.Type: {rbac.ActionCreate},
@@ -187,8 +175,25 @@ func AsSystemRestricted(ctx context.Context) context.Context {
187175
},
188176
}),
189177
Scope: rbac.ScopeAll,
190-
},
191-
)
178+
}
179+
)
180+
181+
// AsProvisionerd returns a context with an actor that has permissions required
182+
// for provisionerd to function.
183+
func AsProvisionerd(ctx context.Context) context.Context {
184+
return context.WithValue(ctx, authContextKey{}, subjectProvisionerd)
185+
}
186+
187+
// AsAutostart returns a context with an actor that has permissions required
188+
// for autostart to function.
189+
func AsAutostart(ctx context.Context) context.Context {
190+
return context.WithValue(ctx, authContextKey{}, subjectAutostart)
191+
}
192+
193+
// AsSystemRestricted returns a context with an actor that has permissions
194+
// required for various system operations (login, logout, metrics cache).
195+
func AsSystemRestricted(ctx context.Context) context.Context {
196+
return context.WithValue(ctx, authContextKey{}, subjectSystemRestricted)
192197
}
193198

194199
var AsRemoveActor = rbac.Subject{

coderd/database/dbauthz/querier_test.go

Lines changed: 0 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -282,11 +282,6 @@ func (s *MethodTestSuite) TestProvsionerJob() {
282282
check.Args(database.UpdateProvisionerJobWithCancelByIDParams{ID: j.ID}).
283283
Asserts(v.RBACObject(tpl), []rbac.Action{rbac.ActionRead, rbac.ActionUpdate}).Returns()
284284
}))
285-
s.Run("GetProvisionerJobsByIDs", s.Subtest(func(db database.Store, check *expects) {
286-
a := dbgen.ProvisionerJob(s.T(), db, database.ProvisionerJob{})
287-
b := dbgen.ProvisionerJob(s.T(), db, database.ProvisionerJob{})
288-
check.Args([]uuid.UUID{a.ID, b.ID}).Asserts().Returns(slice.New(a, b))
289-
}))
290285
s.Run("GetProvisionerLogsByIDBetween", s.Subtest(func(db database.Store, check *expects) {
291286
w := dbgen.Workspace(s.T(), db, database.Workspace{})
292287
j := dbgen.ProvisionerJob(s.T(), db, database.ProvisionerJob{
@@ -619,22 +614,6 @@ func (s *MethodTestSuite) TestTemplate() {
619614
})
620615
check.Args(tv.ID).Asserts(t1, rbac.ActionRead).Returns(tv)
621616
}))
622-
s.Run("GetTemplateVersionsByIDs", s.Subtest(func(db database.Store, check *expects) {
623-
t1 := dbgen.Template(s.T(), db, database.Template{})
624-
t2 := dbgen.Template(s.T(), db, database.Template{})
625-
tv1 := dbgen.TemplateVersion(s.T(), db, database.TemplateVersion{
626-
TemplateID: uuid.NullUUID{UUID: t1.ID, Valid: true},
627-
})
628-
tv2 := dbgen.TemplateVersion(s.T(), db, database.TemplateVersion{
629-
TemplateID: uuid.NullUUID{UUID: t2.ID, Valid: true},
630-
})
631-
tv3 := dbgen.TemplateVersion(s.T(), db, database.TemplateVersion{
632-
TemplateID: uuid.NullUUID{UUID: t2.ID, Valid: true},
633-
})
634-
check.Args([]uuid.UUID{tv1.ID, tv2.ID, tv3.ID}).
635-
Asserts( /*t1, rbac.ActionRead, t2, rbac.ActionRead*/ ).
636-
Returns(slice.New(tv1, tv2, tv3))
637-
}))
638617
s.Run("GetTemplateVersionsByTemplateID", s.Subtest(func(db database.Store, check *expects) {
639618
t1 := dbgen.Template(s.T(), db, database.Template{})
640619
a := dbgen.TemplateVersion(s.T(), db, database.TemplateVersion{
@@ -803,13 +782,6 @@ func (s *MethodTestSuite) TestUser() {
803782
b := dbgen.User(s.T(), db, database.User{CreatedAt: database.Now()})
804783
check.Args(database.GetUsersParams{}).Asserts(a, rbac.ActionRead, b, rbac.ActionRead)
805784
}))
806-
s.Run("GetUsersByIDs", s.Subtest(func(db database.Store, check *expects) {
807-
a := dbgen.User(s.T(), db, database.User{CreatedAt: database.Now().Add(-time.Hour)})
808-
b := dbgen.User(s.T(), db, database.User{CreatedAt: database.Now()})
809-
check.Args([]uuid.UUID{a.ID, b.ID}).
810-
Asserts( /*a, rbac.ActionRead, b, rbac.ActionRead*/ ).
811-
Returns(slice.New(a, b))
812-
}))
813785
s.Run("InsertUser", s.Subtest(func(db database.Store, check *expects) {
814786
check.Args(database.InsertUserParams{
815787
ID: uuid.New(),
@@ -977,14 +949,6 @@ func (s *MethodTestSuite) TestWorkspace() {
977949
agt := dbgen.WorkspaceAgent(s.T(), db, database.WorkspaceAgent{ResourceID: res.ID})
978950
check.Args(agt.AuthInstanceID.String).Asserts(ws, rbac.ActionRead).Returns(agt)
979951
}))
980-
s.Run("GetWorkspaceAgentsByResourceIDs", s.Subtest(func(db database.Store, check *expects) {
981-
ws := dbgen.Workspace(s.T(), db, database.Workspace{})
982-
build := dbgen.WorkspaceBuild(s.T(), db, database.WorkspaceBuild{WorkspaceID: ws.ID, JobID: uuid.New()})
983-
res := dbgen.WorkspaceResource(s.T(), db, database.WorkspaceResource{JobID: build.JobID})
984-
agt := dbgen.WorkspaceAgent(s.T(), db, database.WorkspaceAgent{ResourceID: res.ID})
985-
check.Args([]uuid.UUID{res.ID}).Asserts( /*ws, rbac.ActionRead*/ ).
986-
Returns([]database.WorkspaceAgent{agt})
987-
}))
988952
s.Run("UpdateWorkspaceAgentLifecycleStateByID", s.Subtest(func(db database.Store, check *expects) {
989953
ws := dbgen.Workspace(s.T(), db, database.Workspace{})
990954
build := dbgen.WorkspaceBuild(s.T(), db, database.WorkspaceBuild{WorkspaceID: ws.ID, JobID: uuid.New()})
@@ -1026,23 +990,6 @@ func (s *MethodTestSuite) TestWorkspace() {
1026990

1027991
check.Args(agt.ID).Asserts(ws, rbac.ActionRead).Returns(slice.New(a, b))
1028992
}))
1029-
s.Run("GetWorkspaceAppsByAgentIDs", s.Subtest(func(db database.Store, check *expects) {
1030-
aWs := dbgen.Workspace(s.T(), db, database.Workspace{})
1031-
aBuild := dbgen.WorkspaceBuild(s.T(), db, database.WorkspaceBuild{WorkspaceID: aWs.ID, JobID: uuid.New()})
1032-
aRes := dbgen.WorkspaceResource(s.T(), db, database.WorkspaceResource{JobID: aBuild.JobID})
1033-
aAgt := dbgen.WorkspaceAgent(s.T(), db, database.WorkspaceAgent{ResourceID: aRes.ID})
1034-
a := dbgen.WorkspaceApp(s.T(), db, database.WorkspaceApp{AgentID: aAgt.ID})
1035-
1036-
bWs := dbgen.Workspace(s.T(), db, database.Workspace{})
1037-
bBuild := dbgen.WorkspaceBuild(s.T(), db, database.WorkspaceBuild{WorkspaceID: bWs.ID, JobID: uuid.New()})
1038-
bRes := dbgen.WorkspaceResource(s.T(), db, database.WorkspaceResource{JobID: bBuild.JobID})
1039-
bAgt := dbgen.WorkspaceAgent(s.T(), db, database.WorkspaceAgent{ResourceID: bRes.ID})
1040-
b := dbgen.WorkspaceApp(s.T(), db, database.WorkspaceApp{AgentID: bAgt.ID})
1041-
1042-
check.Args([]uuid.UUID{a.AgentID, b.AgentID}).
1043-
Asserts( /*aWs, rbac.ActionRead, bWs, rbac.ActionRead*/ ).
1044-
Returns([]database.WorkspaceApp{a, b})
1045-
}))
1046993
s.Run("GetWorkspaceBuildByID", s.Subtest(func(db database.Store, check *expects) {
1047994
ws := dbgen.Workspace(s.T(), db, database.Workspace{})
1048995
build := dbgen.WorkspaceBuild(s.T(), db, database.WorkspaceBuild{WorkspaceID: ws.ID})
@@ -1096,15 +1043,6 @@ func (s *MethodTestSuite) TestWorkspace() {
10961043
res := dbgen.WorkspaceResource(s.T(), db, database.WorkspaceResource{JobID: build.JobID})
10971044
check.Args(res.ID).Asserts(ws, rbac.ActionRead).Returns(res)
10981045
}))
1099-
s.Run("GetWorkspaceResourceMetadataByResourceIDs", s.Subtest(func(db database.Store, check *expects) {
1100-
ws := dbgen.Workspace(s.T(), db, database.Workspace{})
1101-
build := dbgen.WorkspaceBuild(s.T(), db, database.WorkspaceBuild{WorkspaceID: ws.ID, JobID: uuid.New()})
1102-
_ = dbgen.ProvisionerJob(s.T(), db, database.ProvisionerJob{ID: build.JobID, Type: database.ProvisionerJobTypeWorkspaceBuild})
1103-
a := dbgen.WorkspaceResource(s.T(), db, database.WorkspaceResource{JobID: build.JobID})
1104-
b := dbgen.WorkspaceResource(s.T(), db, database.WorkspaceResource{JobID: build.JobID})
1105-
check.Args([]uuid.UUID{a.ID, b.ID}).
1106-
Asserts( /*ws, []rbac.Action{rbac.ActionRead, rbac.ActionRead}*/ )
1107-
}))
11081046
s.Run("Build/GetWorkspaceResourcesByJobID", s.Subtest(func(db database.Store, check *expects) {
11091047
ws := dbgen.Workspace(s.T(), db, database.Workspace{})
11101048
build := dbgen.WorkspaceBuild(s.T(), db, database.WorkspaceBuild{WorkspaceID: ws.ID, JobID: uuid.New()})
@@ -1117,18 +1055,6 @@ func (s *MethodTestSuite) TestWorkspace() {
11171055
job := dbgen.ProvisionerJob(s.T(), db, database.ProvisionerJob{ID: v.JobID, Type: database.ProvisionerJobTypeTemplateVersionImport})
11181056
check.Args(job.ID).Asserts(v.RBACObject(tpl), []rbac.Action{rbac.ActionRead, rbac.ActionRead}).Returns([]database.WorkspaceResource{})
11191057
}))
1120-
s.Run("GetWorkspaceResourcesByJobIDs", s.Subtest(func(db database.Store, check *expects) {
1121-
tpl := dbgen.Template(s.T(), db, database.Template{})
1122-
v := dbgen.TemplateVersion(s.T(), db, database.TemplateVersion{TemplateID: uuid.NullUUID{UUID: tpl.ID, Valid: true}, JobID: uuid.New()})
1123-
tJob := dbgen.ProvisionerJob(s.T(), db, database.ProvisionerJob{ID: v.JobID, Type: database.ProvisionerJobTypeTemplateVersionImport})
1124-
1125-
ws := dbgen.Workspace(s.T(), db, database.Workspace{})
1126-
build := dbgen.WorkspaceBuild(s.T(), db, database.WorkspaceBuild{WorkspaceID: ws.ID, JobID: uuid.New()})
1127-
wJob := dbgen.ProvisionerJob(s.T(), db, database.ProvisionerJob{ID: build.JobID, Type: database.ProvisionerJobTypeWorkspaceBuild})
1128-
check.Args([]uuid.UUID{tJob.ID, wJob.ID}).
1129-
Asserts( /*v.RBACObject(tpl), rbac.ActionRead, ws, rbac.ActionRead*/ ).
1130-
Returns([]database.WorkspaceResource{})
1131-
}))
11321058
s.Run("InsertWorkspace", s.Subtest(func(db database.Store, check *expects) {
11331059
u := dbgen.User(s.T(), db, database.User{})
11341060
o := dbgen.Organization(s.T(), db, database.Organization{})

0 commit comments

Comments
 (0)