0

I've been trying to use a service account in order to obtain google workspace activities via the admin SDK but although the service account is granted an admin role with Reports privilidges I'm receiving the following error -

Access denied. You are not authorized to read activity records. [401] Errors [ Message[Access denied. You are not authorized to read activity records.] Location[Authorization - header] Reason[authError] Domain[global] ]

See the following code snippet -

using Google.Apis.Admin.Reports.reports_v1;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;

var scopes = new[]
{
    ReportsService.ScopeConstants.AdminReportsAuditReadonly,
};
var serviceAccountMail = "<ServiceAccountMail>";
var serviceAccountPrivateKey = "<PrivateKey>";
var serviceAccountCredential = new ServiceAccountCredential(new ServiceAccountCredential.Initializer(serviceAccountMail).FromPrivateKey(serviceAccountPrivateKey)) { Scopes = scopes };
var reportsService = new ReportsService(new BaseClientService.Initializer { HttpClientInitializer = serviceAccountCredential });
var listActivitiesRequest = reportsService.Activities.List("all", ActivitiesResource.ListRequest.ApplicationNameEnum.Token);
var activities = await listActivitiesRequest.ExecuteAsync();

foreach (var activity in activities.Items)
{
    Console.WriteLine(activity);
}

For comparison the following code snippet works as expected with the same setup -

using Google.Apis.Admin.Directory.directory_v1;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;

var scopes = new[]
{
    DirectoryService.ScopeConstants.AdminDirectoryUserReadonly
};

var serviceAccountMail = "<ServiceAccountMail>";
var serviceAccountPrivateKey = "<PrivateKey>";
var serviceAccountCredential =
    new ServiceAccountCredential(
            new ServiceAccountCredential.Initializer(serviceAccountMail).FromPrivateKey(serviceAccountPrivateKey))
        { Scopes = scopes };

var directoryService = new DirectoryService(new BaseClientService.Initializer { HttpClientInitializer = serviceAccountCredential });
var listUsersRequest = directoryService.Users.List();
listUsersRequest.Customer = "<CustomerId>";
var users = await listUsersRequest.ExecuteAsync();

foreach (var user in users.UsersValue)
{
    Console.WriteLine(user);
}

See the following custom admin role assigned to the service account -

enter image description here

  • Is the [Admin SDK API](https://console.cloud.google.com/apis/library/admin.googleapis.com) enabled? Also, have you tried impersonating a Super Admin? Did you set up [domain-wide delegation](https://developers.google.com/workspace/guides/create-credentials#optional_set_up_domain-wide_delegation_for_a_service_account)? – Lorena Gomez Jun 15 '23 at 16:24
  • Admin SDK API enabled. I'm able to make the call using domain-wide delegation and impersonating a Super Admin but have a requirement to avoid domain-wide delegation (I'm aware of the possibility of using OAuth Scopes as permission boundaries). I'm able to call other org units/users/groups methods with this setup so trying to understand why reports behave differently – Alon Shitrit Jun 15 '23 at 16:34
  • When did you assign the roles to the service account? – Lorena Gomez Jun 15 '23 at 16:52
  • A couple of days ago – Alon Shitrit Jun 15 '23 at 17:26
  • if [this](https://stackoverflow.com/a/76492004/19103633) answer actually worked for you (at least for your initial concern), don't forget to either upvote or mark it as 'best answer'. By doing so, other people in the community, who may have the same concern as you, will know that theirs can be resolved. – Milagro Sosa Jun 19 '23 at 15:18

1 Answers1

0

I did some testing with Directory API - Method: users.list and Reports API - Method: activities.list in Python. I was able to list users with the Method: users.list with a service account with the same privileges you mentioned above but had the same issue you mentioned when listing activities with Method: activities.list with the same service account.

I also tested assigning the same privileges to one of my users in my domain and was able to retrieve activities list through the Admin console UI and with the Reports API - Method: activities.list.

I found this thread with a similar issue you're reporting and ended up setting up domain-wide delegation and impersonate a user. I know that some time ago, you always needed to set up domain-wide delegation and impersonate when using a service account, the ability to do this without domain-wide delegation is a recent feature so I think it's worth it reporting this behavior through the issue tracker. In case you open an issue tracker, make sure to share it to raise visibility to your request.

Lorena Gomez
  • 1,946
  • 2
  • 4
  • 11