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

Commitcfdea02

Browse files
chore: add WorkspaceAgent rbac policy
1 parentfccd2de commitcfdea02

File tree

16 files changed

+133
-12
lines changed

16 files changed

+133
-12
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: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ var (
177177
// Unsure why provisionerd needs update and read personal
178178
rbac.ResourceUser.Type: {policy.ActionRead,policy.ActionReadPersonal,policy.ActionUpdatePersonal},
179179
rbac.ResourceWorkspaceDormant.Type: {policy.ActionDelete,policy.ActionRead,policy.ActionUpdate,policy.ActionWorkspaceStop},
180+
rbac.ResourceWorkspaceAgent.Type: {policy.ActionCreate},
180181
rbac.ResourceWorkspace.Type: {policy.ActionDelete,policy.ActionRead,policy.ActionUpdate,policy.ActionWorkspaceStart,policy.ActionWorkspaceStop},
181182
rbac.ResourceApiKey.Type: {policy.WildcardSymbol},
182183
// When org scoped provisioner credentials are implemented,
@@ -318,6 +319,24 @@ var (
318319
Scope:rbac.ScopeAll,
319320
}.WithCachedASTValue()
320321

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+
321340
subjectSystemRestricted= rbac.Subject{
322341
Type:rbac.SubjectTypeSystemRestricted,
323342
FriendlyName:"System",
@@ -346,6 +365,7 @@ var (
346365
rbac.ResourceNotificationTemplate.Type: {policy.ActionCreate,policy.ActionUpdate,policy.ActionDelete},
347366
rbac.ResourceCryptoKey.Type: {policy.ActionCreate,policy.ActionUpdate,policy.ActionDelete},
348367
rbac.ResourceFile.Type: {policy.ActionCreate,policy.ActionRead},
368+
rbac.ResourceWorkspaceAgent.Type: {policy.ActionCreate,policy.ActionRead,policy.ActionDelete},
349369
}),
350370
Org:map[string][]rbac.Permission{},
351371
User: []rbac.Permission{},
@@ -435,6 +455,12 @@ func AsResourceMonitor(ctx context.Context) context.Context {
435455
returnAs(ctx,subjectResourceMonitor)
436456
}
437457

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+
438464
// AsSystemRestricted returns a context with an actor that has permissions
439465
// required for various system operations (login, logout, metrics cache).
440466
funcAsSystemRestricted(ctx context.Context) context.Context {
@@ -1482,9 +1508,15 @@ func (q *querier) DeleteWebpushSubscriptions(ctx context.Context, ids []uuid.UUI
14821508
}
14831509

14841510
func (q*querier)DeleteWorkspaceAgentByID(ctx context.Context,id uuid.UUID)error {
1485-
iferr:=q.authorizeContext(ctx,policy.ActionDelete,rbac.ResourceSystem);err!=nil {
1511+
agent,err:=q.db.GetWorkspaceAgentByID(ctx,id)
1512+
iferr!=nil {
14861513
returnerr
14871514
}
1515+
1516+
iferr:=q.authorizeContext(ctx,policy.ActionDelete,agent);err!=nil {
1517+
returnerr
1518+
}
1519+
14881520
returnq.db.DeleteWorkspaceAgentByID(ctx,id)
14891521
}
14901522

@@ -3044,9 +3076,7 @@ func (q *querier) GetWorkspaceAgentsInLatestBuildByWorkspaceID(ctx context.Conte
30443076
}
30453077

30463078
func (q*querier)GetWorkspaceAgentsWithParentID(ctx context.Context,parentID uuid.NullUUID) ([]database.WorkspaceAgent,error) {
3047-
// TODO(DanielleMaywood):
3048-
// Replace usage of ResourceSystem with more appropriate resource type.
3049-
iferr:=q.authorizeContext(ctx,policy.ActionRead,rbac.ResourceSystem);err!=nil {
3079+
iferr:=q.authorizeContext(ctx,policy.ActionRead,rbac.ResourceWorkspaceAgent);err!=nil {
30503080
returnnil,err
30513081
}
30523082
returnq.db.GetWorkspaceAgentsWithParentID(ctx,parentID)
@@ -3707,9 +3737,10 @@ func (q *querier) InsertWorkspace(ctx context.Context, arg database.InsertWorksp
37073737
}
37083738

37093739
func (q*querier)InsertWorkspaceAgent(ctx context.Context,arg database.InsertWorkspaceAgentParams) (database.WorkspaceAgent,error) {
3710-
iferr:=q.authorizeContext(ctx,policy.ActionCreate,rbac.ResourceSystem);err!=nil {
3740+
iferr:=q.authorizeContext(ctx,policy.ActionCreate,rbac.ResourceWorkspaceAgent);err!=nil {
37113741
return database.WorkspaceAgent{},err
37123742
}
3743+
37133744
returnq.db.InsertWorkspaceAgent(ctx,arg)
37143745
}
37153746

‎coderd/database/dbauthz/dbauthz_test.go

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3983,12 +3983,27 @@ func (s *MethodTestSuite) TestSystemFunctions() {
39833983
Asserts(/*rbac.ResourceSystem, policy.ActionRead*/ ).
39843984
Returns(slice.New(a,b))
39853985
}))
3986+
s.Run("DeleteWorkspaceAgentByID",s.Subtest(func(db database.Store,check*expects) {
3987+
_=dbgen.User(s.T(),db, database.User{})
3988+
pj:=dbgen.ProvisionerJob(s.T(),db,nil, database.ProvisionerJob{})
3989+
res:=dbgen.WorkspaceResource(s.T(),db, database.WorkspaceResource{JobID:pj.ID})
3990+
agent:=dbgen.WorkspaceAgent(s.T(),db, database.WorkspaceAgent{ResourceID:res.ID})
3991+
check.Args(agent.ID).Asserts(rbac.ResourceWorkspaceAgent.WithID(agent.ID),policy.ActionDelete)
3992+
}))
3993+
s.Run("GetWorkspaceAgentsWithParentID",s.Subtest(func(db database.Store,check*expects) {
3994+
_=dbgen.User(s.T(),db, database.User{})
3995+
pj:=dbgen.ProvisionerJob(s.T(),db,nil, database.ProvisionerJob{})
3996+
res:=dbgen.WorkspaceResource(s.T(),db, database.WorkspaceResource{JobID:pj.ID})
3997+
agent:=dbgen.WorkspaceAgent(s.T(),db, database.WorkspaceAgent{ResourceID:res.ID})
3998+
_=dbgen.WorkspaceAgent(s.T(),db, database.WorkspaceAgent{ResourceID:res.ID,ParentID: uuid.NullUUID{Valid:true,UUID:agent.ID}})
3999+
check.Args(uuid.NullUUID{Valid:true,UUID:agent.ID}).Asserts(rbac.ResourceWorkspaceAgent,policy.ActionRead)
4000+
}))
39864001
s.Run("InsertWorkspaceAgent",s.Subtest(func(db database.Store,check*expects) {
39874002
dbtestutil.DisableForeignKeysAndTriggers(s.T(),db)
39884003
check.Args(database.InsertWorkspaceAgentParams{
39894004
ID:uuid.New(),
39904005
Name:"dev",
3991-
}).Asserts(rbac.ResourceSystem,policy.ActionCreate)
4006+
}).Asserts(rbac.ResourceWorkspaceAgent,policy.ActionCreate)
39924007
}))
39934008
s.Run("InsertWorkspaceApp",s.Subtest(func(db database.Store,check*expects) {
39944009
dbtestutil.DisableForeignKeysAndTriggers(s.T(),db)

‎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
@@ -335,4 +335,11 @@ var RBACPermissions = map[string]PermissionDefinition{
335335
ActionCreate:actDef("create workspace agent devcontainers"),
336336
},
337337
},
338+
"workspace_agent": {
339+
Actions:map[Action]ActionDefinition{
340+
ActionRead:actDef("read workspace agent"),
341+
ActionCreate:actDef("create workspace agent"),
342+
ActionDelete:actDef("delete workspace agent"),
343+
},
344+
},
338345
}

‎coderd/rbac/roles_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -831,6 +831,21 @@ func TestRolePermissions(t *testing.T) {
831831
},
832832
},
833833
},
834+
{
835+
Name:"WorkspaceAgent",
836+
Actions: []policy.Action{policy.ActionRead,policy.ActionCreate,policy.ActionDelete},
837+
Resource:rbac.ResourceWorkspaceAgent,
838+
AuthorizeMap:map[bool][]hasAuthSubjects{
839+
true: {owner},
840+
false: {
841+
memberMe,orgMemberMe,otherOrgMember,
842+
orgAdmin,otherOrgAdmin,
843+
orgAuditor,otherOrgAuditor,
844+
templateAdmin,orgTemplateAdmin,otherOrgTemplateAdmin,
845+
userAdmin,orgUserAdmin,otherOrgUserAdmin,
846+
},
847+
},
848+
},
834849
// Members may read their own chats.
835850
{
836851
Name:"CreateReadUpdateDeleteMyChats",

‎codersdk/rbacresources_gen.go

Lines changed: 2 additions & 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.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp