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

Automated copy feature/OIDC oauth groups rev2 #1213

Closed
wants to merge 45 commits into from

Conversation

Avantol13
Copy link
Contributor

@Avantol13 Avantol13 commented Jan 13, 2025

Link to JIRA ticket if there is one:

New Features

  • Support for OIDC Group Claims from an IdP to sync to the authorization policy engine
  • Implementation of token refresh (extension of GA4GH Access Token polling) to update group authz

Breaking Changes

Bug Fixes

Improvements

Dependency updates

Deployment changes

uwwint and others added 30 commits September 26, 2024 20:57

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
remove trailing space

Co-authored-by: Alexander VanTol <Avantol13@users.noreply.github.com>
...to make user creation more uniform, reflecting what is also done elsewhere
in fence/sync/sync_users.py _upsert_userinfo() for example
pieterlukasse and others added 15 commits November 8, 2024 11:23
* fix use real bucket name

* fix

* update comment

* use regex

* update version
Update documentation link in setup.md

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
…ustralianBioCommons/fence into automatedCopy-feature/oidc-oauth-groups-rev2
@coveralls
Copy link

Pull Request Test Coverage Report for Build 12750495859

Details

  • 0 of 0 changed or added relevant lines in 0 files are covered.
  • 113 unchanged lines in 7 files lost coverage.
  • Overall coverage decreased (-0.05%) to 75.189%

Files with Coverage Reduction New Missed Lines %
resources/openid/microsoft_oauth2.py 1 95.0%
error_handler.py 2 96.08%
init.py 3 90.84%
scripting/fence_create.py 5 60.35%
config.py 5 71.88%
blueprints/login/base.py 29 78.72%
resources/openid/idp_oauth2.py 68 64.06%
Totals Coverage Status
Change from base Build 12356407492: -0.05%
Covered Lines: 7967
Relevant Lines: 10596

💛 - Coveralls

Copy link

Please find the ci env pod logs here

)

self.post_login(
user=flask.g.user,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think this will error if flask.g.user doesn't exist (like you're checking for in getattr(flask.g, "user", None). Either you need to raise an exception afterthe logger.error, or you need to make sure this code block doesn't get hit when .user doesn't exist

# If all methods fail, return None
return None

def introspect_token(self, 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.

We don't support token introspection elsewhere already and I'd rather not add this in, since it will likely require a security review (since this is trusting another systems endpoint to return information to us outside of the already approved content of the token itself). Unless you absolutely need this method, I recommend removing and relying on the exp in the token content itself

@@ -142,6 +314,13 @@ def post_login(self, user=None, token_result=None, **kwargs):
client_id=flask.session.get("client_id"),
)

# this attribute is only applicable to some OAuth clients
# (e.g., not all clients need is_read_authz_groups_from_tokens_enabled)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not sure I understand this clarifying comment. Isn't read_authz_groups_from_tokens just a boolean on every client?

# to do this, only include error messages for known http status codes
# that are less that 500
# Decide whether to re-raise errors or handle gracefully based on the debug flag
debug_mode = config.get("DEBUG", False)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

You don't need to safely check for top level config. It is guaranteed to be there and be the default value if it wasn't overwritten. So you can just do: if config["DEBUG"]:

# Decide whether to re-raise errors or handle gracefully based on the debug flag
debug_mode = config.get("DEBUG", False)

if debug_mode:
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think we want this, b/c in a deployed runtime setting where we are temporarily turning this configuration on to get more detailed logs into our logging system, this is altering the actual error handling behavior so we wouldn't see the same flow. I propose removing this and leaving it the way it was before so that regardless of the DEBUG flag, the flow of the exceptions is the same

@@ -72,18 +96,69 @@ def get_jwt_keys(self, jwks_uri):
return None
return resp.json()["keys"]

def decode_and_validate_token(self, token_id, keys, audience, verify_aud=True):
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I feel the name token_id is misleading since it's the entire token. I would suggest simply 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.

Also, we already have a validation function that takes into account denylisted tokens. Was there some issue with using the existing code? fence.jwt.validate.validate_jwt

)
refresh_token = token_response["refresh_token"]
# Fetching the expires at from token_response.
# Defaulting to 1 hour if not available.
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 should part of the configuration, not hard-coded 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.

We also need an info log for audit trail, that a token was persisted for x user for y amount of time

Copy link
Contributor Author

Choose a reason for hiding this comment

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

unless the store_refresh_token function already handles that

Choose a reason for hiding this comment

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

handled at store_refresh_token functio

a. Retrieves the list of groups from Arborist.
b. Retrieves the user's groups from the IdP.
c. Adds the user to groups in Arborist that match the groups from the IdP.
d. Removes the user from groups in Arborist that they are no longer part of in the IdP.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

step d. is the problematic one. If we simply rely on Arborist to expire policies, then we could avoid the comparison here (and the issue where there are multiple sources of truth for group membership)

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 looks like the actual logic for this got removed 👍 , so I think we just need to update this comment


idp_group_names = set(authz_groups_from_idp)

# Expiration for group membership. Default 7 days
Copy link
Contributor Author

Choose a reason for hiding this comment

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

we must make sure that this duration does not exceed the refresh token expiration. B/c if it does, we're breaking policy and extending beyond the source of truth's maximum allowed validity of the information and approval of the user for us to act on their behalf

Choose a reason for hiding this comment

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

fixed

@PlanXCyborg PlanXCyborg closed this Feb 3, 2025
@PlanXCyborg PlanXCyborg deleted the automatedCopy-feature/oidc-oauth-groups-rev2 branch February 3, 2025 18:40
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.

9 participants