0

I'm trying to understand how gcloud manages to work with APIs that require service account to access them, e.g. accessing Speech API using your user (not svcacc) credentials will result in "403 Your application has authenticated using end user credentials from the Google Cloud SDK or Google Cloud Shell which are not supported by the speech.googleapis.com".

However when I run gcloud ml speech recognize gs://cloud-samples-tests/speech/brooklyn.flac --language-code=en-US it works just fine even-though I didn't set any dedidcated svcacc keys as described in the quick start [1], and even disabled all service accounts in the project just to be sure.

So again,

  • gcloud ml speech recognize gs://cloud-samples-tests/speech/brooklyn.flac --language-code=en-US - works
  • curl -s -H "Content-Type: application/json" -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) https://speech.googleapis.com/v1/speech:recognize -d @sync-request.json as per [2] fails with 403 error above

Question: how gcloud manages to work without me providing it with a dedicated service account?

[1] https://cloud.google.com/speech-to-text/docs/quickstart-gcloud

Zaar Hai
  • 9,152
  • 8
  • 37
  • 45

1 Answers1

1

Google credentials are provided by two types of account: service accounts and regular (human?) accounts (e.g. @gmail.com, @your.email). The types of tokens issued for these accounts differ but they both authenticate to services.

When you use gcloud you're often using human accounts that you have previously authenticated using gcloud auth login and may be shown with gcloud auth list.

In this case, you're also using these gcloud human credentials with curl because you acquire an access token using gcloud auth print-access-token. Your two examples effectively authenticated using the same (probably human) account.

When you want to have one service authenticate to another, it is recommended that you use service accounts. There's no human in the process to support OAuth's three-legged auth and so service accounts use two-legged auth (see link).

Generally with Cloud Platform services, credentials must also have IAM roles that describe permissions that authorize their use, but some Cloud Platform services (IIRC ML) do not (yet) implement IAM and so authorization is achieved solely using OAuth scopes and you can use vanilla service accounts that have no specific IAM bindings assigned.

NOTE it is possible to authenticate gcloud with service accounts too gcloud auth activate-service-account but IIRC this approach is being discouraged.

DazWilkin
  • 32,823
  • 5
  • 47
  • 88
  • Thanks for the elaborated answer, but that's not what I'm asking about: 1. in my curl i use `gcloud auth app-default print-access-token` (note the `app-default`). 2. both my gcloud and app-default credentials use my g-suite (not svacc) account, hence I don't understand how does gcloud API distinguish between the two (the former works, the latter doesn't). My only guess that checks for hard-code gcloud DEFAULT_CREDENTIALS_DEFAULT_CLIENT_ID and if it matches, throws "user service account error". – Zaar Hai May 29 '20 at 13:10
  • Finally, trying to mimic what `gcloud` does by supplying `gcloud auth print-access-token` (instead of app-default token), results in weird error that "Speech APi is not enabled for project 32555940559", which matches `CLOUDSDK_CLIENT_ID = '32555940559.apps.googleusercontent.com'` definition from gcloud code. I.e. gcloud call speech api in a way that I can't currently reproduce. – Zaar Hai May 29 '20 at 13:12
  • `application-default` is a way to generate service account like (!) credentials from your user (e.g. G Suite) account. I think this mechanism is now being discouraged. – DazWilkin May 29 '20 at 17:04