0

I'm trying to use this API manage company devices in my workspace. 1st step is pulling a list of current devices. Code is in apps script.

I'm getting:

Exception: Request failed for https://cloudidentity.googleapis.com returned code 403. Truncated server response: {
  "error": {
    "code": 403,
    "message": "The caller does not have permission",
    "status": "PERMISSION_DENIED"
  }
}

Things I've done

  1. Service account has domain wide delegation for cloud-platform, cloud-identity and cloud-identity.devices
  2. Auth is done via Google's OAuth library, seems to work fine.
  3. OAuth also has space for scopes, same one's are requested.

Code bits:

    var scriptProperties = PropertiesService.getScriptProperties()
    private_key= scriptProperties.getProperty('private_key').replace(/\\n/g, '\n')
    client_email = scriptProperties.getProperty("client_email")
    ;

    function getOAuthService() {
      return OAuth2.createService('Service Account')
        // Set the endpoint URLs
        .setTokenUrl('https://accounts.google.com/o/oauth2/token')

        // Set the client ID and secret
        .setPrivateKey(private_key)
        .setIssuer(client_email)

        // Set the property store where authorized tokens should be persisted
        .setPropertyStore(PropertiesService.getScriptProperties())
        // .setCache(CacheService.getUserCache())

        .setParam('access_type', 'offline')
        .setScope('https://www.googleapis.com/auth/cloud-identity');
    }

    function reset() {
      var service = getOAuthService();
      service.reset();
    }


    function downloadDevices() {
    var service = getOAuthService();
    service.reset();
      if (service.hasAccess()) {
        var pageToken;
        var URL = "https://cloudidentity.googleapis.com/v1/devices";
        var headers = {
            Authorization: 'Bearer ' + service.getAccessToken()
          };
        var options = {
                method : "GET",
                headers: headers
              };
          var response = UrlFetchApp.fetch(URL, options);
        } else {
        Logger.log('service Error');
        Logger.log(service.getLastError());
      }
    }

By the looks of it everything is fine, it just that I don't have permissions. But as far as I can see there is no more relevant permissions to give.

TheMaster
  • 45,448
  • 6
  • 62
  • 85
Landsil
  • 23
  • 10
  • Are you impersonating the right user? I am just asking because I do not see any impersonation being done in the code. – Fernando Lara Feb 11 '22 at 20:32
  • I'm not impersonating a user at all. This documentation is horrible. Oryginalny I was using general Oauth2 at my credentials as I have access to those actions but in that case Google insisted those scopes don't exist. – Landsil Feb 12 '22 at 09:32
  • `service.reset();` Why are you resetting at ``downloadDevices``? – TheMaster Feb 12 '22 at 13:05
  • Since you are not impersonating a user, I think the problem is that your script may be taking the access from the service account and that is why you get that error. You would need to impersonate a user with enough access like a super admin so it runs correctly. – Fernando Lara Feb 12 '22 at 15:13
  • Re service.reset. it's part of all structure examples. To my understanding it enforces re-auth instead of trying to use expired token. – Landsil Feb 13 '22 at 14:10
  • Re impersonating, this is interesting, I was sure that this isn't how service account is supposed to be used (I know it can with DMW but neither should actually be needed here. I will investigate this angle and be back, I will update code in question if I end up adding it but it still doesn't work. – Landsil Feb 13 '22 at 14:12
  • @FernandoLara I'm 99% sure you are correct. Seems like `.setSubject(user_email)` is required. I'm still testing it but if you post an answer I think I can mark is as a correct solution. – Landsil Feb 15 '22 at 10:34

1 Answers1

0

Based on the code provided I can see that you are probably not doing the user impersonation needed in order to get the correct permissions. Usually when the user impersonation is not done correctly, the system can get the permissions from the service account and since this one does not have super admin permissions, that is why you get the 403 error.

The correct way to go would be to use the service account impersonate a super admin so that you get enough permissions when calling the API.

Fernando Lara
  • 2,263
  • 2
  • 4
  • 14