Skip to content

Commit 0ffffeb

Browse files
committed
Add nesting of teams to the policy
1 parent c666797 commit 0ffffeb

File tree

5 files changed

+82
-45
lines changed

5 files changed

+82
-45
lines changed

coderd/database/spice/policy/playground/main.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ func usage() {
2323
fmt.Println("Usage: policycmd [command]")
2424
fmt.Println("Commands:")
2525
fmt.Println(" export")
26-
fmt.Println(" import")
27-
fmt.Println(" playground")
28-
fmt.Println(" run")
29-
fmt.Println(" test")
26+
//fmt.Println(" import")
27+
//fmt.Println(" playground")
28+
//fmt.Println(" run")
29+
//fmt.Println(" test")
3030
}

coderd/database/spice/policy/playground/relationships/generate.sh

100644100755
File mode changed.

coderd/database/spice/policy/playground/relationships/objects.go

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,22 @@ func (obj *ObjTeam) Platform(subs ...*ObjPlatform) *ObjTeam {
126126
return obj
127127
}
128128

129+
func (obj *ObjTeam) Parent(subs ...*ObjTeam) *ObjTeam {
130+
for i := range subs {
131+
sub := subs[i]
132+
obj.AddRelation(v1.Relationship{
133+
Resource: obj.Obj,
134+
Relation: "parent",
135+
Subject: &v1.SubjectReference{
136+
Object: sub.Obj,
137+
OptionalRelation: "",
138+
},
139+
OptionalCaveat: nil,
140+
})
141+
}
142+
return obj
143+
}
144+
129145
func (obj *ObjTeam) MemberGroup(subs ...*ObjGroup) *ObjTeam {
130146
for i := range subs {
131147
sub := subs[i]
@@ -542,10 +558,10 @@ func (obj *ObjTeam) Template_insights_viewerUser(subs ...*ObjUser) *ObjTeam {
542558
return obj
543559
}
544560

545-
func (obj *ObjTeam) ValidateMembership() *ObjTeam {
561+
func (obj *ObjTeam) ValidateDirect_membership() *ObjTeam {
546562
obj.AddValidation(v1.Relationship{
547563
Resource: obj.Obj,
548-
Relation: "membership",
564+
Relation: "direct_membership",
549565
OptionalCaveat: nil,
550566
})
551567
return obj
@@ -659,12 +675,12 @@ func (obj *ObjTeam) ValidateCreate_template() *ObjTeam {
659675
return obj
660676
}
661677

662-
func (obj *ObjTeam) CanMembershipBy(subs ...ObjectWithRelationships) *ObjTeam {
678+
func (obj *ObjTeam) CanDirect_membershipBy(subs ...ObjectWithRelationships) *ObjTeam {
663679
for i := range subs {
664680
sub := subs[i]
665681
obj.AssertTrue(v1.Relationship{
666682
Resource: obj.Obj,
667-
Relation: "membership",
683+
Relation: "direct_membership",
668684
Subject: &v1.SubjectReference{
669685
Object: sub.Object(),
670686
OptionalRelation: "",
@@ -675,12 +691,12 @@ func (obj *ObjTeam) CanMembershipBy(subs ...ObjectWithRelationships) *ObjTeam {
675691
return obj
676692
}
677693

678-
func (obj *ObjTeam) CannotMembershipBy(subs ...ObjectWithRelationships) *ObjTeam {
694+
func (obj *ObjTeam) CannotDirect_membershipBy(subs ...ObjectWithRelationships) *ObjTeam {
679695
for i := range subs {
680696
sub := subs[i]
681697
obj.AssertFalse(v1.Relationship{
682698
Resource: obj.Obj,
683-
Relation: "membership",
699+
Relation: "direct_membership",
684700
Subject: &v1.SubjectReference{
685701
Object: sub.Object(),
686702
OptionalRelation: "",

coderd/database/spice/policy/playground/relationships/relationships.go

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28,34 +28,50 @@ func GenerateRelationships() {
2828
groupEveryone := Group("everyone").MemberWildcard()
2929
groupHR := Group("hr").MemberUser(camilla)
3030
groupFinance := Group("finance").MemberUser(ammar, kyle, shark)
31-
groupCostControl := Group("cost-control").MemberGroup(groupFinance).MemberUser(dean, colin)
31+
groupCostControl := Group("cost-control").MemberUser(ammar, kyle, dean, colin)
3232
groupEngineers := Group("engineers").MemberUser(ammar, colin, dean, jon, kayla, kira, kyle, steven)
3333
groupMarketing := Group("marketing").MemberUser(katherine, ammar)
3434
groupSales := Group("sales").MemberUser(shark, eric)
3535

3636
// Teams
37-
teamCompany := Team("company").Platform(platform)
38-
teamLegal := Team("legal").Platform(platform)
39-
teamMarketing := Team("marketing").Platform(platform)
37+
teamCompany := Team("company").
38+
Platform(platform).
39+
// Cost control can see all workspaces
40+
Workspace_viewerGroup(groupCostControl)
41+
teamLegal := Team("legal").Platform(platform).
42+
Parent(teamCompany)
43+
teamMarketing := Team("marketing").Platform(platform).
44+
Parent(teamCompany)
45+
46+
// company
47+
// ├── legal
48+
// ├── marketing
49+
// └── engineering
50+
// ├── developers
51+
// └── technical
52+
teamEngineering := Team("engineering").Platform(platform).
53+
Parent(teamCompany)
54+
4055
// People who write code
41-
teamDevelopers := Team("developers").Platform(platform)
56+
teamDevelopers := Team("developers").Platform(platform).
57+
Parent(teamEngineering)
4258
// People who tinker
43-
teamTechnical := Team("technical").Platform(platform)
44-
//teamCustomerSuccess := Team("customer-success").Platform(platform) // Customer solutions
45-
//teamEngineering := Team("engineering").Platform(platform)
59+
teamTechnical := Team("technical").Platform(platform).
60+
Parent(teamEngineering)
4661

4762
// Nest some teams
4863
// TODO: This is currently unsupported
4964

5065
// Assign groups to teams
51-
teamCompany.MemberGroup(groupEveryone)
52-
teamLegal.MemberGroup(groupHR, groupFinance)
53-
teamMarketing.MemberGroup(groupMarketing)
54-
teamDevelopers.
55-
Workspace_creatorGroup(groupEngineers).
66+
teamCompany.MemberGroup(groupEveryone).
5667
// Cost control groups can edit workspaces & delete them
5768
Workspace_editorGroup(groupCostControl).
5869
Workspace_deletorGroup(groupCostControl)
70+
teamLegal.MemberGroup(groupHR, groupFinance)
71+
teamMarketing.MemberGroup(groupMarketing)
72+
73+
teamDevelopers.
74+
Workspace_creatorGroup(groupEngineers)
5975

6076
teamTechnical.
6177
Workspace_creatorGroup(groupEngineers, groupSales).
@@ -78,9 +94,9 @@ func GenerateRelationships() {
7894

7995
// Add some assertions
8096
stevenWorkspace.
81-
CanViewBy(steven).
82-
CannotViewBy(camilla)
97+
CanViewBy(steven, ammar, kyle).
98+
CannotViewBy(camilla, jon)
8399

84100
// Validations enumerate who can do the given action.
85-
stevenWorkspace.ValidateView().ValidateSsh()
101+
stevenWorkspace.ValidateView().ValidateSsh().ValidateEdit()
86102
}

coderd/database/spice/policy/schema.zed

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,17 @@ definition platform {
1414
permission super_admin = administrator
1515
}
1616

17+
1718
// team is a collection of resources.
1819
// TODO: Should we call this a namespace?
1920
definition team {
2021
// platform relation is the super admin level. All super-admin type permissions
2122
// are passed through the team level.
2223
relation platform: platform
2324

25+
// parent allows nesting teams
26+
relation parent: team
27+
2428
// Teams have their own roles for user's to interact with team resources.
2529
// Each role can be either a group or a user.
2630

@@ -67,33 +71,34 @@ definition team {
6771
* Other Roles *
6872
*******************/
6973

70-
// membership needs to include all ways in which someone is a member of this team.
71-
permission membership = member +
74+
// direct_membership needs to include all ways in which someone is a member of this team.
75+
// This does not include parent team members.
76+
permission direct_membership = member +
7277
workspace_viewer + workspace_creator + workspace_deletor + workspace_version_selector + dangerous_workspace_connector + workspace_editor +
7378
template_viewer + template_creator + template_deletor + template_editor
7479

7580
/*************************
7681
* Workspace Permissions *
7782
*************************/
7883
// view all workspaces owned by the team
79-
permission view_workspaces = platform->super_admin + workspace_viewer
80-
permission edit_workspaces = platform->super_admin + workspace_editor
81-
permission select_workspace_version = platform->super_admin + workspace_version_selector
82-
permission delete_workspaces = platform->super_admin + workspace_deletor
83-
permission connect_workspaces = dangerous_workspace_connector
84+
permission view_workspaces = platform->super_admin + workspace_viewer + parent->view_workspaces
85+
permission edit_workspaces = platform->super_admin + workspace_editor + parent->edit_workspaces
86+
permission select_workspace_version = platform->super_admin + workspace_version_selector + parent->select_workspace_version
87+
permission delete_workspaces = platform->super_admin + workspace_deletor + parent->delete_workspaces
88+
permission connect_workspaces = dangerous_workspace_connector + parent->connect_workspaces
8489
// create_workspace is on the team level object. A workspace that is created is owned by the team
8590
// and the application should setup the correct permissions/relations for the new resource.
86-
permission create_workspace = platform->super_admin + workspace_creator
91+
permission create_workspace = platform->super_admin + workspace_creator + parent->create_workspace
8792

8893
/************************
8994
* Template Permissions *
9095
************************/
91-
permission view_templates = platform->super_admin + template_viewer
92-
permission view_template_insights = platform->super_admin + template_insights_viewer
93-
permission edit_templates = platform->super_admin + template_editor
94-
permission delete_templates = platform->super_admin + template_deletor
95-
permission manage_template_permissions = platform->super_admin + template_permission_manager
96-
permission create_template = platform->super_admin + template_creator
96+
permission view_templates = platform->super_admin + template_viewer + parent->view_templates
97+
permission view_template_insights = platform->super_admin + template_insights_viewer + parent->view_template_insights
98+
permission edit_templates = platform->super_admin + template_editor + parent->edit_templates
99+
permission delete_templates = platform->super_admin + template_deletor + parent->delete_templates
100+
permission manage_template_permissions = platform->super_admin + template_permission_manager + parent->manage_template_permissions
101+
permission create_template = platform->super_admin + template_creator + parent->create_template
97102
}
98103

99104
// group is a collection of users and operates exactly like a user from
@@ -129,12 +134,12 @@ definition workspace {
129134
// Some perms require view as well
130135
edit + delete + select_template_version + ssh +
131136
// Give view permissons to any role that requires reading the workspace to conduct their actions.
132-
owner->view_workspaces + (viewer & owner->membership)
133-
permission edit = owner->edit_workspaces + (editor & owner->membership)
134-
permission delete = owner->delete_workspaces + (deletor & owner->membership)
137+
owner->view_workspaces + viewer
138+
permission edit = owner->edit_workspaces + editor
139+
permission delete = owner->delete_workspaces + deletor
135140
// TODO: Maybe a caveat to check if the selected version is the active template version, and if that is allowed.
136-
permission select_template_version = owner->select_workspace_version + (selector & owner->membership)
137-
permission ssh = owner->connect_workspaces + (connector & owner->membership)
141+
permission select_template_version = owner->select_workspace_version + selector
142+
permission ssh = owner->connect_workspaces + connector
138143
}
139144

140145
definition workspace_build {

0 commit comments

Comments
 (0)