Authentication between services
In addition to authenticating end user requests, you may want to authenticate services (non-human users) that make requests to your API. This page explains how to use service accounts to provide authentication for humans or services.
Overview
To identify a service that sends requests to your API, you use a service account. The calling service uses the service account's private key to sign a secure JSON Web Token (JWT) and sends the signed JWT in the request to your API.
To implement service account authentication in your API and calling service:
- Create a service account and key for the calling service to use.
- Add support for authentication in the API config for your API Gateway service.
- Add code to the calling service that: - Creates a JWT and signs it with the service account's private key.
- Sends the signed JWT in a request to the API.
 
API Gateway validates that the claims in the JWT match the configuration in your API config before forwarding the request to your API. API Gateway doesn't check for Cloud Identity permissions that you have granted on the service account.
Prerequisites
This page assumes that you have already:
Creating a service account with a key
You need a service account with a private key file that the calling service uses to sign the JWT. If you have more than one service sending requests to your API, you can create one service account to represent all the calling services. If you need to differentiate between the services—for example, they might have different permissions—you can create a service account and key for each calling service.
This section shows how to use the Google Cloud console and the gcloud command-line tool to create the service account and private key file and to assign the service account the Service Account Token Creator role. For information on using an API to do this task, see Creating and managing service accounts.
To create a service account with a key:
Google Cloud console
Create a service account:
- In the Google Cloud console, go to Create service account. 
- Select a project. 
- In the Service account name field, enter a name. The Google Cloud console fills in the Service account ID field based on this name. 
- Optional: In the Service account description field, enter a description. 
- Click Create. 
- Click the Select a role field. - Under All roles, select Service Accounts > Service Account Token Creator. 
- Click Continue. 
- Click Done to finish creating the service account. - Do not close your browser window. You will use it in the next procedure. 
Create a service account key:
- In the Google Cloud console, click the email address for the service account that you created.
- Click Keys.
- Click Add key, then Create new key.
- Click Create. A JSON key file is downloaded to your computer.
- Click Close.
gcloud
You can run the following commands by using the Google Cloud CLI on your local machine, or within Cloud Shell.
- Set the default account for - gcloud. If you have more than one account, make sure to choose the account that is in the Google Cloud project that you want to use.- gcloud auth login
- Display the project IDs for your Google Cloud projects. - gcloud projects list
- Set the default project. Replace - PROJECT_IDwith the Google Cloud project ID that you want to use.- gcloud config set project PROJECT_ID 
- Create a service account. Replace - SA_NAMEand- SA_DISPLAY_NAMEwith the name and display name that you want to use.- gcloud iam service-accounts create SA_NAME \ --display-name "SA_DISPLAY_NAME" 
- Display the email address for the service account that you just created. - gcloud iam service-accounts list
- Add the Service Account Token Creator role. Replace - SA_EMAIL_ADDRESSwith the service account's email address.- gcloud projects add-iam-policy-binding PROJECT_ID \ --member serviceAccount:SA_EMAIL_ADDRESS \ --role roles/iam.serviceAccountTokenCreator 
- Create a service account key file in the current working directory. Replace - FILE_NAMEwith the name that you want to use for key file. By default, the- gcloudcommand creates a JSON file.- gcloud iam service-accounts keys create FILE_NAME.json \ --iam-account SA_EMAIL_ADDRESS 
See the gcloud reference for more information about the previous commands.
For information on safeguarding the private key, see Best practices for managing credentials.
Configuring your API to support authentication
When you create an API config for your gateway, you specify a service account that your gateway uses to interact with other services. In order to enable service account authentication for services calling your gateway, modify the security requirement object and security definitions object in your API config. Following the steps below will enable API Gateway to validate the claims in the signed JWT used by calling services.
- Add the service account as an issuer in your API config. - securityDefinitions: DEFINITION_NAME: authorizationUrl: "" flow: "implicit" type: "oauth2" x-google-issuer: "SA_EMAIL_ADDRESS" x-google-jwks_uri: "https://www.googleapis.com/robot/v1/metadata/x509/SA_EMAIL_ADDRESS" - Replace DEFINITION_NAMEwith a string that identifies this security definition. You might want to replace it with the service account name or a name that identifies the calling service.
- Replace SA_EMAIL_ADDRESSwith the service account's email address.
- You can define multiple security definitions in your API config, but each definition must have a different x-google-issuer. If you have created separate service accounts for each calling service, you can create a security definition for each service account, for example:
 - securityDefinitions: service-1: authorizationUrl: "" flow: "implicit" type: "oauth2" x-google-issuer: "service-1@example-project-12345.iam.gserviceaccount.com" x-google-jwks_uri: "https://www.googleapis.com/robot/v1/metadata/x509/service-1@example-project-12345.iam.gserviceaccount.com" service-2: authorizationUrl: "" flow: "implicit" type: "oauth2" x-google-issuer: "service-2@example-project-12345.iam.gserviceaccount.com" x-google-jwks_uri: "https://www.googleapis.com/robot/v1/metadata/x509/service-2@example-project-12345.iam.gserviceaccount.com" 
