Google Cloud authentication can be confusing. This post explains how Application Default Credentials (ADC) work and how to fix common authentication errors.
When you’re authenticating with Google Cloud, it’s important to be clear on whether you’re trying to authenticate as a user or through a service account. Here’s some guidance on when to use each:
- User credentials: Best for local development and testing
- Service accounts: Best for production, CI/CD pipelines, and any automated processes
- Metadata server: Best when running on Google Cloud infrastructure
User credentials are tied to an individual identity. Service account credentials represent an automated identity used in production.
Checking your current credentials
The GOOGLE_APPLICATION_CREDENTIALS
environment variable tells ADC which credentials file to use. Check if it’s set:
echo $GOOGLE_APPLICATION_CREDENTIALS
You might see:
- Nothing (empty) - ADC will look for credentials in the default locations
- Path to service account - e.g.,
/path/to/my-service-account.json
- Path to user credentials - e.g.,
/Users/you/.config/gcloud/application_default_credentials.json
Where it looks
When you instantiate a client, the library looks for credentials in this order:
-
Wherever
GOOGLE_APPLICATION_CREDENTIALS
env var is pointing to (user account or service account JSON key) -
The default location, which is
~/.config/gcloud/application_default_credentials.json
. This is wheregcloud auth application-default login
will create credentials. -
Built-in service account on GCE/Cloud Run/Cloud Functions via the metadata server. This automatically provides credentials when running on Google Cloud infrastructure—no configuration needed.
Getting user credentials
gcloud auth application-default login
Credentials files
Below are two examples of what the credentials file might look like, depending on the type:
// User credentials example
{
"account": "",
"client_id": "[REDACTED_CLIENT_ID].apps.googleusercontent.com",
"client_secret": "[REDACTED_SECRET]",
"refresh_token": "[REDACTED_REFRESH_TOKEN]",
"type": "authorized_user",
"universe_domain": "googleapis.com"
}
// Service account example
{
"type": "service_account",
"project_id": "[PROJECT_ID]",
"private_key_id": "[REDACTED_KEY_ID]",
"private_key": "[REDACTED_PRIVATE_KEY]",
"client_email": "[SERVICE_ACCOUNT]@[PROJECT_ID].iam.gserviceaccount.com",
"client_id": "[REDACTED_CLIENT_ID]",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "[REDACTED_CERT_URL]"
}
It will either say "type": "authorized_user"
if it’s user credentials or "type": "service_account"
If you ran gcloud auth application-default login
and haven’t set GOOGLE_APPLICATION_CREDENTIALS
, ADC will default to your user credentials.
There is a script you can run to show your credentials here: https://github.com/jss367/scripts/blob/master/check_google_credentials.py
Which one am I using?
To check your credentials, you can enter:
cat $GOOGLE_APPLICATION_CREDENTIALS | grep '"type"'
Here are the possible responses:
- User credentials -
"type": "authorized_user",
- Service account -
"type": "service_account",
- External Account (Workload Identity) -
"type": "external_account",
- External Account Authorized User -
"type": "external_account_authorized_user",
Which one do I want to use?
Let’s walk through an example. Say you’ve run into this problem:
PermissionDenied: 403 Your application is authenticating by using local Application Default Credentials. The documentai.googleapis.com API requires a quota project, which is not set by default.
You probably want to switch to your service account.
Switching to your service account
You can see all your projects with gcloud projects list
You might get something like this:
PROJECT_ID NAME PROJECT_NUMBER
companydev companydev 123456789
Note that your id is not your number. It’s more likely to be a text string.
So you would do this:
gcloud iam service-accounts list \
--project companydev