Skip to content

feat: implement provisioner auth middleware and proper org params #12330

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 11 commits into from
Mar 4, 2024

Conversation

Emyrk
Copy link
Member

@Emyrk Emyrk commented Feb 27, 2024

What this does

This is a prerequisite to org scoping provisioner daemons. To do so, the provisioner authentication has to properly support the orgs in the api route.

Implemented similar to our coder workspace agent tokens and workspace proxies. As a future follow up we might want to expand the security around how provisioners authenticate, and that can all be handled in this middleware. Eg assigning a unique token to each provisioner.

Changes

  • Added read to all organizations for subjectProvisionerd
    • Cannot scope this to a single org because all provisioners share the same auth token atm.
  • RequireAPIKeyOrProvisionerDaemonAuth middleware to allow a user auth or provisioner auth in handlers.
  • ExtractOrganizationParam allows setting default as the organization ID. This is easier for single org deployments to not bother messing with org ids.
  • ExtractOrganizationParam handles the uuid.Nil as the default org. This is to prevent a breaking change, as prior to this the nil uuid was user
  • Provisioner daemons by default will use default as org id if non specified.

Follow up

The follow up PR will add organizationID as a column on the provisioner daemons table.

Step to enable org scoped provisioner daemons
@Emyrk Emyrk changed the title feat: provisioner auth in mw to allow ExtractOrg feat: implement provisioner auth middleware and proper org params Feb 27, 2024
Comment on lines 58 to 68
// If the name is exactly "default", then we fetch the default
// organization. This is a special case to make it easier
// for single org deployments.
//
// arg == uuid.Nil.String() should be a temporary workaround for
// legacy provisioners that don't provide an organization ID.
// This prevents a breaking change.
// TODO: This change was added March 2024, this should be removed
// some number of months after that date.
if arg == codersdk.DefaultOrganization || arg == uuid.Nil.String() {
organization, dbErr = db.GetDefaultOrganization(ctx)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the only quirky thing. A nil uuid has to be interpreted as the default org for backwards compatibility.

I've added a default string so we can use that placeholder in single org deployments and not have to use a uuid which is harder to remember.

@Emyrk Emyrk marked this pull request as ready for review February 28, 2024 16:32
@Emyrk Emyrk requested a review from spikecurtis February 28, 2024 17:28
}

// Use the same subject for the userAuthKey
ctx = context.WithValue(ctx, userAuthKey{}, Authorization{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. why do we need this for provisioner daemons?

  2. more generally, why do we store the rbac.Subject under 2 different context keys (authContextKey{} and userAuthKey{})?

  3. what is the difference between an "actor" and a "subject"? Are they interchangeable ideas and we're just inconsistent in how we refer to them in the code?

Copy link
Member Author

@Emyrk Emyrk Feb 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These should be merged into 1 context value.

It exists because dbauthz needed a context, and it did not feel right to use the httpmw functions for it. So it created it's own.

We should standardize on the dbauthz context, or place one in like /rbac.


  1. I was just being consistent with the other auths. If I omit this, then the HTTPAuthorizer will not work:
    func (h *HTTPAuthorizer) Authorize(r *http.Request, action rbac.Action, object rbac.Objecter) bool {
    . This is used in the provisioner handlers.
  2. Legacy reasons when dbauthz used to be an experiment, and not always enabled.
  3. Interchangeable. One affects http handlers, one affects dbauthz.

I just made an issue tracking it here: #12363

serverURL, err := c.URL.Parse(fmt.Sprintf("/api/v2/organizations/%s/provisionerdaemons/serve", req.Organization))
orgParam := req.Organization.String()
if req.Organization == uuid.Nil {
orgParam = DefaultOrganization
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't get why we don't like uuid.Nil meaning the default on the API, but are fine with it on the SDK.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I went back and forth on this. I think we are the only users of our sdk atm, but if I was to require the OrgID argument in the sdk to be set now, that would be a breaking change for the sdk.

I've been trying to maintain that single org deployments do not have to make any changes, and they continue to work as they do today.

On the sdk side, this is an omission of a field being set.

On the API, the nil uuid could be an explicit value being set, rather than an omission.

})
}, &provisionerd.Options{
Logger: logger.Named("provisionerd"),
Logger: logger.Named(provPSK),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the logger changed to the PSK? I'm assuming over-zealous replacement of strings? This is only a test, but yikes if we ever did that in production!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Over-zealous...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch

@Emyrk Emyrk requested a review from spikecurtis February 29, 2024 16:52
@Emyrk Emyrk merged commit 5c6974e into main Mar 4, 2024
@Emyrk Emyrk deleted the stevenmasley/provisioner_auth branch March 4, 2024 21:15
@github-actions github-actions bot locked and limited conversation to collaborators Mar 4, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants