Search code examples
pythongoogle-cloud-platformgoogle-oauthgoogle-admin-sdkgoogle-api-python-client

Accessing Google Admin API via Service Account


Is it possible to access the Google Admin Reports API via server to server Service Account authorization?

I am try to make a server to server call to the Google Admin API, following the tutorial here.

When setting domain-wide delegation, I added these scopes: https://www.googleapis.com/auth/admin.reports.usage.readonly, https://www.googleapis.com/auth/admin.reports.audit.readonly, as defined here.

I try making the API call like this, using the relevant PyPI packages:

creds = service_account.Credentials.from_service_account_file('credentials.json', scopes=SCOPES)

with build('admin', 'reports_v1', credentials=creds) as service:
  response = service.activities().list(userKey='all', applicationName='login', maxResults=10).execute()

Which results in the following error:

googleapiclient.errors.HttpError: <HttpError 401 when requesting https://admin.googleapis.com/admin/reports/v1/activity/users/all/applications/login?maxResults=10&alt=json returned "Access denied. You are not authorized to read activity records.". Details: "[{'message': 'Access denied. You are not authorized to read activity records.', 'domain': 'global', 'reason': 'authError', 'location': 'Authorization', 'locationType': 'header'}]">

When I make the API call using a different credentials method, such as Desktop Application, the call works as expected. However, the first time I run it, I have to interact with it via browser to approve/authenticate the call. Because this code will be running on a server without user interaction, that is not desirable behavior.

As a note, the docs for the Admin API say

Your application must use OAuth 2.0 to authorize requests. No other authorization protocols are supported.

Based on the documentation for sever to server calls, I believe service accounts still qualify as OAuth 2.0, but I could be wrong in that assumption.


Solution

  • In Google Workspace domains, the domain administrator can grant third-party applications with domain-wide access to its users' data — this is referred as domain-wide delegation of authority. Perform Google Workspace Domain-Wide Delegation of Authority

    The documentation even has a python example.

    from googleapiclient.discovery import build
    from oauth2client.service_account import ServiceAccountCredentials
    
    """Email of the Service Account"""
    SERVICE_ACCOUNT_EMAIL = '<some-id>@developer.gserviceaccount.com'
    
    """Path to the Service Account's Private Key file"""
    SERVICE_ACCOUNT_PKCS12_FILE_PATH = '/path/to/<public_key_fingerprint>-privatekey.p12'
    
    def create_reports_service(user_email):
        """Build and returns an Admin SDK Reports service object authorized with the service accounts
        that act on behalf of the given user.
    
        Args:
          user_email: The email of the user. Needs permissions to access the Admin APIs.
        Returns:
          Admin SDK reports service object.
        """
    
        credentials = ServiceAccountCredentials.from_p12_keyfile(
            SERVICE_ACCOUNT_EMAIL,
            SERVICE_ACCOUNT_PKCS12_FILE_PATH,
            'notasecret',
            scopes=['https://www.googleapis.com/auth/admin.reports.audit.readonly'])
    
        credentials = credentials.create_delegated(user_email)
    
        return build('admin', 'reports_v1', http=http)
    

    Notice that user_email is the user you are acting on behalf of, not the service account email.

    The error message Access denied. You are not authorized to read activity records. means that you have not properly set up delegation for the user. Contact your workspace admin and have them look into it.