1
votes

I'm trying to use a Service Account to access data of a domain that's installed my app (via Google Apps Marketplace).

But calls to the Google Admin SDK api, to get lists of users or lists of admins for a given domain, seem to require that you know the email address of a user in the domain.

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

  HttpTransport httpTransport = new NetHttpTransport();
  JacksonFactory jsonFactory = new JacksonFactory();
  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();
  Directory service = new Directory.Builder(httpTransport, jsonFactory, null)
  .setHttpRequestInitializer(credential).build();

  Directory.Users.List request = service.users().list().setDomain(domain);

The above works, but requires that you called the setServiceAccountUser(userEmail) method on the builder. Without that, when you execute the request, you'll get a 403 "not authorized for this resource/api error". This is documented by several existing questions, such as Google Apps Admin API: need to specify account user for service account? .

But how do you know a userEmail in the first place? You can't get a list of emails in the domain without already knowing an email in the domain. You could store the email of the admin who first installs the app - but this seems improper and is insufficient. What if this admin's account is deleted or the email address changes?

1

1 Answers

2
votes

Service accounts cannot be granted admin rights on the domain; they must impersonate a domain admin, hence the need for an email address. The recommended approach is to store the email of the admin that installed the app, or have a configuration screen where they can set the email of the admin account to use. As you've pointed out this approach can be a little fragile, if the admin account is deleted or it's email changes. Make sure you handle that case, by disabling the app and alerting the user that an admin must re-configure it.