Skip to content
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

ROX-23709: Trust Data Plane OAuth issuers in fleetshard authorization middleware #1801

Merged
merged 6 commits into from
May 22, 2024

Conversation

kovayur
Copy link
Contributor

@kovayur kovayur commented May 8, 2024

Description

This change adds Data Plane OAuth issuers validation in fleetshard authorization middleware.
The old authorization remains for backward compatibility

Checklist (Definition of Done)

  • Unit and integration tests added
  • Added test description under Test manual
  • Documentation added if necessary (i.e. changes to dev setup, test execution, ...)
  • CI and all relevant tests are passing
  • Add the ticket number to the PR title if available, i.e. ROX-12345: ...
  • Discussed security and business related topics privately. Will move any security and business related topics that arise to private communication channel.
  • Add secret to app-interface Vault or Secrets Manager if necessary
  • RDS changes were e2e tested manually
  • Check AWS limits are reasonable for changes provisioning new resources
  • (If applicable) Changes to the dp-terraform Helm values have been reflected in the addon on integration environment

Test manual

TODO: Add manual testing efforts

# To run tests locally run:
make db/teardown db/setup db/migrate
make ocm/setup
make verify lint binary test test/integration

Copy link
Contributor

openshift-ci bot commented May 8, 2024

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@openshift-ci openshift-ci bot added the approved label May 8, 2024
@kovayur kovayur force-pushed the yury/ROX-23709-fleetshard-auth branch from 7c3d605 to cdec282 Compare May 10, 2024 19:17
@kovayur kovayur force-pushed the yury/ROX-23709-fleetshard-authz branch from 0064307 to fd7a041 Compare May 10, 2024 19:17
@kovayur
Copy link
Contributor Author

kovayur commented May 10, 2024

@@ -40,6 +42,8 @@ func (c *FleetShardAuthZConfig) AddFlags(fs *pflag.FlagSet) {
"Fleetshard authZ middleware configuration file containing a list of allowed org IDs")
fs.BoolVar(&c.Enabled, "enable-fleetshard-authz", c.Enabled, "Enable fleetshard authZ "+
"via the list of allowed org IDs")
fs.StringVar(&c.AllowedSubject, "fleetshard-authz-subject", c.AllowedSubject,
"Fleetshard authZ middleware allowed subject")
Copy link

Choose a reason for hiding this comment

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

nit: maybe to make it more clear to folks reading through things:

Suggested change
"Fleetshard authZ middleware allowed subject")
"Fleetshard authZ middleware allowed subject claim of the token")

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Obsolete, moved to the config file

@@ -24,13 +24,15 @@ type FleetShardAuthZConfig struct {
Enabled bool
AllowedOrgIDs AllowedOrgIDs
AllowedOrgIDsFile string
AllowedSubject string
Copy link

Choose a reason for hiding this comment

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

Seeing as the effort will be relatively low, might make sense to allow setting multiple subjects as allowed ones, similar to the previous org IDs? While currently not eminent, it's not a lot of work to add support for that and will make our life easier in the future.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

return
}

glog.Infof("fleetshard subject is not allowed (expected=%s, actual=%s)", expected, s)
Copy link

Choose a reason for hiding this comment

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

In case the subject is empty or malformed:

Suggested change
glog.Infof("fleetshard subject is not allowed (expected=%s, actual=%s)", expected, s)
glog.Infof("fleetshard subject is not allowed (expected=%s, actual=%q)", expected, s)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Obsolete, added the generic claims check

@@ -47,3 +69,29 @@ func checkAllowedOrgIDs(allowedOrgIDs AllowedOrgIDs) mux.MiddlewareFunc {
})
}
}

