Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit9d2c374

Browse files
chore: add WorkspaceAgent rbac policy
1 parente83ea4e commit9d2c374

File tree

16 files changed

+127
-10
lines changed

16 files changed

+127
-10
lines changed

‎coderd/agentapi/devcontainer_agent.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ type DevContainerAgentAPI struct {
2525
}
2626

2727
func (a*DevContainerAgentAPI)CreateDevContainerAgent(ctx context.Context,req*agentproto.CreateDevContainerAgentRequest) (*agentproto.CreateDevContainerAgentResponse,error) {
28+
ctx=dbauthz.AsDevContainerAgentAPI(ctx)
29+
2830
parentAgent,err:=a.AgentFn(ctx)
2931
iferr!=nil {
3032
returnnil,xerrors.Errorf("get parent agent: %w",err)
@@ -39,7 +41,7 @@ func (a *DevContainerAgentAPI) CreateDevContainerAgent(ctx context.Context, req
3941
// Validate this agent name
4042
agentName:=strings.ToLower(req.Name)
4143

42-
devContainerAgent,err:=a.Database.InsertWorkspaceAgent(dbauthz.AsSystemRestricted(ctx), database.InsertWorkspaceAgentParams{
44+
devContainerAgent,err:=a.Database.InsertWorkspaceAgent(ctx, database.InsertWorkspaceAgentParams{
4345
ID:uuid.New(),
4446
ParentID: uuid.NullUUID{Valid:true,UUID:parentAgent.ID},
4547
CreatedAt:a.Clock.Now(),
@@ -71,20 +73,24 @@ func (a *DevContainerAgentAPI) CreateDevContainerAgent(ctx context.Context, req
7173
}
7274

7375
func (a*DevContainerAgentAPI)DeleteDevContainerAgent(ctx context.Context,req*agentproto.DeleteDevContainerAgentRequest) (*emptypb.Empty,error) {
76+
ctx=dbauthz.AsDevContainerAgentAPI(ctx)
77+
7478
devContainerAgentID,err:=uuid.FromBytes(req.Id)
7579
iferr!=nil {
7680
returnnil,err
7781
}
7882

79-
iferr:=a.Database.DeleteWorkspaceAgentByID(dbauthz.AsSystemRestricted(ctx),devContainerAgentID);err!=nil {
83+
iferr:=a.Database.DeleteWorkspaceAgentByID(ctx,devContainerAgentID);err!=nil {
8084
returnnil,err
8185
}
8286

8387
return&emptypb.Empty{},nil
8488
}
8589

8690
func (a*DevContainerAgentAPI)ListDevContainerAgents(ctx context.Context,req*agentproto.ListDevContainerAgentsRequest) (*agentproto.ListDevContainerAgentsResponse,error) {
87-
workspaceAgents,err:=a.Database.GetWorkspaceAgentsWithParentID(dbauthz.AsSystemRestricted(ctx), uuid.NullUUID{Valid:true,UUID:a.AgentID})
91+
ctx=dbauthz.AsDevContainerAgentAPI(ctx)
92+
93+
workspaceAgents,err:=a.Database.GetWorkspaceAgentsWithParentID(ctx, uuid.NullUUID{Valid:true,UUID:a.AgentID})
8894
iferr!=nil {
8995
returnnil,err
9096
}

‎coderd/agentapi/devcontainer_agent_test.go

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,27 @@ package agentapi_test
22

33
import (
44
"context"
5+
"sync/atomic"
56
"testing"
67

8+
"cdr.dev/slog"
79
"github.com/coder/coder/v2/agent/proto"
810
"github.com/coder/coder/v2/coderd/agentapi"
911
"github.com/coder/coder/v2/coderd/database"
12+
"github.com/coder/coder/v2/coderd/database/dbauthz"
1013
"github.com/coder/coder/v2/coderd/database/dbgen"
1114
"github.com/coder/coder/v2/coderd/database/dbtestutil"
15+
"github.com/coder/coder/v2/coderd/rbac"
1216
"github.com/coder/coder/v2/testutil"
1317
"github.com/coder/quartz"
1418
"github.com/google/uuid"
19+
"github.com/prometheus/client_golang/prometheus"
1520
"github.com/stretchr/testify/require"
1621
)
1722

18-
funcdevContainerAgentAPI(t*testing.T)*agentapi.DevContainerAgentAPI {
23+
funcdevContainerAgentAPI(t*testing.T,log slog.Logger)*agentapi.DevContainerAgentAPI {
1924
db,_:=dbtestutil.NewDB(t)
25+
2026
user:=dbgen.User(t,db, database.User{})
2127
org:=dbgen.Organization(t,db, database.Organization{})
2228
template:=dbgen.Template(t,db, database.Template{
@@ -50,22 +56,29 @@ func devContainerAgentAPI(t *testing.T) *agentapi.DevContainerAgentAPI {
5056

5157
clock:=quartz.NewMock(t)
5258

59+
accessControlStore:=&atomic.Pointer[dbauthz.AccessControlStore]{}
60+
varacs dbauthz.AccessControlStore= dbauthz.AGPLTemplateAccessControlStore{}
61+
accessControlStore.Store(&acs)
62+
63+
auth:=rbac.NewStrictCachingAuthorizer(prometheus.NewRegistry())
64+
5365
return&agentapi.DevContainerAgentAPI{
5466
AgentID:agent.ID,
5567
AgentFn:func(context.Context) (database.WorkspaceAgent,error) {
5668
returnagent,nil
5769
},
5870
Clock:clock,
59-
Database:db,
71+
Database:dbauthz.New(db,auth,log,accessControlStore),
6072
}
6173
}
6274

6375
funcTestDevContainerAgentAPI(t*testing.T) {
6476
t.Parallel()
6577

78+
log:=testutil.Logger(t)
6679
ctx:=testutil.Context(t,testutil.WaitShort)
6780

68-
api:=devContainerAgentAPI(t)
81+
api:=devContainerAgentAPI(t,log)
6982

7083
// Given: There are no dev container agents.
7184
listResp,err:=api.ListDevContainerAgents(ctx,&proto.ListDevContainerAgentsRequest{})

‎coderd/apidoc/docs.go

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/apidoc/swagger.json

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/database/dbauthz/dbauthz.go

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,24 @@ var (
319319
Scope:rbac.ScopeAll,
320320
}.WithCachedASTValue()
321321

322+
subjectDevContainerAgentAPI= rbac.Subject{
323+
Type:rbac.SubjectTypeDevContainerAgentAPI,
324+
FriendlyName:"Dev Container Agent API",
325+
ID:uuid.Nil.String(),
326+
Roles:rbac.Roles([]rbac.Role{
327+
{
328+
Identifier: rbac.RoleIdentifier{Name:"devcontaineragentapi"},
329+
DisplayName:"Dev Container Agent API",
330+
Site:rbac.Permissions(map[string][]policy.Action{
331+
rbac.ResourceWorkspaceAgent.Type: {policy.ActionRead,policy.ActionCreate,policy.ActionDelete},
332+
}),
333+
Org:map[string][]rbac.Permission{},
334+
User: []rbac.Permission{},
335+
},
336+
}),
337+
Scope:rbac.ScopeAll,
338+
}.WithCachedASTValue()
339+
322340
subjectSystemRestricted= rbac.Subject{
323341
Type:rbac.SubjectTypeSystemRestricted,
324342
FriendlyName:"System",
@@ -437,6 +455,12 @@ func AsResourceMonitor(ctx context.Context) context.Context {
437455
returnAs(ctx,subjectResourceMonitor)
438456
}
439457

458+
// AsDevContainerAgentAPI returns a context with an actor that has permissions required for
459+
// handling the lifecycle of dev container agents.
460+
funcAsDevContainerAgentAPI(ctx context.Context) context.Context {
461+
returnAs(ctx,subjectDevContainerAgentAPI)
462+
}
463+
440464
// AsSystemRestricted returns a context with an actor that has permissions
441465
// required for various system operations (login, logout, metrics cache).
442466
funcAsSystemRestricted(ctx context.Context) context.Context {
@@ -1483,9 +1507,15 @@ func (q *querier) DeleteWebpushSubscriptions(ctx context.Context, ids []uuid.UUI
14831507
}
14841508

14851509
func (q*querier)DeleteWorkspaceAgentByID(ctx context.Context,id uuid.UUID)error {
1486-
iferr:=q.authorizeContext(ctx,policy.ActionDelete,rbac.ResourceSystem);err!=nil {
1510+
agent,err:=q.db.GetWorkspaceAgentByID(ctx,id)
1511+
iferr!=nil {
14871512
returnerr
14881513
}
1514+
1515+
iferr:=q.authorizeContext(ctx,policy.ActionDelete,agent);err!=nil {
1516+
returnerr
1517+
}
1518+
14891519
returnq.db.DeleteWorkspaceAgentByID(ctx,id)
14901520
}
14911521

@@ -3071,9 +3101,7 @@ func (q *querier) GetWorkspaceAgentsInLatestBuildByWorkspaceID(ctx context.Conte
30713101
}
30723102

30733103
func (q*querier)GetWorkspaceAgentsWithParentID(ctx context.Context,parentID uuid.NullUUID) ([]database.WorkspaceAgent,error) {
3074-
// TODO(DanielleMaywood):
3075-
// Replace usage of ResourceSystem with more appropriate resource type.
3076-
iferr:=q.authorizeContext(ctx,policy.ActionRead,rbac.ResourceSystem);err!=nil {
3104+
iferr:=q.authorizeContext(ctx,policy.ActionRead,rbac.ResourceWorkspaceAgent);err!=nil {
30773105
returnnil,err
30783106
}
30793107
returnq.db.GetWorkspaceAgentsWithParentID(ctx,parentID)

‎coderd/database/dbauthz/dbauthz_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4033,6 +4033,21 @@ func (s *MethodTestSuite) TestSystemFunctions() {
40334033
Asserts(rbac.ResourceProvisionerJobs.InOrg(o.ID),policy.ActionRead).
40344034
Returns(slice.New(a,b))
40354035
}))
4036+
s.Run("DeleteWorkspaceAgentByID",s.Subtest(func(db database.Store,check*expects) {
4037+
_=dbgen.User(s.T(),db, database.User{})
4038+
pj:=dbgen.ProvisionerJob(s.T(),db,nil, database.ProvisionerJob{})
4039+
res:=dbgen.WorkspaceResource(s.T(),db, database.WorkspaceResource{JobID:pj.ID})
4040+
agent:=dbgen.WorkspaceAgent(s.T(),db, database.WorkspaceAgent{ResourceID:res.ID})
4041+
check.Args(agent.ID).Asserts(rbac.ResourceWorkspaceAgent.WithID(agent.ID),policy.ActionDelete)
4042+
}))
4043+
s.Run("GetWorkspaceAgentsWithParentID",s.Subtest(func(db database.Store,check*expects) {
4044+
_=dbgen.User(s.T(),db, database.User{})
4045+
pj:=dbgen.ProvisionerJob(s.T(),db,nil, database.ProvisionerJob{})
4046+
res:=dbgen.WorkspaceResource(s.T(),db, database.WorkspaceResource{JobID:pj.ID})
4047+
agent:=dbgen.WorkspaceAgent(s.T(),db, database.WorkspaceAgent{ResourceID:res.ID})
4048+
_=dbgen.WorkspaceAgent(s.T(),db, database.WorkspaceAgent{ResourceID:res.ID,ParentID: uuid.NullUUID{Valid:true,UUID:agent.ID}})
4049+
check.Args(uuid.NullUUID{Valid:true,UUID:agent.ID}).Asserts(rbac.ResourceWorkspaceAgent,policy.ActionRead)
4050+
}))
40364051
s.Run("InsertWorkspaceAgent",s.Subtest(func(db database.Store,check*expects) {
40374052
u:=dbgen.User(s.T(),db, database.User{})
40384053
o:=dbgen.Organization(s.T(),db, database.Organization{})

‎coderd/database/modelmethods.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,10 @@ type WorkspaceAgentConnectionStatus struct {
359359
DisconnectedAt*time.Time`json:"disconnected_at"`
360360
}
361361

362+
func (aWorkspaceAgent)RBACObject() rbac.Object {
363+
returnrbac.ResourceWorkspaceAgent.WithID(a.ID)
364+
}
365+
362366
func (aWorkspaceAgent)Status(inactiveTimeout time.Duration)WorkspaceAgentConnectionStatus {
363367
connectionTimeout:=time.Duration(a.ConnectionTimeoutSeconds)*time.Second
364368

‎coderd/rbac/authz.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ const (
7373
SubjectTypeSystemReadProvisionerDaemonsSubjectType="system_read_provisioner_daemons"
7474
SubjectTypeSystemRestrictedSubjectType="system_restricted"
7575
SubjectTypeNotifierSubjectType="notifier"
76+
SubjectTypeDevContainerAgentAPISubjectType="devcontainer_agent_api"
7677
)
7778

7879
// Subject is a struct that contains all the elements of a subject in an rbac

‎coderd/rbac/object_gen.go

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/rbac/policy/policy.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,4 +343,11 @@ var RBACPermissions = map[string]PermissionDefinition{
343343
ActionCreate:actDef("create workspace agent devcontainers"),
344344
},
345345
},
346+
"workspace_agent": {
347+
Actions:map[Action]ActionDefinition{
348+
ActionRead:actDef("read workspace agent"),
349+
ActionCreate:actDef("create workspace agent"),
350+
ActionDelete:actDef("delete workspace agent"),
351+
},
352+
},
346353
}

‎coderd/rbac/roles_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -840,6 +840,21 @@ func TestRolePermissions(t *testing.T) {
840840
},
841841
},
842842
},
843+
{
844+
Name:"WorkspaceAgent",
845+
Actions: []policy.Action{policy.ActionRead,policy.ActionCreate,policy.ActionDelete},
846+
Resource:rbac.ResourceWorkspaceAgent,
847+
AuthorizeMap:map[bool][]hasAuthSubjects{
848+
true: {owner},
849+
false: {
850+
memberMe,orgMemberMe,otherOrgMember,
851+
orgAdmin,otherOrgAdmin,
852+
orgAuditor,otherOrgAuditor,
853+
templateAdmin,orgTemplateAdmin,otherOrgTemplateAdmin,
854+
userAdmin,orgUserAdmin,otherOrgUserAdmin,
855+
},
856+
},
857+
},
843858
// Members may read their own chats.
844859
{
845860
Name:"CreateReadUpdateDeleteMyChats",

‎codersdk/rbacresources_gen.go

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎docs/reference/api/members.md

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎docs/reference/api/schemas.md

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎site/src/api/rbacresourcesGenerated.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,11 @@ export const RBACResourceActions: Partial<
182182
stop:"allows stopping a workspace",
183183
update:"edit workspace settings (scheduling, permissions, parameters)",
184184
},
185+
workspace_agent:{
186+
create:"create workspace agent",
187+
delete:"delete workspace agent",
188+
read:"read workspace agent",
189+
},
185190
workspace_agent_devcontainers:{
186191
create:"create workspace agent devcontainers",
187192
},

‎site/src/api/typesGenerated.ts

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp