python-3.xgoogle-cloud-platformgoogle-workspacegoogle-groups-settings

Google Group Settings API Authorization Error


I am trying to setup Group Settings service, but cannot figure out where the issue is with the authorization. Below is the code that I am using to test:

import os
import internal_package
from google.oauth2 import service_account
from googleapiclient.discovery import build


# read credential from vault
gsuite_service_account = internal_package.vault.get_credential(service_account="gsuite_script", json_response=True)
if gsuite_service_account is None:
    raise ValueError('gsuite_script')
user_account = gsuite_service_account['user_email']

scopes = ['https://www.googleapis.com/auth/apps.groups.settings']

# Load credentials for Service Account
service_account_file = os.environ["GOOGLE_APPLICATION_CREDENTIALS"]

credentials = service_account.Credentials.from_service_account_file(service_account_file, scopes=scopes, subject=user_account)

group_client = build("groupssettings", "v1", credentials=credentials)
print("GSuite service successfully configured.")

group_email = 'soc@example.com'
group_settings = group_client.groups().get(groupUniqueId=group_email).execute()

The script is using gsuite_service_account (Google Cloud service account) to impersonate user_account (Google workspace account).

There are no errors creating the group_client, but when the script executed the last GET method, it generates an authorization error:

raise exceptions.RefreshError(
google.auth.exceptions.RefreshError: ('unauthorized_client: Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested.', {'error': 'unauthorized_client', 'error_description': 'Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested.'})

I have checked the following:

  1. The 'gsuite_service_account' has been granted the the group settings scope (https://www.googleapis.com/auth/apps.groups.settings) in Google Workspace under API Controls.
  2. The 'user_account' has been granted Group Admin as well as Groups for Business role in Workspace.

I am able to use the same accounts with Admin SDK v1 successfully, but not group setting API. Any idea what I might be missing?'


Solution

  • Your code works for me (albeit without the secret manager)

    main.py:

    import os
    
    from google.oauth2 import service_account
    from googleapiclient.discovery import build
    
    project_id = os.getenv("PROJECT")
    service_account_file = os.getenv("GOOGLE_APPLICATION_CREDENTIALS")
    
    user_account = os.getenv("USER_EMAIL") # me@my-domain.com
    group_account = os.getenv("GROUP_EMAIL") # foo@my-domain.com
    
    scopes = ["https://www.googleapis.com/auth/apps.groups.settings"]
    
    credentials = service_account.Credentials.from_service_account_file(
        service_account_file,
        scopes=scopes,
        subject=user_account,)
    
    
    group_client = build("groupssettings", "v1", credentials=credentials)
    print("GSuite service successfully configured.")
    
    group_settings = group_client.groups().get(groupUniqueId=group_account).execute()
    print(group_settings)
    

    I already had a domain-wide delegated service account and added the apps.groups.settings scope per your question:

    https://admin.google.com/ac/owl/domainwidedelegation

    I used https://groups.google.com to create a Group (foo) and then set GROUP_EMAIL to foo@my-domain.com.

    Then:

    PROJECT="..." # Project that owns the domain-wide delegated account
    ACCOUNT="..." # Name of the domain-wide delegated account
    
    EMAIL="${ACCOUNT}@${PROJECT}.iam.gserviceaccount.com"
    
    gcloud services enable groupssettings.googleapis.com \
    --project=${PROJECT}
    
    gcloud iam service-accounts keys create ${PWD}/${ACCOUNT}.json \
    --iam-account=${EMAIL}
    
    # Arbitrary role that it's in the Project's IAM binding
    gcloud projects add-iam-policy-binding ${PROJECT} \
    --member=serviceAccount:${EMAIL} \
    --role=roles/iam.serviceAccountUser
    

    Ran the code and yields:

    {
        "kind": "groupsSettings#groups",
        "email": "foo@my-domain.com",
        "name": "foo",
        ...
    }