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

PXP-10113 Client credentials grant #1033

Merged
merged 9 commits into from
Aug 15, 2022
Merged

Conversation

paulineribeyre
Copy link
Contributor

@paulineribeyre paulineribeyre commented Aug 3, 2022

Jira Ticket: PXP-10113

⚠️ "Client credentials" tokens are not supported by all endpoints, only by the ones needed for the driving use cases

New Features

  • Support the OAuth2 "client credentials" grant

Improvements

  • fence-create client-create now outputs the whole stacktrace in case of error

Deployment changes

  • Requires a Fence DB migration (Client.redirect_uri is now optional)

@github-actions
Copy link

github-actions bot commented Aug 3, 2022

The style in this PR agrees with black. ✔️

This formatting comment was generated automatically by a script in uc-cdis/wool.

@coveralls
Copy link

Pull Request Test Coverage Report for Build 12674

  • 87 of 89 (97.75%) changed or added relevant lines in 11 files are covered.
  • 2 unchanged lines in 2 files lost coverage.
  • Overall coverage increased (+0.1%) to 73.913%

Changes Missing Coverage Covered Lines Changed/Added Lines %
fence/auth.py 5 6 83.33%
fence/models.py 5 6 83.33%
Files with Coverage Reduction New Missed Lines %
fence/models.py 1 83.44%
fence/utils.py 1 59.9%
Totals Coverage Status
Change from base Build 12646: 0.1%
Covered Lines: 6868
Relevant Lines: 9292

💛 - Coveralls

README.md Outdated
@@ -515,6 +515,14 @@ To specify allowed scopes, use the `allowed-scopes` argument:
fence-create client-create ... --allowed-scopes openid user data
```

#### Register an Oauth Client for a Client Credentials flow

As a Gen3 commons administrator, if you want to create an oauth client for a client credentials flow:
Copy link
Contributor

Choose a reason for hiding this comment

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

we may want more docs than this, or an explanation of when you might want this (and how authorization is applied the same as users and this only works against certain endpoints)

client_id = ""
try:
if not token:
token = validate_request(scope=[], audience=config.get("BASE_URL"))
Copy link
Contributor

Choose a reason for hiding this comment

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

we may want to consider a scope for client-level information similar to user, maybe client. I'm not sure when we wouldn't provide this though.. and if the spec doesn't dictate then maybe it's not necessary

Copy link
Contributor Author

Choose a reason for hiding this comment

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

good point - since we're not allowing client tokens for these endpoints anyway, i'm leaving this as-is so we don't complicate things. let me know if you think we should add the scope.

@@ -643,7 +643,9 @@ def check_legacy_authorization(self, action):
)
return self.index_document.get("uploader") == username

given_acls = set(filter_auth_ids(action, flask.g.user.project_access))
given_acls = set()
Copy link
Contributor

Choose a reason for hiding this comment

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

Okay so my read of this is that we're not actually allowing client credentials tokens to generate signed URLs, right? All these changes are just to ensure that a sane 401 is returned (instead of 500-ing off of all the user specific access stuff) and pave the road for potentially adding that support 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.

it does work (s3 only) if the client has read-storage access to the resource. we can block it if you would rather we do that though

Copy link
Contributor

Choose a reason for hiding this comment

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

ehhh, I feel like we want to restrict client direct access to data until we absolutely need to support it. Least privilege and all that.

@@ -260,6 +279,7 @@ def check_client_secret(self, client_secret):

def check_requested_scopes(self, scopes):
if "openid" not in scopes:
logger.error(f"Invalid scopes: 'openid' not in requested scopes ({scopes})")
Copy link
Contributor

Choose a reason for hiding this comment

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

This is one of those error lines that I imagine you added after hours of frustration trying to figure out why something wasn't working, lol. Or at least that's what it'd be for me

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants