Skip to content

Commit 9d39371

Browse files
authored
feat: Option to remove WorkspaceExec from owner role (#7050)
* chore: Add AllResources option for listing all RBAC objects * Owners cannot do workspace exec site wide * Fix FE authchecks to valid RBAC resources
1 parent ad2353c commit 9d39371

28 files changed

+700
-169
lines changed

Makefile

+7-2
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,7 @@ gen: \
423423
provisionersdk/proto/provisioner.pb.go \
424424
provisionerd/proto/provisionerd.pb.go \
425425
site/src/api/typesGenerated.ts \
426+
coderd/rbac/object_gen.go \
426427
docs/admin/prometheus.md \
427428
docs/cli.md \
428429
docs/admin/audit-logs.md \
@@ -443,6 +444,7 @@ gen/mark-fresh:
443444
provisionersdk/proto/provisioner.pb.go \
444445
provisionerd/proto/provisionerd.pb.go \
445446
site/src/api/typesGenerated.ts \
447+
coderd/rbac/object_gen.go \
446448
docs/admin/prometheus.md \
447449
docs/cli.md \
448450
docs/admin/audit-logs.md \
@@ -495,6 +497,9 @@ site/src/api/typesGenerated.ts: scripts/apitypings/main.go $(shell find ./coders
495497
cd site
496498
yarn run format:types
497499

500+
coderd/rbac/object_gen.go: scripts/rbacgen/main.go coderd/rbac/object.go
501+
go run scripts/rbacgen/main.go ./coderd/rbac > coderd/rbac/object_gen.go
502+
498503
docs/admin/prometheus.md: scripts/metricsdocgen/main.go scripts/metricsdocgen/metrics
499504
go run scripts/metricsdocgen/main.go
500505
cd site
@@ -505,12 +510,12 @@ docs/cli.md: scripts/clidocgen/main.go $(GO_SRC_FILES) docs/manifest.json
505510
cd site
506511
yarn run format:write:only ../docs/cli.md ../docs/cli/*.md ../docs/manifest.json
507512

508-
docs/admin/audit-logs.md: scripts/auditdocgen/main.go enterprise/audit/table.go
513+
docs/admin/audit-logs.md: scripts/auditdocgen/main.go enterprise/audit/table.go coderd/rbac/object_gen.go
509514
go run scripts/auditdocgen/main.go
510515
cd site
511516
yarn run format:write:only ../docs/admin/audit-logs.md
512517

513-
coderd/apidoc/swagger.json: $(shell find ./scripts/apidocgen $(FIND_EXCLUSIONS) -type f) $(wildcard coderd/*.go) $(wildcard enterprise/coderd/*.go) $(wildcard codersdk/*.go) .swaggo docs/manifest.json
518+
coderd/apidoc/swagger.json: $(shell find ./scripts/apidocgen $(FIND_EXCLUSIONS) -type f) $(wildcard coderd/*.go) $(wildcard enterprise/coderd/*.go) $(wildcard codersdk/*.go) .swaggo docs/manifest.json coderd/rbac/object_gen.go
514519
./scripts/apidocgen/generate.sh
515520
yarn run --cwd=site format:write:only ../docs/api ../docs/manifest.json ../coderd/apidoc/swagger.json
516521

cli/testdata/coder_server_--help.golden

+6
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ Start a Coder server
1616
$CACHE_DIRECTORY is set, it will be used for compatibility with
1717
systemd.
1818

19+
--disable-owner-workspace-access bool, $CODER_DISABLE_OWNER_WORKSPACE_ACCESS
20+
Remove the permission for the 'owner' role to have workspace execution
21+
on all workspaces. This prevents the 'owner' from ssh, apps, and
22+
terminal access based on the 'owner' role. They still have their user
23+
permissions to access their own workspaces.
24+
1925
--disable-path-apps bool, $CODER_DISABLE_PATH_APPS
2026
Disable workspace apps that are not served from subdomains. Path-based
2127
apps can make requests to the Coder API and pose a security risk when

cli/testdata/server-config.yaml.golden

+6
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,12 @@ agentFallbackTroubleshootingURL: https://coder.com/docs/coder-oss/latest/templat
315315
# --wildcard-access-url is configured.
316316
# (default: <unset>, type: bool)
317317
disablePathApps: false
318+
# Remove the permission for the 'owner' role to have workspace execution on all
319+
# workspaces. This prevents the 'owner' from ssh, apps, and terminal access based
320+
# on the 'owner' role. They still have their user permissions to access their own
321+
# workspaces.
322+
# (default: <unset>, type: bool)
323+
disableOwnerWorkspaceAccess: false
318324
# These options change the behavior of how clients interact with the Coder.
319325
# Clients include the coder cli, vs code extension, and the web UI.
320326
client:

coderd/apidoc/docs.go

+59-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/apidoc/swagger.json

+59-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/authorize.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ func (api *API) checkAuthorization(rw http.ResponseWriter, r *http.Request) {
168168
obj := rbac.Object{
169169
Owner: v.Object.OwnerID,
170170
OrgID: v.Object.OrganizationID,
171-
Type: v.Object.ResourceType,
171+
Type: v.Object.ResourceType.String(),
172172
}
173173
if obj.Owner == "me" {
174174
obj.Owner = auth.Actor.ID
@@ -188,7 +188,7 @@ func (api *API) checkAuthorization(rw http.ResponseWriter, r *http.Request) {
188188
var dbObj rbac.Objecter
189189
var dbErr error
190190
// Only support referencing some resources by ID.
191-
switch v.Object.ResourceType {
191+
switch v.Object.ResourceType.String() {
192192
case rbac.ResourceWorkspaceExecution.Type:
193193
wrkSpace, err := api.Database.GetWorkspaceByID(ctx, id)
194194
if err == nil {

coderd/authorize_test.go

+7-7
Original file line numberDiff line numberDiff line change
@@ -46,34 +46,34 @@ func TestCheckPermissions(t *testing.T) {
4646
params := map[string]codersdk.AuthorizationCheck{
4747
readAllUsers: {
4848
Object: codersdk.AuthorizationObject{
49-
ResourceType: "users",
49+
ResourceType: codersdk.ResourceUser,
5050
},
5151
Action: "read",
5252
},
5353
readMyself: {
5454
Object: codersdk.AuthorizationObject{
55-
ResourceType: "users",
55+
ResourceType: codersdk.ResourceUser,
5656
OwnerID: "me",
5757
},
5858
Action: "read",
5959
},
6060
readOwnWorkspaces: {
6161
Object: codersdk.AuthorizationObject{
62-
ResourceType: "workspaces",
62+
ResourceType: codersdk.ResourceWorkspace,
6363
OwnerID: "me",
6464
},
6565
Action: "read",
6666
},
6767
readOrgWorkspaces: {
6868
Object: codersdk.AuthorizationObject{
69-
ResourceType: "workspaces",
69+
ResourceType: codersdk.ResourceWorkspace,
7070
OrganizationID: adminUser.OrganizationID.String(),
7171
},
7272
Action: "read",
7373
},
7474
updateSpecificTemplate: {
7575
Object: codersdk.AuthorizationObject{
76-
ResourceType: rbac.ResourceTemplate.Type,
76+
ResourceType: codersdk.ResourceTemplate,
7777
ResourceID: template.ID.String(),
7878
},
7979
Action: "update",
@@ -103,7 +103,7 @@ func TestCheckPermissions(t *testing.T) {
103103
Client: orgAdminClient,
104104
UserID: orgAdminUser.ID,
105105
Check: map[string]bool{
106-
readAllUsers: false,
106+
readAllUsers: true,
107107
readMyself: true,
108108
readOwnWorkspaces: true,
109109
readOrgWorkspaces: true,
@@ -115,7 +115,7 @@ func TestCheckPermissions(t *testing.T) {
115115
Client: memberClient,
116116
UserID: memberUser.ID,
117117
Check: map[string]bool{
118-
readAllUsers: false,
118+
readAllUsers: true,
119119
readMyself: true,
120120
readOwnWorkspaces: true,
121121
readOrgWorkspaces: false,

coderd/coderd.go

+6
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,12 @@ func New(options *Options) *API {
171171
options = &Options{}
172172
}
173173

174+
if options.DeploymentValues.DisableOwnerWorkspaceExec {
175+
rbac.ReloadBuiltinRoles(&rbac.RoleOptions{
176+
NoOwnerWorkspaceExec: true,
177+
})
178+
}
179+
174180
if options.Authorizer == nil {
175181
options.Authorizer = rbac.NewCachingAuthorizer(options.PrometheusRegistry)
176182
}

coderd/coderdtest/coderdtest.go

+2
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,8 @@ func NewOptions(t *testing.T, options *Options) (func(http.Handler), context.Can
203203
if options.DeploymentValues == nil {
204204
options.DeploymentValues = DeploymentValues(t)
205205
}
206+
// This value is not safe to run in parallel. Force it to be false.
207+
options.DeploymentValues.DisableOwnerWorkspaceExec = false
206208

207209
// If no ratelimits are set, disable all rate limiting for tests.
208210
if options.APIRateLimit == 0 {

coderd/rbac/object.go

+6-5
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ type Objecter interface {
1414
// Resources are just typed objects. Making resources this way allows directly
1515
// passing them into an Authorize function and use the chaining api.
1616
var (
17+
// ResourceWildcard represents all resource types
18+
// Try to avoid using this where possible.
19+
ResourceWildcard = Object{
20+
Type: WildcardSymbol,
21+
}
22+
1723
// ResourceWorkspace CRUD. Org + User owner
1824
// create/delete = make or delete workspaces
1925
// read = access workspace
@@ -136,11 +142,6 @@ var (
136142
Type: "organization_member",
137143
}
138144

139-
// ResourceWildcard represents all resource types
140-
ResourceWildcard = Object{
141-
Type: WildcardSymbol,
142-
}
143-
144145
// ResourceLicense is the license in the 'licenses' table.
145146
// ResourceLicense is site wide.
146147
// create/delete = add or remove license from site.

coderd/rbac/object_gen.go

+30
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)