3

I am attempting to use a service account to access members of a group. I have verified that I can do this using a normal OAuth2 token on behalf of a user, with a call to https://www.googleapis.com/admin/directory/v1/groups/{group}/members and the scope https://www.googleapis.com/auth/admin.directory.group.readonly.

I’d like to do the same with a service account, and I have added the service account email address as a group member and verified that View Members permissions are set to “All members of the group, All organization members”.

When I ask for a list of members, I receive this error:

{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "forbidden",
    "message": "Not Authorized to access this resource/api"
   }
  ],
  "code": 403,
  "message": "Not Authorized to access this resource/api"
 }
}

What do I need to do to authorize this service account to see the group?

  • It's a good practice to reformulate your question at the beginning or at the end of a post. Make sure you have a question in you question's post ;) – Jeremy Dicaire Jun 10 '15 at 18:13
  • 1
    service account can be a confusing term. Do you mean the service account you created in API Console? Or it is just a generic user account? – Emily Jun 10 '15 at 20:45
  • Yes, I mean a Service Account created in the API console. – Michal Migurski Jun 10 '15 at 23:10
  • Have you authorized to scopes for the service account as per the documentation here: https://developers.google.com/admin-sdk/directory/v1/guides/delegation ? The service account shouldn't need any membership as you're granting access to the Admin SDK which can view membership details (just like any super admin account access could). – miketreacy Jun 11 '15 at 14:53
  • I have now, but see below: it didn’t make a difference. – Michal Migurski Jun 11 '15 at 19:54

2 Answers2

1

Assume that you have the following

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

SCOPES = ["https://www.googleapis.com/auth/admin.directory.user", 
          "https://www.googleapis.com/auth/admin.directory.group"]

credentials = service_account.Credentials.from_service_account_file(
                PATH-TO-YOUR-SERVICE-ACCOUNT-FILE, 
                scopes=SCOPES, subject=ADMIN-EMAIL-ID)
service = build('admin', 'directory_v1', credentials=credentials)
group = "YOUR-GROUP-EMAIL-ID"
direct_members = service.members().list(groupKey=group).execute()["members"]
print(direct_members)

# Note that the above code would give only direct members.
# To get the direct members, set the `inclueDerivedMembership` 
# argument to True as below.
all_members = service.members().list(
              groupKey=group, inclueDerivedMembership=True).execute()["members"]
print(all_members)

The source of truth of this answer is here.

Abhishek Mishra
  • 1,984
  • 1
  • 18
  • 13
0

You can follow the steps outlined in the following API docs page to create the service account and perform a domain wide delegation of authority, please bear in mind you need the email address of any user who is a member of the group (userEmail in the code snippet below) so the service account can act on their behalf:

https://developers.google.com/admin-sdk/directory/v1/guides/delegation

The page includes a Java and Python examples of how to instantiate a com.google.api.services.admin.directory.Directory object using the service account and private key created on the Google Developers Console

 GoogleCredential credential = new GoogleCredential.Builder()
  .setTransport(httpTransport)
  .setJsonFactory(jsonFactory)
  .setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
  .setServiceAccountScopes(DirectoryScopes.ADMIN_DIRECTORY_USERS)
  .setServiceAccountUser(userEmail)
  .setServiceAccountPrivateKeyFromP12File(
      new java.io.File(SERVICE_ACCOUNT_PKCS12_FILE_PATH))
  .build();
omerio
  • 1,186
  • 7
  • 16
  • Looks promising. I’ve added my Service Account Client ID under “Manage API client access”, and now I think I’m stuck on the next step. Here’s a short code sample which uses the content of the key; the first call to the G+ API works so I know the key is good, and the second continues to fail: https://gist.github.com/migurski/9b8e44da1536c5713e0a – Michal Migurski Jun 11 '15 at 18:57
  • What is client_email? is this the service account email or the email of the user that the service account is acting on their behalf – omerio Jun 12 '15 at 09:44
  • It’s the Service Account email, looks like `nnnnnnn-nnnnnnn@developer.gserviceaccount.com` – Michal Migurski Jun 12 '15 at 17:09
  • When using service account you are acting on behalf of someone, so you need to set that somehow – omerio Jun 13 '15 at 10:44
  • Huh, okay. I don’t see anyplace to do that in the API that I’m working with. Since I am attempting to use service accounts to circumvent the need to work on someone’s behalf like with OAuth, maybe this is entirely the wrong path anyway. Thanks for your help! – Michal Migurski Jun 15 '15 at 16:25