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

Google Workspace OIDC connector can become unusable when fetching transitive groups if a user belongs to external groups #10635

Open
espadolini opened this issue Feb 25, 2022 · 13 comments · Fixed by #11422
Labels
bug c-gj Internal Customer Reference c-ny Internal Customer Reference good-starter-issue Good starter issue to start contributing to Teleport sso Used for single sign on related tasks. support-load This issue generates support load

Comments

@espadolini
Copy link
Contributor

espadolini commented Feb 25, 2022

Description

When using the OIDC connector for Google Workspace configured to fetch transitive groups, users that belong to external Google Groups are not able to login, as the groups.memberships.searchTransitiveMemberships API will return a somewhat generic Unauthorized error.

This is doubly problematic because - unless external groups are disabled at the google workspace level - anyone is seemingly able to add a user to an external group without requiring confirmation.

Potential solutions

We could just accept this limitation (as it is, in fact, a Google Workspace limitation) and document the fact that transitive group membership listing only works if the users do not belong to external groups - and to be completely fair, we already indirectly required this by saying that the google_admin_email user must have view permissions over all the groups that users belong to, which is just never true if any user belongs to an external group. Something we ought to mention in the docs is that there is a way to block users from joining external groups at the workspace level.

The searchTransitiveMemberships call can select just the "security" groups; this prevents the issue as those groups don't allow members outside of the Google Workspace, and thus should be always readable with group admin read privileges. This is a breaking change, however - potentially a welcome one, as it would allow admins to select specific groups to be analyzed for role mapping, but a breaking one nonetheless. Adding a configuration option increases "configuration fatigue" however, which is also not great.

We could inject a new security_groups claim and either duplicate the regular groups that are also security groups in there (which would bloat the user traits even more), or only list the security groups in there and not in the groups claim (which would be a breaking change); this would allow us to try to fetch just the security groups when fetching the full list fails for whatever reason - this seems more awkward than adding a configuration option, however.

Falling back to the old direct membership API is also an option, but will result in potentially confusing behavior if for some reason the transitive group API starts failing (and potentially insecure, if some groups are mapped to roles with deny rules). An error when logging in is far clearer than suddenly having access to half of the nodes that you expect for no apparent reason.

Another option could be to manually enumerate the groups; this still needs some way to select the behavior, and it's unclear how many API calls to the "Admin SDK Directory API" we can do in burst - this is the worst possible option because we need to recursively call groups.list on the user and then each and every returned group, recursively.

@espadolini espadolini added bug c-ny Internal Customer Reference labels Feb 25, 2022
@espadolini
Copy link
Contributor Author

It is worth mentioning that even the Groups Inspection page in the Google Admin Console fails for users that are in external groups.

@pschisa pschisa added the c-gj Internal Customer Reference label Mar 4, 2022
@russjones russjones added the sso Used for single sign on related tasks. label Mar 19, 2022
@espadolini
Copy link
Contributor Author

As per @zmb3, we're going with the option of just documenting the inherent limitation of the APIs provided by Google.

@dmsergeevN26
Copy link

dmsergeevN26 commented Mar 24, 2022

@espadolini Another option is to use the members.hasMember method in the old Directory API which would be called for each group configured in a connector? Not perfect as it will require multiple calls, but at least there's no functional limitation and it doesn't require recursive calls.

Right now I am trying to troubleshoot(with google suite admins and google support) as to why this new call(searchTransitiveMemberships) returns 403 for some users and not others and it's proving to be extremely difficult as the number of groups is quite large in any 1k+ employees organization. It's not apparent which group is at fault

@espadolini
Copy link
Contributor Author

@dmsergeevN26 do those users belong to any external google group, by any chance?

@dmsergeevN26
Copy link

@espadolini Not that I can see

@dmsergeevN26
Copy link

dmsergeevN26 commented Mar 24, 2022

@espadolini for example, I managed to zero in on one group that breaks this call. The group has 15 direct members, real internal users. No indirect users. When I add anybody to this group both Teleport and Google Inspect group break and return 403. I am not able to check what groups this group belongs to because the Inspect Group view returns 403

@espadolini
Copy link
Contributor Author

espadolini commented Mar 24, 2022

@espadolini Another option is to use the members.hasMember method in the old Directory API which would be called for each group configured in a connector? Not perfect as it will require multiple calls, but at least there's no functional limitation and it doesn't require recursive calls.

I believe that it would be a breaking change, because all groups are added to the claims trait in the user, which can be inspected by RBAC rules, and it'd be impossible to figure out which groups would have to be fetched in that way.

@dmsergeevN26
Copy link

Ah, true. That's too bad

@espadolini
Copy link
Contributor Author

As per @zmb3 we're just going to document this limitation until some better solution comes along.

@espadolini
Copy link
Contributor Author

https://cloud.google.com/identity/docs/reference/rest/v1/groups.memberships/searchTransitiveGroups was updated two weeks ago (and about a month ago I noticed that the "groups inspection" console had a checkbox that probably does the same thing):

Query may optionally contain equality operators on the parent of the group restricting the search within a particular customer, e.g. parent == 'customers/{customerId}'. The customerId must begin with "C" (for example, 'C046psxkn'). This filtering is only supported for Admins with groups read permissons on the input customer.

Example query: member_key_id == 'member_key_id_value' && <label_value> in labels && parent == 'customers/C046psxkn'

@espadolini espadolini reopened this Mar 1, 2023
@espadolini espadolini removed their assignment Mar 1, 2023
@espadolini
Copy link
Contributor Author

espadolini commented Mar 1, 2023

To fix this, we need to figure out if there's a way to use that additional filtering mechanism to select the "local" customer automatically, find some API to fetch it as part of the login process, or add an option to the OIDC connector resource to let the user specify it (google_customer_id?), then add that && parent == 'customers/<customer ID>' suffix to the query string in e/lib/auth/oidc_google.go, then check that logging in actually works even if the user is directly or indirectly a member of a google group outside of the workspace (and that the correct list of internal google groups is returned).

@espadolini espadolini added the good-starter-issue Good starter issue to start contributing to Teleport label Mar 1, 2023
@GavinFrazar
Copy link
Contributor

This issue has come up a couple times this week for customers.

I think we should at least make a python script that can be used to identify a group that directly or transitively makes a user a member of an external group, because it's not easy to find it by hand.

@espadolini espadolini added the support-load This issue generates support load label Nov 29, 2023
@kelvich
Copy link

kelvich commented Apr 10, 2024

Stumbled on a pretty severe case of this issue.

Gmail users who enrolled in the Gemini preview are automatically added to several Google Groups, such as [email protected] and [email protected] -- figured this out through support. Users themselves cannot see these groups in their list of external groups, and therefore, they cannot quit them. Sending an email to <group_name>[email protected] works for some of these groups but not for all. Trying to resolve/escalate that with support but not luck so far.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug c-gj Internal Customer Reference c-ny Internal Customer Reference good-starter-issue Good starter issue to start contributing to Teleport sso Used for single sign on related tasks. support-load This issue generates support load
Projects
None yet
6 participants