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

Support Application Default Credentials #110

Open
mwilliammyers opened this issue Nov 2, 2019 · 6 comments
Open

Support Application Default Credentials #110

mwilliammyers opened this issue Nov 2, 2019 · 6 comments

Comments

@mwilliammyers
Copy link

mwilliammyers commented Nov 2, 2019

I originally opened this over in google-apis-rs/generator#20, so let me know if you think this is a better fit for that project.

What do you think about supporting Application Default Credentials? To start we could just check GOOGLE_APPLICATION_CREDENTIALS.

Down the road, we could also communicate with the metadata server to automatically obtain credentials if GOOGLE_APPLICATION_CREDENTIALS wasn’t provided. This would obviously be more involved but I think reverse engineering this process from one of the official client libraries wouldn’t be too bad.

I envision adding a new top level function like: yup_oath2:: service_account_key_from_application_default_credentials, although that is rather verbose...

So the flow would be:

Try to use an explicitly provided service account.
If None, check GOOGLE_APPLICATION_CREDENTIALS
(Future work) If None, communicate with metadata server to use default service account
If still not found, Err.

One of the things I love about GCP (as opposed to AWS etc) is their authentication mechanism. It is so seamless and uniform across all their APIs. This would be a big step towards that UX.

Once we decide on a direction, I would be happy to open a PR.

@dermesser
Copy link
Owner

I am quite sympathetic towards supporting them. I also have #44 lying around for some time now, which I think is related.

The flow sounds good to me, however I am tending very much towards modular and optional approaches rather than magic intransparent ones (I want to be clear so we're on the same page). So as long as the change works well with other providers too, although yes - yup-oauth2 is mostly Google focused still, and is somewhat transparent to users of the library, I would be extremely happy to take a PR from you!

Also apologies for the delay :(

@mwilliammyers
Copy link
Author

Yeah #44 and #186 are both what I am proposing here. Although I was proposing doing #44 at a later stage.

I am trying to think of the best API for this because I agree I don’t like “magic” solutions, but the entire Google Application Default Credentials flow (which is pretty much what I described above but for some reason forgot to link this) is fairly automatic/magical which is kind of its strength—to make auth a lot less of a hassle in production. I am mostly interested in this as a feature parity with official Google cloud SDK libraries.

@dermesser
Copy link
Owner

I think magic is fine if it is well-documented. So taking the credentials from environment variables or the GCE sidecar server is fine, if we say so in the module's documentation (and explain how it works and what to do if it doesn't).

Feature parity with google cloud libraries would be awesome!

@mwilliammyers
Copy link
Author

mwilliammyers commented Jun 6, 2020

I am hoping to have time to work this soon...

It looks like we just need to:

  1. If GOOGLE_APPLICATION_CREDENTIALS is set, call
    yup_oauth2::read_service_account_key() and
    yup_oauth2::ServiceAccountAuthenticator::builder()

  2. If not, make the equivalent HTTP request (works on GCE, GKE, App Engine, Cloud Run, and possibly more?):

    curl "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token" -H "Metadata-Flavor: Google"
    

    which returns:

    { "access_token": "...", "expires_in": 2801, "token_type": "Bearer" }
  3. Else: return an Err



In the end, I am envisioning an API that looks something like (definitely need to think of a better name):

let authenticator = yup_oauth2::ApplicationDefaultCredentialsAuthenticator::new().await?;

or we could use the builder pattern to match the other flows, but there isn't
really anything to configure (pretty much the point of using ADC 🙃)... Although, there might be other things to configure, like persist_tokens_to_disk etc...

@dermesser
Copy link
Owner

I agree with your approaches, it looks similar to what I had thought of before. If you were to send a PR, I will gladly integrate it! For me to built/test it, I'd first have to set up a proper environment on Google Cloud again.

@braincow
Copy link
Contributor

braincow commented Jun 9, 2021

Boosting signal on this linked issue as well:

I have created a small bare bones impl of this and would requests comments/contributions on it before creating an pull request: https://github.com/braincow/yup-oauth2/tree/gcp_instance_metadata

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

No branches or pull requests

3 participants