Skip to content

Instantly share code, notes, and snippets.

@jay0lee
Created December 14, 2022 20:00
Show Gist options
  • Save jay0lee/656d1a755b69984a2f849de59f252171 to your computer and use it in GitHub Desktop.
Save jay0lee/656d1a755b69984a2f849de59f252171 to your computer and use it in GitHub Desktop.
PoC script to create a new Workspace user using a GCP service account
#!/usr/bin/env python3
### This script requires a service account private key JSON credentials file.
### The service account should be granted an admin role in your domain that
### authorizes it to create users. See:
###
### https://support.google.com/a/answer/9807615?hl=en&ref_topic=9832445&fl=1#zippy=%2Cassign-a-role-to-a-service-account
###
### This script requires PyJWT and requests. Install it by running:
###
### pip3 install PyJWT
### pip3 install requests
###
### Example usage on Linux with curl to call Admin SDK Directory API users.create()
###
### python3 ~/create-user.py \
### --file ./service-account-private-key.json \
### --user-email newuser@example.com \
### --firstname New \
### --lastname User \
### --password p@ssw3rd
###
import argparse
import http.client
import json
import os
import sys
import time
import jwt
import requests
parser = argparse.ArgumentParser(description='Create a Google user using service account JWT auth')
parser.add_argument('--file',
help='Service account private key credential file.',
required=True,
dest='cred_file')
parser.add_argument('--user-email',
required=True,
help='Email address for new Google Workspace / Cloud Identity user.',
dest='useremail')
parser.add_argument('--firstname',
required=True,
help='First name / given name for new user.',
dest='firstname')
parser.add_argument('--lastname',
required=True,
help='Last name / family name for new user.',
dest='lastname')
parser.add_argument('--password',
required=True,
help='Password for new user. Must be at least 8 characters and meet admin console password requirements.',
dest='password')
parser.add_argument('--debug',
action='store_true',
help='Enable verbose debugging of JWT token and HTTP request.',
dest='debug')
args = parser.parse_args()
# read the service account private key file downloaded from GCP console service account keys.
# https://cloud.google.com/iam/docs/creating-managing-service-account-keys
if not os.path.isfile(args.cred_file):
print(f'ERROR: {args.cred_file} does not exist')
sys.exit(1)
with open(args.cred_file, 'r') as f:
try:
sa_info = json.load(f)
except json.JSONDecodeError:
print(f'ERROR: {args.cred_file} is not valid JSON. This doesn\'t look like a service account private key file.')
sys.exit(1)
if not 'private_key' in sa_info:
print(f'ERROR: no private_key in {args.cred_file}. This doesn\'t look like a service account private key file.')
sys.exit(1)
# Enable HTTP debugging if --debug is supplied
if args.debug:
http.client.HTTPConnection.debuglevel = 1
# formulate the JWT we'll use as an auth header
# https://developers.google.com/identity/protocols/oauth2/service-account#jwt-auth
iat = int(time.time())
exp = iat + 3600
payload = {'iss': sa_info['client_email'],
'aud': 'https://admin.googleapis.com/',
'iat': iat,
'exp': exp,
'sub': sa_info['client_email']}
headers = {'kid': sa_info['private_key_id']}
# sign our JWT with our service account private key
signed_jwt = jwt.encode(payload,
sa_info['private_key'],
headers=headers,
algorithm='RS256')
# call our API to create a user
url = 'https://admin.googleapis.com/admin/directory/v1/users'
headers = {'Authorization': f'Bearer {signed_jwt}'}
body = {'primaryEmail': args.useremail,
'password': args.password,
'name': {
'givenName': args.firstname,
'familyName': args.lastname,
},
}
r = requests.post(url,
headers=headers,
json=body)
# Dump the JSON data for the new user
print(json.dumps(r.json(),
indent=4,
sort_keys=True))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment