This guide helps you choose and configure the appropriate authentication approach for your Data Manager API production deployment.
Choose your deployment scenario
Select the authentication approach that matches your application architecture and deployment environment:
- Workloads in Google Cloud: For automated workloads (such as ETL pipelines, batch jobs, or backend services) running on Compute Engine, Cloud Run, Cloud Functions, or GKE, use Application Default Credentials (ADC) with an attached service account or Workload Identity Federation for GKE.
- Workloads outside Google Cloud: For automated workloads running on-premises or on other cloud providers, use Application Default Credentials (ADC) with Workload Identity Federation or a service account key.
- Act on behalf of users: For third-party platforms and multi-tenant applications that manage accounts for external users (such as advertisers who sign up on your platform), use the OAuth 2.0 Web Server flow with per-user refresh tokens, or partner links if you are an approved data partner.
For general guidance on Google Cloud authentication, see the Google Cloud authentication decision tree.
Workloads in Google Cloud
When running on Google Cloud, attach a service account directly to your compute resource or configure Workload Identity Federation for GKE. Client libraries use ADC to retrieve short-lived credentials for the service account automatically without requiring credential files or environment variables.
Compute Engine
When creating a virtual machine instance, specify the service account and the Data Manager API scope so access tokens returned by the instance metadata server include the required authorization.
gcloud compute instances create INSTANCE_NAME \
--service-account="SERVICE_ACCOUNT_EMAIL" \
--scopes="https://www.googleapis.com/auth/datamanager,https://www.googleapis.com/auth/cloud-platform"
To update the scopes or service account on an existing instance, stop the
instance, update the configuration with set-service-account, and restart
the instance:
gcloud compute instances stop INSTANCE_NAME
gcloud compute instances set-service-account \
INSTANCE_NAME \
--service-account="SERVICE_ACCOUNT_EMAIL" \
--scopes="https://www.googleapis.com/auth/datamanager,https://www.googleapis.com/auth/cloud-platform"
gcloud compute instances start INSTANCE_NAME
Cloud Run
Specify the service account when deploying the service:
gcloud run deploy SERVICE_NAME \
--image="IMAGE_URL" \
--service-account="SERVICE_ACCOUNT_EMAIL"
Cloud Functions
Specify the service account when deploying the function:
gcloud functions deploy FUNCTION_NAME \
--service-account="SERVICE_ACCOUNT_EMAIL" \
--runtime="RUNTIME" \
--trigger-http
GKE
- Enable Workload Identity Federation for GKE on your cluster.
Bind your Kubernetes Service Account (KSA) to the Google Service Account (GSA):
# Define the Kubernetes service account member: KUBERNETES_MEMBER="serviceAccount:PROJECT_ID.svc.id.goog[KUBERNETES_NAMESPACE/KUBERNETES_SA_NAME]" # Grant the Workload Identity User role to the Kubernetes service account: gcloud iam service-accounts add-iam-policy-binding \ SERVICE_ACCOUNT_EMAIL \ --role="roles/iam.workloadIdentityUser" \ --member="${KUBERNETES_MEMBER}"Annotate the Kubernetes Service Account with the Google Service Account email:
kubectl annotate serviceaccount KUBERNETES_SA_NAME \ --namespace="KUBERNETES_NAMESPACE" \ iam.gke.io/gcp-service-account="SERVICE_ACCOUNT_EMAIL"Specify the Kubernetes Service Account in your pod specification:
apiVersion: v1 kind: Pod metadata: name: data-manager-worker spec: serviceAccountName: KUBERNETES_SA_NAME containers: - name: worker image: IMAGE_URL
Verify IAM and account access
Before deploying your production application, verify that your service account has the necessary permissions:
Google Cloud IAM permissions: Grant the service account the Service Usage Consumer role (
roles/serviceusage.serviceUsageConsumer) in the Google Cloud project where the Data Manager API is enabled.gcloud projects add-iam-policy-binding PROJECT_ID \ --member="serviceAccount:SERVICE_ACCOUNT_EMAIL" \ --role="roles/serviceusage.serviceUsageConsumer"Destination account access: Grant the service account the required access to your destination accounts. For step-by-step instructions, see Set up account access.
Workloads outside Google Cloud
When running code in on-premises data centers or on other cloud providers, choose one of the following authentication mechanisms:
Workload Identity Federation (Recommended): Configure Workload Identity Federation to let your application exchange credentials from your external identity provider for short-lived Google Cloud credentials without managing service account keys. Generate a credential configuration file and provide it to ADC using the
GOOGLE_APPLICATION_CREDENTIALSenvironment variable.Service account keys (Fallback): If Workload Identity Federation is not available, create a service account key and provide it to ADC using the
GOOGLE_APPLICATION_CREDENTIALSenvironment variable.
Set GOOGLE_APPLICATION_CREDENTIALS
Set the GOOGLE_APPLICATION_CREDENTIALS environment variable to the absolute
path of the Workload Identity Federation credential configuration file or
service account key file so client libraries can locate your credentials
automatically using ADC.
Linux / macOS
Set the environment variable in your shell profile or deployment script:
export GOOGLE_APPLICATION_CREDENTIALS=\
"/path/to/credentials.json"
Windows (PowerShell)
Set the environment variable in PowerShell:
$env:GOOGLE_APPLICATION_CREDENTIALS = `
"C:\path\to\credentials.json"
Docker / Containers
Mount the credentials file into the container and set the environment variable:
ENV GOOGLE_APPLICATION_CREDENTIALS="/secrets/credentials.json"
Or pass the environment variable at runtime:
HOST_CREDS="/host/path/credentials.json"
docker run -e GOOGLE_APPLICATION_CREDENTIALS="/secrets/credentials.json" \
-v "${HOST_CREDS}:/secrets/credentials.json:ro" \
IMAGE_NAME
Kubernetes
Mount the credentials as a Secret and reference it in the pod's environment:
apiVersion: v1
kind: Pod
metadata:
name: data-manager-worker
spec:
containers:
- name: worker
image: IMAGE_URL
env:
- name: GOOGLE_APPLICATION_CREDENTIALS
value: "/etc/secrets/google/credentials.json"
volumeMounts:
- name: credentials-volume
mountPath: "/etc/secrets/google"
readOnly: true
volumes:
- name: credentials-volume
secret:
secretName: data-manager-credentials
Authenticate REST and curl requests
If your automated pipeline makes raw HTTP requests with curl rather than using
a client library, use the Google Cloud CLI to non-interactively authenticate and
manage access tokens without manually signing tokens:
Authorize the Google Cloud CLI using the credential file configured in your environment:
gcloud auth login --cred-file="${GOOGLE_APPLICATION_CREDENTIALS}"Pass the generated access token in the
Authorizationheader of your API requests:curl -X POST "https://datamanager.googleapis.com/v1/..." \ -H "Authorization: Bearer $(gcloud auth print-access-token)" \ -H "Content-Type: application/json" \ -d @request.jsonThe Google Cloud CLI automatically caches the access token and refreshes it before expiration.
Verify IAM and account access
Before deploying your production application, verify that your service account has the necessary permissions:
Google Cloud IAM permissions: Grant the service account the Service Usage Consumer role (
roles/serviceusage.serviceUsageConsumer) in the Google Cloud project where the Data Manager API is enabled.gcloud projects add-iam-policy-binding PROJECT_ID \ --member="serviceAccount:SERVICE_ACCOUNT_EMAIL" \ --role="roles/serviceusage.serviceUsageConsumer"Destination account access: Grant the service account the required access to your destination accounts. For step-by-step instructions, see Set up account access.
Act on behalf of users
Third-party platforms such as marketing platforms and agencies often need to send API requests on behalf of multiple advertisers who sign up for their service.
In this architecture, instead of using Application Default Credentials, use the OAuth 2.0 Web Server flow to obtain user credentials with offline access from each advertiser, and then use those credentials to configure the client library at runtime based on which advertiser account the request is managing.
Implement the OAuth 2.0 web flow
Here is how to set up user delegation for multi-tenant applications:
Request offline access: Direct users to Google's OAuth consent screen requesting the
https://www.googleapis.com/auth/datamanagerscope withaccess_type=offlineandprompt=consent. Your server exchanges the authorization code for an access token and arefresh_token. For step-by-step instructions, see OAuth 2.0 for Web Server Applications.Store credentials securely: Store each user's refresh token securely in an encrypted credential store associated with their account on your platform.
Initialize client libraries at runtime: When sending an API request on behalf of a specific user, construct user credentials from the refresh token you stored for the user and the client ID and client secret for your app, and pass them when initializing the client:
.NET
using Google.Ads.DataManager.V1; using Google.Apis.Auth.OAuth2; UserCredential credential = CredentialFactory.FromJsonParameters<UserCredential>( new JsonCredentialParameters { Type = JsonCredentialParameters.AuthorizedUserCredentialType, ClientId = clientId, ClientSecret = clientSecret, RefreshToken = refreshToken }); IngestionServiceClient client = new IngestionServiceClientBuilder { Credential = credential }.Build();Go
import ( "context" datamanager "cloud.google.com/go/datamanager/apiv1" "golang.org/x/oauth2" "golang.org/x/oauth2/google" "google.golang.org/api/option" ) cfg := &oauth2.Config{ ClientID: clientID, ClientSecret: clientSecret, Endpoint: google.Endpoint, } ts := cfg.TokenSource(ctx, &oauth2.Token{RefreshToken: refreshToken}) client, err := datamanager.NewIngestionClient(ctx, option.WithTokenSource(ts))Java
import com.google.ads.datamanager.v1.IngestionServiceClient; import com.google.ads.datamanager.v1.IngestionServiceSettings; import com.google.api.gax.core.FixedCredentialsProvider; import com.google.auth.oauth2.UserCredentials; UserCredentials credentials = UserCredentials.newBuilder() .setClientId(clientId) .setClientSecret(clientSecret) .setRefreshToken(refreshToken) .build(); IngestionServiceSettings settings = IngestionServiceSettings.newBuilder() .setCredentialsProvider(FixedCredentialsProvider.create(credentials)) .build(); try (IngestionServiceClient client = IngestionServiceClient.create(settings)) { // Send API requests using client... }Node.js
const {IngestionServiceClient} = require('@google-ads/datamanager').v1; const {UserRefreshClient} = require('google-auth-library'); const authClient = new UserRefreshClient({ clientId, clientSecret, refreshToken, }); const client = new IngestionServiceClient({authClient});PHP
use Google\Ads\DataManager\V1\Client\IngestionServiceClient; use Google\Auth\Credentials\UserRefreshCredentials; $credentials = new UserRefreshCredentials( null, [ 'client_id' => $clientId, 'client_secret' => $clientSecret, 'refresh_token' => $refreshToken, ] ); $client = new IngestionServiceClient(['credentials' => $credentials]);Python
from google.ads.datamanager_v1 import IngestionServiceClient from google.oauth2.credentials import Credentials credentials = Credentials.from_authorized_user_info({ "client_id": client_id, "client_secret": client_secret, "refresh_token": refresh_token, }) client = IngestionServiceClient(credentials=credentials)Ruby
require "google/ads/data_manager/v1" require "googleauth" credentials = Google::Auth::UserRefreshCredentials.new( client_id: client_id, client_secret: client_secret, refresh_token: refresh_token ) client = Google::Ads::DataManager::V1::IngestionService::Client.new do |config| config.credentials = credentials end
Complete OAuth app verification
Because https://www.googleapis.com/auth/datamanager is a sensitive scope, any Google Cloud
app used to obtain user credentials from external Google Accounts must undergo
Google OAuth verification before going to production:
- Development: While the app's publishing status is set to Testing on the Audience page in the Google Cloud Console, only designated test accounts can authorize your application.
- Production: Before making your application available to external users, set the publishing status to In production and submit the app for verification.
App verification isn't required for workloads that run using service accounts. In addition, there are some exceptions for scenarios such as internal applications. Check out When is verification not needed for details.
Alternative: Partner links
If your organization is an approved data partner, you can use partner links instead of managing per-user OAuth tokens for ongoing data ingestion.
With partner links, advertisers connect their accounts to your data partner account in the Google Ads, Display & Video 360, or Google Ad Manager UI. After the link is established, your application sends ingestion requests using your own service account credentials through ADC, avoiding the need to store and maintain long-lived user refresh tokens.
Production best practices
Review these key operational considerations when moving to production:
- Error handling and validation: Understand how the API validates requests using the fast-fail model and returns structured error details.
- Retry strategy: Implement exponential backoff with jitter for transient server errors.
- Batching and concurrency: Maximize throughput by batching records and sending requests concurrently within limits.
- Diagnostics and monitoring: Capture response request IDs and query the diagnostics service to verify asynchronous processing and detect warnings and errors.