Hide

OAuth Service Accounts

The AdWords API allows access without user intervention through service accounts for Google Apps domains. A service account employs an OAuth 2.0 flow that does not require human authorization, but uses instead a key file that only your application can access. This guide discusses how to access the AdWords API with service accounts.

OAuth2 offline and web flows require user interaction only once: when access to the account is granted. From that point, all operations can be executed with no manual steps until the access token is revoked. We strongly recommend using offline or web flows instead of service accounts unless you need domain-specific features (e.g. impersonation).

An alternative to service accounts

Many developers look at service accounts because they are interested in programmatic access to an API using OAuth2.0, but without user intervention. However, due to the complicated nature of setting up service accounts for the AdWords API, a simpler alternative that achieves the same goal is to use the OAuth 2.0 installed application flow and persist the refresh token. This way, your application will always be able to request a new access token when necessary.

The only caveat is that this process requires a user to manually authorize the application during the OAuth 2.0 installed applications flow. However this needs to be done only once since Google OAuth 2.0 refresh tokens do not expire.

Benefits of using service accounts with AdWords API

Using service accounts provides two major benefits:

  1. The authorization of an application to access a Google API is done as a configuration step and thus avoids the complications associated with other OAuth 2.0 flows that would otherwise require user intervention or your application to cache tokens to avoid future user intervention.
  2. OAuth 2.0 assertion flow allows for your application to impersonate other users if necessary.

The remainder of this guide walks you through the steps of how to use service accounts with the AdWords API. The code examples provided use the Google Ads Java client library for AdWords API, but can be adapted to AdWords API client libraries in other languages as well.

Prerequisites

Steps to using a service account to access the AdWords API

  1. Generate a service account key in your Google API Console:

    1. Go to the Google API Console.
    2. Click on the API Access tab.
    3. Click on Create another client ID...
    4. Select Service account as the Application type and click on Create client ID.
    5. Download your private key and store it in a safe place that only you can access.
    6. A new section called "Service account" should appear under your API Access information. Ensure this page is handy as you will need to copy the "Email address" later on.

  2. Using service accounts and assertion flow with Google OAuth 2.0 services require that you have your own domain registered with Google Apps. This is because user impersonation is controlled at the domain level with no finer granularity of access control. In other words, all users of a domain using a service account that has been whitelisted with the power to impersonate, can impersonate any user in the domain. For example, this is why Gmail accounts cannot be impersonated with service accounts.

    Security concerns

    Because of Google Apps domain-level control, it is important that you protect the *.p12 key file that allows a service account to access the Google services for which it has been authorized. This is especially the case since we are going to be granting that service account the ability to impersonate any user in the domain. It is also a good practice to allow service accounts to only access one Google API each (using the "scope" field shown in the next section). This is a preventative measure to mitigate the amount of data an attacker can access in the situation that the service account's *.p12 key file is compromised.

    Steps to granting a service account impersonation abilities

    1. Add a new authorized API client to your Google Apps domain by going to:
      https://www.google.com/a/cpanel/YOUR_DOMAIN/ManageOauthClients
      Note: Be sure to replace YOUR_DOMAIN with your actual domain (e.g., mydomain.com).

    2. Add a new authorized API client using the client ID we generated in the API console in step 1 as the "Client Name".

    3. Enter the following for the API scope:
      https://www.googleapis.com/auth/adwords

    4. Repeat the process for all other service accounts you want to grant impersonation power to.

  3. Now you can access your AdWords account using the service account via the OAuth 2.0 assertion flow. In the following code example, we use our service account with the OAuth 2.0 assertion flow to obtain an access token, then make a basic AdWords API call that gets all the campaigns associated with the test account.

    private static Credential getOAuth2Credential() throws Exception {
      // Service account credential.
      GoogleCredential credential = new GoogleCredential.Builder().setTransport(
          new NetHttpTransport())
          .setJsonFactory(new GsonFactory())
          .setServiceAccountId(
              "****@developer.gserviceaccount.com")
          .setServiceAccountScopes("https://www.googleapis.com/auth/adwords")
          .setServiceAccountPrivateKeyFromP12File(new File("/path/to/key.p12"))
          // Set the user you are impersonating. This should be a valid login email
          // for your AdWords API manager account or the advertiser account you are making
          // calls to.
          .setServiceAccountUser("[email protected]")
          .build();
    
      credential.refreshToken();
      return credential;
    }
    
    public static void runExample(AdWordsServices adWordsServices, AdWordsSession session) throws Exception {
      // Get the CampaignService.
      CampaignServiceInterface campaignService =
          adWordsServices.get(session, CampaignServiceInterface.class);
    
      // Create selector.
      Selector selector = new Selector();
      selector.setFields(new String[] {"Id", "Name"});
    
      // Get all campaigns.
      CampaignPage page = campaignService.get(selector);
    
      // Display campaigns.
      if (page.getEntries() != null) {
        for (Campaign campaign : page.getEntries()) {
          System.out.println("Campaign with name \"" + campaign.getName() + "\" and id \""
              + campaign.getId() + "\" was found.");
        }
      } else {
        System.out.println("No campaigns were found.");
      }
    }
    
    public static void main(String[] args) throws Exception {
      // Get the OAuth2 credential.
      Credential credential = getOAuth2Credential();
    
      // Construct an AdWordsSession.
      AdWordsSession session = new AdWordsSession.Builder()
          .fromFile()
          .withOAuth2Credential(credential)
          .build();
    
      AdWordsServices adWordsServices = new AdWordsServices();
      runExample(adWordsServices, session);
    }

Send feedback about...

AdWords API