func checkSubject(expected string) mux.MiddlewareFunc {
Copy link

Choose a reason for hiding this comment

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

nit:

Suggested change
func checkSubject(expected string) mux.MiddlewareFunc {
func checkSubject(allowedSubject string) mux.MiddlewareFunc {

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Obsolete, added the generic claims check

@dhaus67
Copy link

dhaus67 commented May 13, 2024

One thing in addition that would work well besides verifying the subject would also be verifying the audience. We can set the audience to a custom one in the projected volume mount (and also should, so that the token cannot be used to access the API server) and additionally verify that here.

@kovayur
Copy link
Contributor Author

kovayur commented May 14, 2024

One thing in addition that would work well besides verifying the subject would also be verifying the audience. We can set the audience to a custom one in the projected volume mount (and also should, so that the token cannot be used to access the API server) and additionally verify that here.

Done

@kovayur kovayur marked this pull request as ready for review May 14, 2024 09:08
@kovayur kovayur requested a review from dhaus67 May 14, 2024 09:08
@kovayur kovayur force-pushed the yury/ROX-23709-fleetshard-auth branch from cdec282 to 4834ca2 Compare May 15, 2024 11:39
@kovayur kovayur force-pushed the yury/ROX-23709-fleetshard-authz branch from d6f9367 to 2752423 Compare May 15, 2024 11:40
@kovayur kovayur force-pushed the yury/ROX-23709-fleetshard-auth branch from 4834ca2 to 9353319 Compare May 15, 2024 11:57
@kovayur kovayur force-pushed the yury/ROX-23709-fleetshard-authz branch from a7a9c4c to 44ede5a Compare May 15, 2024 11:59
@@ -16,6 +16,11 @@ func (c *ACSClaims) VerifyIssuer(cmp string, req bool) bool {
return jwt.MapClaims(*c).VerifyIssuer(cmp, req)
}

// VerifyAudience wraps jwt.VerifyAudience
Copy link

Choose a reason for hiding this comment

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

super nit: while we're at it, might make sense to give proper comments to all the functions here..

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

@@ -16,6 +16,11 @@ func (c *ACSClaims) VerifyIssuer(cmp string, req bool) bool {
return jwt.MapClaims(*c).VerifyIssuer(cmp, req)
}

// VerifyAudience wraps jwt.VerifyAudience
func (c *ACSClaims) VerifyAudience(cmp string, req bool) bool {
Copy link

Choose a reason for hiding this comment

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

Looking at this, does it even make sense to give clients the option to set required to false? I don't think we should IMO, but since this is more or less pre-existing, it's fine to leave as is and address in a follow-up, but I feel like we should introduce some sane defaults here to avoid people unsetting the required by mistake.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agree, removed the required option

audienceAccepted = true
break
Copy link

Choose a reason for hiding this comment

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

instead of breaking you could just call next.ServeHTTP here. Then you don't have the additional indentation at the bottom with !audienceAccepted.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done, thanks

@@ -79,6 +84,15 @@ func (c *ACSClaims) GetSubject() (string, error) {
return "", fmt.Errorf("can't find %q attribute in claims", tenantSubClaim)
}

// GetAudience returns the audience claim of the token. It identifies the token consumer.
func (c *ACSClaims) GetAudience() (interface{}, error) {
Copy link

Choose a reason for hiding this comment

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

Is it going to be a string or string array? Either way, I think it would be nice to have a concrete type here instead of the interface.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It can be either string or array

Copy link
Contributor Author

@kovayur kovayur May 21, 2024

Choose a reason for hiding this comment

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

I added logic to cast it to []string and a few unit tests


if !audienceAccepted {
audience, _ := claims.GetAudience()
glog.Infof("none of the audiences (%q) in the access token is not in the list of allowed values [%s]",
Copy link

Choose a reason for hiding this comment

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

Since audience is of type interface, what will %q actually print here? Better to return a concrete type in GetAudience().

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed to strings.join since claims.getAudience now returns []string. See the comment above.

@kovayur kovayur force-pushed the yury/ROX-23709-fleetshard-authz branch from bbf4f42 to a40721e Compare May 21, 2024 12:48
@kovayur kovayur force-pushed the yury/ROX-23709-fleetshard-auth branch from 26b84f6 to d0507ef Compare May 21, 2024 12:48
@kovayur kovayur requested a review from dhaus67 May 21, 2024 16:02
// IsOrgAdmin ...
// GetAudience returns the audience claim of the token. It identifies the token consumer.
func (c *ACSClaims) GetAudience() ([]string, error) {
aud := make([]string, 0)
Copy link

Choose a reason for hiding this comment

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

super nit: probably preferences, but might as well do var aud []string 🤷

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was done on purpose in order to get consistent results in the following test cases:

  • should return empty slice if the claim is empty array
  • should return empty slice if the claim is empty interface

If I change this line to var aud []string, GetAudience will return an empty and nil slice respectively.

for _, a := range v {
vs, ok := a.(string)
if !ok {
return nil, fmt.Errorf("can't parse part of the audience claim: %q", a)
Copy link

Choose a reason for hiding this comment

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

I'd rather fail open and create a log message that parts of the audience couldn't be parsed but not fail closed like we do here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

@openshift-ci openshift-ci bot added the lgtm label May 22, 2024
Base automatically changed from yury/ROX-23709-fleetshard-auth to main May 22, 2024 08:15
@kovayur kovayur force-pushed the yury/ROX-23709-fleetshard-authz branch from 14eb2cd to c5a1af0 Compare May 22, 2024 10:14
@openshift-ci openshift-ci bot removed the lgtm label May 22, 2024
Copy link
Contributor

openshift-ci bot commented May 22, 2024

New changes are detected. LGTM label has been removed.

Copy link
Contributor

openshift-ci bot commented May 22, 2024

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: dhaus67, kovayur

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@kovayur kovayur force-pushed the yury/ROX-23709-fleetshard-authz branch from 6417b2b to f48b741 Compare May 22, 2024 15:17
@kovayur kovayur merged commit 280129a into main May 22, 2024
7 checks passed
@kovayur kovayur deleted the yury/ROX-23709-fleetshard-authz branch May 22, 2024 16:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants