1

I'm trying to create a user using Googles Directory API and a service account. However I'm getting the error

googleapiclient.errors.HttpError: <HttpError 403 when requesting https://admin.googleapis.com/admin/directory/v1/users?alt=json returned "Not Authorized to access this resource/api". Details: "Not Authorized to access this resource/api">

I've created a service account on the Google Console and allowed Domain wide delegation. It also says the Admin SDK API is enabled for my project. However I can't seem to create a user. The documentation is confusing me slightly. Here is my implementation

def create_googleuser(content, randpass):
    ''' This function creates a Google Apps account for a user passing webhook contents and password as arguments '''
    
    # Get User info from Webhook and store them in variables
    firstname = get_firstname(content)
    secondname = get_secondname(content)
    emailaddress = firstname + "." + secondname + "@example.com"
    
    # Connect to google API
    userscope = ['https://www.googleapis.com/auth/admin.directory.user']
    service_account_credentials = ('serviceaccountcredentials.json')
    credentials = service_account.Credentials.from_service_account_file(service_account_credentials, scopes=userscope)
    
    userservice = googleapiclient.discovery.build('admin', 'directory_v1', credentials=credentials)


    # Create a user dictionary with user details
    userinfo = {"primaryEmail": emailaddress,"name":{"givenName":firstname,"familyName":secondname},"password":randpass}
    print (emailaddress)

    # Create user through googleAPI    
    userservice.users().insert(body = userinfo).execute()

I'm thinking that my implementation is wrong rather than the permissions as the serviceaccountcredentials.json should have the correct permissions. Any suggestions?

new name
  • 15,861
  • 19
  • 68
  • 114
mactire
  • 333
  • 3
  • 7
  • For domain wide delegation, you mention you completed GCP part, what about the part for [admin console](https://developers.google.com/admin-sdk/reports/v1/guides/delegation)? – dany L Jul 23 '21 at 14:18
  • Yep. On the admin security panel, I see the correct client ID for that service account under API controls and I can also see the scopes which it has access to. So that part looks fine, good suggestion though – mactire Jul 23 '21 at 15:49
  • The error suggests that the credentialed account does **not** have sufficient permissions. Do you have access to an Administrator account that you can authenticate with instead of the Service Account? That would eliminate your code as the issue and confirm that the Service Account is either incorrectly configured or has insufficient permissions. – DazWilkin Jul 23 '21 at 16:01
  • 2
    Your code is not using impersonation/delegation: `credentials = credentials.with_subject(USER_ACCOUNT_EMAIL)` – John Hanley Jul 23 '21 at 18:22
  • Does this answer your question? [Google Admin SDK authentication with service account](https://stackoverflow.com/questions/60078324/google-admin-sdk-authentication-with-service-account) – Iamblichus Jul 27 '21 at 11:58

2 Answers2

1

There are two possibilities for getting this error.

  1. If the API method requires an impersonated user to be used.

  2. If the impersonated user has not the relevant service enabled.

Solution for case 1:
Follow the documentation to impersonate a user account.

Solution for case 2:
In the Admin console, open user information and check that the user is not suspended.

Open the "Apps" panel and check that the relevant service is "On".

May be caused by a user not having a license which allows access to the service (Cloud Identity instead of Google Workspace), or a user being in an organizational unit which has the service disabled.

Also this link might be helpful.

1

Thanks for the input. You were both correct to a point. Basically there were two issues. The service account user needs to be delegated domain administrator privileges that require domain admin actions, domain wide delegation isn't enough. Also the domain scope needed to be broader in the Admin console and the scope definition within the code. There is github issue open which helped here:

https://github.com/googleapis/google-api-nodejs-client/issues/1884

My working code looks like this

def create_googleuser(content, randpass):
    ''' This function creates a Google Apps account for a user passing webhook contents and password as arguments '''
    
    # Get User info from Webhook and store them in variables
    username = get_username(content)
    firstname = get_firstname(content)
    secondname = get_secondname(content)
    emailaddress = firstname + "." + secondname + "@example.com"
    
    # Connect to google API
    userscope = ['https://www.googleapis.com/auth/admin.directory.user', 'https://www.googleapis.com/auth/admin.directory.user.security']
    service_account_credentials = ('serviceaccountcredentials.json')

    credentials = service_account.Credentials.from_service_account_file(service_account_credentials, scopes=userscope)
    delegated_credentials = credentials.with_subject('domain.admin@example.com')

    userservice = googleapiclient.discovery.build('admin', 'directory_v1', credentials=delegated_credentials)


    # Create a user dictionary with user details
    userinfo = {"primaryEmail": emailaddress,"name":{"givenName":firstname,"familyName":secondname},"password":randpass}

    # Create user through googleAPI
    userservice.users().insert(body = userinfo).execute()
mactire
  • 333
  • 3
  • 7