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

Feature request: Create equivalent of with_subject() from python google.oauth2.service_account #413

Closed
fh-kpikhart opened this issue Feb 17, 2023 · 8 comments · Fixed by #431
Milestone

Comments

@fh-kpikhart
Copy link

The googledrive::drive_auth email param requires that the email used to auth is also the email address of the service account used to perform actions within the Google Drive. In python, we can use with_subject() to specify a different email address from the one used to auth. Is there an equivalent function in googledrive?

@jennybc
Copy link
Member

jennybc commented Feb 17, 2023

Do you have a service account that has domain-wide delegation of authority? I think gargle (and therefore googledrive and other packages) basically can already do this or at least it's very close. But I am not allowed to have such a service account in my organization's workspace, so the friction for figuring this out in the abstract has always been too high. But if I am communicating with a motivated user that has the necessary setup, that might be the incentive I need to sort this out finally.

Roughly speaking, the experiment to start with is this:

token <- gargle::credentials_service_account(scopes = "{YOUR DESIRED SCOPES}", path = "path/to/your/service/account.json", subject = "{USER YOU WANT TO IMPERSONATE}")

@fh-kpikhart
Copy link
Author

Yes, I have a service account that has domain-wide delegation. Thank you for pointing me to this function! I'm trying it out; will report back after I pair with someone on an error I'm bumping into down in httr:::init_oauth_service_account.

@fh-kpikhart
Copy link
Author

Here's a brief update:

When using gargle::credentials_service_account with the subject param, we're hitting this error:

Error in init_oauth_service_account(self$secrets, scope = self$params$scope,  : 
  Unauthorized (HTTP 401).

Stepping through init_oauth_service_account line by line, I'm seeing that httr is making a POST call to google and getting this result:

Browse[2]> res
Response [https://oauth2.googleapis.com/token]
  Date: 2023-02-21 02:18
  Status: 401
  Content-Type: application/json; charset=utf-8
  Size: 188 B
{
  "error": "unauthorized_client",
  "error_description": "Client is unauthorized to retrieve access tokens using this method, or ...

Browse[2]> res %>% content()
$error
[1] "unauthorized_client"

$error_description
[1] "Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested."

So far I'm unable to figure out what is different between this code and our python implementation (using google.oauth2.service_account and googleapiclient.discovery), to explain why were getting this "unauthorized" error in R only.

@fh-kpikhart
Copy link
Author

Brief update:

  • Our use of gargle::credentials_service_account() was not working because that function appends to the scopes we passed in, and our user does not have the appended scope ("https://www.googleapis.com/auth/userinfo.email").
  • I am waiting for our IT team to add that scope to our user
  • I was able to test that we can generate a token and successfully read/write to Google Sheets if I manually remove the appended scope in credentials_service_account() (in debug mode)

At this point, I think my feature request would be to support the subject arg in googledrive::drive_auth()

@jennybc
Copy link
Member

jennybc commented Mar 9, 2023

Thanks for your continuing effort and sharing. I'm definitely interested in making this work and what you're doing is extremely helpful.

@fh-kpikhart
Copy link
Author

No problem!

FYI, I can confirm that after adding the additional scope, we are able to successfully accomplish our use case with gargle::credentials_service_account()

@jennybc
Copy link
Member

jennybc commented Mar 21, 2023

Very interesting! I'm not entirely sure yet how to act on this, but this is a very useful finding.

I mean: it is clear that drive_auth() will need to the ability to pass the subject arg along. But I'm not sure what to do about the "https://www.googleapis.com/auth/userinfo.email" scope (don't add it if subject is provided vs. try to add it but don't insist vs. document the need for it).

@jennybc jennybc added this to the v2.1.1 milestone Jun 8, 2023
@jennybc
Copy link
Member

jennybc commented Jun 8, 2023

I'm doing the most critical thing, which is to add subject as an argument to drive_auth(). The docs now also explicitly call out the need for the service account to have the "userinfo.email" scope. This may not be where the story ultimately ends, but this is definitely progress.

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

Successfully merging a pull request may close this issue.

2 participants