- Replace 
- Optionally, add - x-google-audiencesto the- securityDefinitionssection. If you don't add- x-google-audiences, API Gateway requires that the- "aud"(audience) claim in the JWT is in the format- https://SERVICE_NAME, where SERVICE_NAME is the name of your API Gateway service, which you have configured in the- hostfield of your OpenAPI document.
- Add a - securitysection at either the top level of the file (not indented or nested) to apply to the entire API, or at the method level to apply to a specific method. If you use- securitysections at both the API level and at the method level, the method-level settings override the API-level settings.- security: - DEFINITION_NAME: [] - Replace DEFINITION_NAMEwith the name that you used in thesecurityDefinitionssection.
- If you have more than one definition in the - securityDefinitionssection, add them in the- securitysection, for example:- security: - service-1: [] - service-2: [] 
 
- Replace 
- Deploy your updated API config. 
Before API Gateway forwards a request to your API, API Gateway verifies:
- The signature of the JWT by using the public key, which is located at the URI specified in the x-google-jwks_urifield in your API config.
- That the "iss"(issuer) claim in the JWT matches the value specified in thex-google-issuerfield.
- That the "aud"(audience) claim in the JWT contains your API Gateway service name or matches one of the values that you specified in thex-google-audiencesfield.
- That the token isn't expired by using the "exp"(expiration time) claim.
For more information about x-google-issuer, x-google-jwks_uri, and x-google-audiences, see OpenAPI extensions.
Making an authenticated request to an API Gateway API
To make an authenticated request, the calling service sends a JWT signed by the service account that you specified in the API config. The calling service must:
- Create a JWT and sign it with the service account's private key.
- Send the signed JWT in a request to the API.
The following sample code demonstrates this process for select languages. To make an authenticated request in other languages, reference jwt.io for a list of supported libraries.
-  In the calling service, add the following function and pass it the following parameters: Java -  saKeyfile: The full path to the service account's private key file.
-  saEmail: The service account's email address.
-  audience: If you added thex-google-audiencesfield to your API config, setaudienceto one of the values that you specified forx-google-audiences. Otherwise, setaudiencetohttps://SERVICE_NAME, whereSERVICE_NAMEis your API Gateway service name.
-  expiryLength: The JWT expiration time, in seconds.
 Python -  sa_keyfile: The full path to the service account's private key file.
-  sa_email: The service account's email address.
-  audience: If you added thex-google-audiencesfield to your API config, setaudienceto one of the values that you specified forx-google-audiences. Otherwise, setaudiencetohttps://SERVICE_NAME, whereSERVICE_NAMEis your API Gateway service name.
-  expiry_length: The JWT expiration time, in seconds.
 Go -  saKeyfile: The full path to the service account's private key file.
-  saEmail: The service account's email address.
-  audience: If you added thex-google-audiencesfield to your API config, setaudienceto one of the values that you specified forx-google-audiences. Otherwise, setaudiencetohttps://SERVICE_NAME, whereSERVICE_NAMEis your API Gateway service name.
-  expiryLength: The JWT expiration time, in seconds.
 The function creates a JWT, signs it by using the private key file, and returns the signed JWT. Java Python Go 
-  
-  In the calling service, add the following function to send the signed JWT in the Authorization: Bearerheader in the request to the API:Java Python Go 
When you send a request by using a JWT, for security reasons, we recommend that you put the authentication token in the Authorization: Bearer header. For example:
 curl --request POST \ --header "Authorization: Bearer ${TOKEN}" \ "${GATEWAY_URL}/echo" where GATEWAY_URL and TOKEN are environment variables containing your deployed gateway URL and authentication token, respectively.
Receiving authenticated results in your API
 API Gateway usually forwards all headers it receives. However, it overrides the original Authorization header when the backend address is specified by x-google-backend in the API config. 
 API Gateway will send the authentication result in the X-Apigateway-Api-Userinfo to the backend API. It is recommended to use this header instead of the original Authorization header. This header is base64url encoded and contains the JWT payload.