yup-oauth2 icon indicating copy to clipboard operation
yup-oauth2 copied to clipboard

Support Application Default Credentials

Open mwilliammyers opened this issue 5 years ago • 6 comments

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.

mwilliammyers avatar Nov 02 '19 17:11 mwilliammyers

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 :(

dermesser avatar Nov 14 '19 22:11 dermesser

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.

mwilliammyers avatar Nov 26 '19 18:11 mwilliammyers

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!

dermesser avatar Dec 02 '19 19:12 dermesser

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...

mwilliammyers avatar Jun 06 '20 20:06 mwilliammyers

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.

dermesser avatar Sep 29 '20 09:09 dermesser

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

braincow avatar Jun 09 '21 12:06 braincow