awslabs / ssosync

Populate AWS SSO directly with your G Suite users and groups using either a CLI or AWS Lambda
Apache License 2.0
508 stars 173 forks source link

Allow GWS service accounts without impersonation #192

Open behobu opened 3 months ago

behobu commented 3 months ago

When attempting to implement this project in my environment, I hit a significant snag when attempting to authenticate. I established a service account in GCP, granted it permissions (scopes) to query my GWS environment, and have been using that successfully for many GWS-related automations. However, the client.go auth mechanism assumes that the service account will be impersonating an actual user admin account in order to perform the actions taken by the code. This represents a coding no-no - tying any automated process to a user's identity, since if that person ever leaves the company there will be a gap (even with the best documentation) that could result in disruption of services (sync) or even potentially malicious activity. In fact, the whole idea of using a service account is so that you DON'T have to link some piece of automation to a real user.

The auth mechanism specified in client.go can be "tricked" into using just the service account, but when that happens, the google client library option in "google.golang.org/api/admin/directory/v1" of 'my_customer' does not work, for reasons I couldn't determine, but are likely tied to that option being pulled from the impersonated account. So I added a my_customer variable to client.go, which ideally would be populated from an AWS Parameter Store or Secrets Manager secret rather than being hard-coded like I did it. I then replaced all the 'my_customer' static strings with my_customer variable references. In addition, the JWTConfigFromJSON used in client.go needs someone to impersonate to work correctly, but using the JWTAccessToeknSourceWithScope allowed me to get the token source to pass to the admin.NewService call, and still specify the scopes needed without impersonating any other users.

Describe the solution you'd like Ideally there would be an option to use a "true" service account approach or an impersonation approach for auth, and the code would handle that gracefully by using the appropriate auth process (which I outlined above). In addition, it would also make the my_customer variable default set to 'my_customer', but optionally able to be overridden by the installer when the stack is built in order to allow for environments where impersonation isn't an option.

Describe alternatives you've considered I've considered re-coding the entire project in Python, but only because my proficiency with that language is better than with Go. However, I don't currently have the time for that kind of effort, so I modified the code locally and then deployed using the SAM CLI (which is terrible btw).

Additional context image image image

ChrisPates commented 3 months ago

I concur the use of a super admin account is undesirable, there is an alternate approach which has been submitted (#150) but has not yet been merged. I'm looking to this work in the next major release, it will need rigorous testing, to ensure backwards compatibility or a clearly announced breaking change.

philomory commented 4 weeks ago

I'm not sure #150 actually addresses this request; it looks like #150 removes the need for the sensitive data in credentials.json, but it does not remove the need for a --google-admin email address to be impersonated, which is what this issue is requesting. Among other problems, whichever email address is supplied for --google-admin, any actions taken by ssosync will appear in audit logs to have been taken by the admin user in question.

EDIT: I have a patch that incorporates @behobu's changes while adding CLI and environment variable support for passing the customer id, as well as tweaks to the CF templates (though I'm not really very confident in my CF so I might have messed that part up). I'll submit a PR tomorrow.