Skip to content

feat: Dbauthz is now default, remove out of experimental #6650

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 32 commits into from
Mar 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
ac597a5
feat: dbauthz always on, out of experimental
Emyrk Mar 16, 2023
7118bf0
Add ability to do rbac checks in unit tests
Emyrk Mar 17, 2023
c555c57
Remove AuthorizeAllEndpoints
Emyrk Mar 17, 2023
c6210c4
Remove some duplicate rbac checks
Emyrk Mar 17, 2023
d48a5c3
Remove rest of duplicate rbac checks
Emyrk Mar 17, 2023
7672f6e
Adding unit tests for rbac checks
Emyrk Mar 17, 2023
263801b
Add method to unit test rbac
Emyrk Mar 17, 2023
893198a
Add comment
Emyrk Mar 17, 2023
6b2c3f9
Add comments
Emyrk Mar 17, 2023
84ba18d
Add comment
Emyrk Mar 17, 2023
38bec6d
Merge remote-tracking branch 'origin/main' into stevenmasley/dbauthz_on
Emyrk Mar 17, 2023
a5ff7fc
Make gen
Emyrk Mar 17, 2023
bb788a4
Make golden files
Emyrk Mar 17, 2023
c0f6ff0
linting
Emyrk Mar 20, 2023
386a967
Merge remote-tracking branch 'origin/main' into stevenmasley/dbauthz_on
Emyrk Mar 20, 2023
f7842ee
linting
Emyrk Mar 20, 2023
b6130e3
linting
Emyrk Mar 20, 2023
8b744ac
Merge lost a config section
Emyrk Mar 20, 2023
55f01c5
Linting
Emyrk Mar 20, 2023
4965c10
Make gen
Emyrk Mar 20, 2023
d038934
Make gen
Emyrk Mar 20, 2023
55b1308
remove experiment enum
Emyrk Mar 20, 2023
f7923df
Make gen
Emyrk Mar 20, 2023
549a34d
Linting
Emyrk Mar 20, 2023
2ae9eac
Correct unit test
Emyrk Mar 20, 2023
faf0714
Merge remote-tracking branch 'origin/main' into stevenmasley/dbauthz_on
Emyrk Mar 20, 2023
899cc69
Override a copy of the error
Emyrk Mar 20, 2023
4fcc69e
have nicer status codes
Emyrk Mar 20, 2023
4ab765f
Test be parallel
Emyrk Mar 20, 2023
9b69f39
This test takes way too long
Emyrk Mar 20, 2023
974d915
Paginated users was taking too long
Emyrk Mar 20, 2023
0934326
Subtest context is shared :(
Emyrk Mar 20, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cli/testdata/coder_list_--output_json.golden
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"updated_at": "[timestamp]",
"owner_id": "[first user ID]",
"owner_name": "testuser",
"organization_id": "[first org ID]",
"template_id": "[template ID]",
"template_name": "test-template",
"template_display_name": "",
Expand Down
6 changes: 4 additions & 2 deletions coderd/apidoc/docs.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 6 additions & 2 deletions coderd/apidoc/swagger.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 0 additions & 26 deletions coderd/apikey.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,6 @@ func (api *API) postToken(rw http.ResponseWriter, r *http.Request) {
aReq.Old = database.APIKey{}
defer commitAudit()

if !api.Authorize(r, rbac.ActionCreate, rbac.ResourceAPIKey.WithOwner(user.ID.String())) {
httpapi.ResourceNotFound(rw)
return
}

var createToken codersdk.CreateTokenRequest
if !httpapi.Read(ctx, rw, r, &createToken) {
return
Expand Down Expand Up @@ -134,11 +129,6 @@ func (api *API) postAPIKey(rw http.ResponseWriter, r *http.Request) {
ctx := r.Context()
user := httpmw.UserParam(r)

if !api.Authorize(r, rbac.ActionCreate, rbac.ResourceAPIKey.WithOwner(user.ID.String())) {
httpapi.ResourceNotFound(rw)
return
}

lifeTime := time.Hour * 24 * 7
cookie, _, err := api.createAPIKey(ctx, createAPIKeyParams{
UserID: user.ID,
Expand Down Expand Up @@ -190,11 +180,6 @@ func (api *API) apiKeyByID(rw http.ResponseWriter, r *http.Request) {
return
}

if !api.Authorize(r, rbac.ActionRead, key) {
httpapi.ResourceNotFound(rw)
return
}

httpapi.Write(ctx, rw, http.StatusOK, convertAPIKey(key))
}

Expand Down Expand Up @@ -230,11 +215,6 @@ func (api *API) apiKeyByName(rw http.ResponseWriter, r *http.Request) {
return
}

if !api.Authorize(r, rbac.ActionRead, token) {
httpapi.ResourceNotFound(rw)
return
}

httpapi.Write(ctx, rw, http.StatusOK, convertAPIKey(token))
}

Expand Down Expand Up @@ -327,7 +307,6 @@ func (api *API) tokens(rw http.ResponseWriter, r *http.Request) {
func (api *API) deleteAPIKey(rw http.ResponseWriter, r *http.Request) {
var (
ctx = r.Context()
user = httpmw.UserParam(r)
keyID = chi.URLParam(r, "keyid")
auditor = api.Auditor.Load()
aReq, commitAudit = audit.InitRequest[database.APIKey](rw, &audit.RequestParams{
Expand All @@ -344,11 +323,6 @@ func (api *API) deleteAPIKey(rw http.ResponseWriter, r *http.Request) {
aReq.Old = key
defer commitAudit()

if !api.Authorize(r, rbac.ActionDelete, rbac.ResourceAPIKey.WithIDString(keyID).WithOwner(user.ID.String())) {
httpapi.ResourceNotFound(rw)
return
}

err = api.Database.DeleteAPIKeyByID(ctx, keyID)
if errors.Is(err, sql.ErrNoRows) {
httpapi.ResourceNotFound(rw)
Expand Down
8 changes: 0 additions & 8 deletions coderd/audit.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,6 @@ import (
// @Router /audit [get]
func (api *API) auditLogs(rw http.ResponseWriter, r *http.Request) {
ctx := r.Context()
if !api.Authorize(r, rbac.ActionRead, rbac.ResourceAuditLog) {
httpapi.Forbidden(rw)
return
}

page, ok := parsePagination(rw, r)
if !ok {
Expand Down Expand Up @@ -90,10 +86,6 @@ func (api *API) auditLogs(rw http.ResponseWriter, r *http.Request) {
// @Router /audit/testgenerate [post]
func (api *API) generateFakeAuditLog(rw http.ResponseWriter, r *http.Request) {
ctx := r.Context()
if !api.Authorize(r, rbac.ActionCreate, rbac.ResourceAuditLog) {
httpapi.Forbidden(rw)
return
}

key := httpmw.APIKey(r)
user, err := api.Database.GetUserByID(ctx, key.UserID)
Expand Down
22 changes: 0 additions & 22 deletions coderd/authorize.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,28 +51,6 @@ type HTTPAuthorizer struct {
// return
// }
func (api *API) Authorize(r *http.Request, action rbac.Action, object rbac.Objecter) bool {
// The experiment does not replace ALL rbac checks, but does replace most.
// This statement aborts early on the checks that will be removed in the
// future when this experiment is default.
if api.Experiments.Enabled(codersdk.ExperimentAuthzQuerier) {
// Some resource types do not interact with the persistent layer and
// we need to keep these checks happening in the API layer.
switch object.RBACObject().Type {
case rbac.ResourceWorkspaceExecution.Type:
// This is not a db resource, always in API layer
case rbac.ResourceDeploymentValues.Type:
// For metric cache items like DAU, we do not hit the DB.
// Some db actions are in asserted in the authz layer.
case rbac.ResourceReplicas.Type:
// Replica rbac is checked for adding and removing replicas.
case rbac.ResourceProvisionerDaemon.Type:
// Provisioner rbac is checked for adding and removing provisioners.
case rbac.ResourceDebugInfo.Type:
// This is not a db resource, always in API layer.
default:
return true
}
}
return api.HTTPAuth.Authorize(r, action, object)
}

Expand Down
20 changes: 9 additions & 11 deletions coderd/coderd.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,15 @@ func New(options *Options) *API {
if options == nil {
options = &Options{}
}

if options.Authorizer == nil {
options.Authorizer = rbac.NewCachingAuthorizer(options.PrometheusRegistry)
}
options.Database = dbauthz.New(
options.Database,
options.Authorizer,
options.Logger.Named("authz_querier"),
)
experiments := initExperiments(
options.Logger, options.DeploymentValues.Experiments.Value(),
)
Expand Down Expand Up @@ -201,9 +210,6 @@ func New(options *Options) *API {
if options.PrometheusRegistry == nil {
options.PrometheusRegistry = prometheus.NewRegistry()
}
if options.Authorizer == nil {
options.Authorizer = rbac.NewCachingAuthorizer(options.PrometheusRegistry)
}
if options.TailnetCoordinator == nil {
options.TailnetCoordinator = tailnet.NewCoordinator()
}
Expand All @@ -216,14 +222,6 @@ func New(options *Options) *API {
if options.SSHConfig.HostnamePrefix == "" {
options.SSHConfig.HostnamePrefix = "coder."
}
// TODO: remove this once we promote authz_querier out of experiments.
if experiments.Enabled(codersdk.ExperimentAuthzQuerier) {
options.Database = dbauthz.New(
options.Database,
options.Authorizer,
options.Logger.Named("authz_querier"),
)
}
if options.SetUserGroups == nil {
options.SetUserGroups = func(context.Context, database.Store, uuid.UUID, []string) error { return nil }
}
Expand Down
Loading