qroberts
qroberts

Reputation: 119

GCP: Allow Service Account to Impersonate a User Account with Google Analytics Scopes

I am trying to create a script that enables a Service Account [email protected] to impersonate a user account [email protected] with the following GA scopes:

target_scopes = ['https://www.googleapis.com/auth/analytics',
'https://www.googleapis.com/auth/analytics.edit',
'https://www.googleapis.com/auth/analytics.manage.users',
'https://www.googleapis.com/auth/analytics.provision',
'https://www.googleapis.com/auth/analytics.user.deletion'] 

So it can add properties to other GA accounts that the user account ([email protected]) has previously been given access to.

This is the code I've written that includes impersonation:

from google.auth import impersonated_credentials    
from google.oauth2 import service_account
target_scopes = ['https://www.googleapis.com/auth/analytics','https://www.googleapis.com/auth/analytics.edit','https://www.googleapis.com/auth/analytics.manage.users','https://www.googleapis.com/auth/analytics.provision','https://www.googleapis.com/auth/analytics.user.deletion']

source_credentials = service_account.Credentials.from_service_account_file(    
'ga-1234567890.json',    
scopes=target_scopes)    
target_credentials = impersonated_credentials.Credentials(
source_credentials=source_credentials,
    target_principal='[email protected]',    
target_scopes=target_scopes,    
lifetime=500)
   

client = AnalyticsAdminServiceClient(credentials=target_credentials)

Which returns the exception:

>Oops! <class 'google.api_core.exceptions.ServiceUnavailable'> occurred.
grpc._channel._InactiveRpcError: <_InactiveRpcError of RPC that terminated with:    
status = StatusCode.UNAVAILABLE    
details = "Getting metadata from plugin failed with error: ('Unable to acquire impersonated credentials', '{\n  "error": {\n"code": 404,\n"message": "Not found; Gaia id not found for email [email protected]",\n     
"status": "NOT_FOUND"\n  }\n}\n')"

debug_error_string = "UNKNOWN:Error received from peer analyticsadmin.googleapis.com:443 {created_time:"2022-11-17T15:28:49.7504959+00:00", grpc_status:14, grpc_message:"Getting metadata from plugin failed with error: (\'Unable to acquire impersonated credentials\', \'{\\n  \"error\": {\\n\"code\": 404,\\n\"message\": \"Not found; Gaia id not found for email [email protected]\",\\n\"status\": \"NOT_FOUND\"\\n  }\\n}\\n\')"}"  

When I attempt to run the below code without impersonation:

from google.auth import impersonated_credentials    
from google.oauth2 import service_account    
target_scopes = ['https://www.googleapis.com/auth/analytics','https://www.googleapis.com/auth/analytics.edit','https://www.googleapis.com/auth/analytics.manage.users','https://www.googleapis.com/auth/analytics.provision','https://www.googleapis.com/auth/analytics.user.deletion']

source_credentials = service_account.Credentials.from_service_account_file(    
'ga-1234567890.json',    
scopes=target_scopes)    

client = AnalyticsAdminServiceClient(credentials=source_credentials)

It returns the exception:

Oops! <class 'google.api_core.exceptions.Unauthenticated'> occurred. grpc._channel._InactiveRpcError: <_InactiveRpcError of RPC that terminated with:
status = StatusCode.UNAVAILABLE
details = "Getting metadata from plugin failed with error: ('Unable to acquire impersonated credentials', '{\n "error": {\n"code": 404,\n"message": "Not found; Gaia id not found for email [email protected]",\n
"status": "NOT_FOUND"\n }\n}\n')"
debug_error_string = "UNKNOWN:Error received from peer analyticsadmin.googleapis.com:443 {created_time:"2022-11-17T15:28:49.7504959+00:00", grpc_status:14, grpc_message:"Getting metadata from plugin failed with error: ('Unable to acquire impersonated credentials', '{\n "error": {\n"code": 404,\n"message": "Not found; Gaia id not found for email [email protected]",\n"status": "NOT_FOUND"\n }\n}\n')"}"

The service account [email protected] has principal [email protected] with roles Service Account Token Creator and Service Account User

The service account [email protected] has Domain-wide Delegation configured in Google Workspace Admin with scopes

https://www.googleapis.com/auth/analytics https://www.googleapis.com/auth/analytics.edit https://www.googleapis.com/auth/analytics.manage.users https://www.googleapis.com/auth/analytics.provision https://www.googleapis.com/auth/analytics.user.deletion

Not sure what I am missing here, any advice would be greatly appreciated.

Upvotes: 0

Views: 1466

Answers (1)

Linda Lawton - DaImTo
Linda Lawton - DaImTo

Reputation: 117301

Assuming that you configured domain wide delegation to the service account though your google workspace. And configured it to a user who has access to the google analytics account.

The same code used to delegate to the other apis should work as well.

credentials = service_account.Credentials.from_service_account_file('my_json.json', scopes=['https://www.googleapis.com/auth/adwords'])

delegated_credentials = credentials.with_subject("[email protected]")

client = AnalyticsAdminServiceClient(credentials=delegated_credentials)

Now by the looks of your error messages im wondering if the system even supports it.

Im going to send an email off to the team, before we start chasing this lets check delegation is supported.

Upvotes: 2

Related Questions