AIP-4112

Service Account Keys

A service account is a special kind of account used by an application or a virtual machine (VM) instance, not a person. Applications use service accounts to make authorized API calls, authorized as either the service account itself, or as Google Workspace or Cloud Identity users through domain-wide delegation. Service accounts are associated with private/public RSA key-pairs that are used for authentication, which is the focus of this AIP.

Note: Because this AIP describes guidance and requirements in a language-neutral way, it uses generic terminology which may be imprecise or inappropriate in certain languages or environments.

Guidance

This section describes the general guidance of supporting Service Account Key authentication using traditional OAuth flow. For Service Account Key authentication using self-signed JWT flow, please refer to the self-signed JWT AIP.

Service Account Key Authentication Using OAuth

Under the latest ADC guidance, when Service Account Key is provided as the source credential, we prefer to use the self-signed JWT flow by default, which does not use the OAuth "scope" argument. Therefore, the client should choose the OAuth flow over self-signed JWT flow only if the OAuth "scope" is explicitly provided to the client.

Expected Behavior

To support Service Account Key authentication using OAuth flow, the auth libraries must follow the steps below:

1. Load the Service Account ID JSON file from the file path specified by GOOGLE_APPLICATION_CREDENTIALS environment variable, or an explicit credentials file path specified through client options. The JSON file will look like below:

{
  "type": "service_account",
  "project_id": "testproject",
  "private_key_id": "redacted",
  "private_key": "redacted",
  "client_email": "testserviceaccount@test.iam.gserviceaccount.com",
  "client_id": "113258942105700140798",
  "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": "https://www.googleapis.com/robot/v1/metadata/x509/testserviceaccount%40test.iam.gserviceaccount.com"
}

Note: A Service Account ID JSON file can be downloaded from Google Cloud Console.

2. Using any standard JWT library, such as one found at jwt.io, create a JWT with a header and claims set like the following example:

{
  "alg": "RS256",
  "typ": "JWT",
  "kid": "abcdef1234567890"
}
{
  "iss": "123456-compute@developer.gserviceaccount.com",
  "sub": "123456-compute@developer.gserviceaccount.com",
  "scope": "https://www.googleapis.com/auth/pubsub",
}
  • For the kid field in the header, specify the service account's private key ID. You can find this value in the private_key_id field of the service account JSON file.

  • For the iss and sub fields, specify the service account's email address. You can find this value in the client_email field of the service account JSON file.

  • For the scope field, specify the scope parameter provided by the client. Multiple scopes can be specified using single space (" ") as delimiter.

3. Sign the JWT with RSA-256 using the private_key found in the service account JSON file. The output will be used as the request payload (a.k.a. assertion) for the 2-legged OAuth flow.

4. Define a parameter "grant_type" as "urn:ietf:params:oauth:grant-type:jwt-bearer". Define a parameter "assertion" as the payload from step 3.

5. Make a POST request to the token_uri endpoint with the parameters from step 4 to obtain an OAuth2 Access Token.