Automate Temporary Access with PagerDuty Schedules
If you're using PagerDuty, then you already have on-call schedules mapped out for critical roles. But when someone is on-call, they may need more database or server access than they'd otherwise use. This is where strongDM temporary grants come in: you can integrate your PagerDuty on-call schedule with strongDM to automatically grant strongDM users access to additional resources during their on-call shifts. This Python example shows a simple way of managing the process.
The script has two major portions: first, look up who is on call for a specific schedule over a certain time period; second, feed these assignments into the strongDM CLI tool sdm
to grant temporary access to a datasource or server. One wrinkle is that two API calls are necessary to PagerDuty: first, getting the list of who is on call will give a list of users and user IDs, but not email addresses. Second, specific user lookups get us the email addresses of who is on call.
To get this script working in your environment, you'll need the following:
- A strongDM admin token with Datasource list and grant and User assign and list rights
- The strongDM Linux binary either installed or simply copied to the local system
- A PagerDuty API key with read-only rights
- The schedule ID of a PagerDuty schedule you wish to use as the basis of the temporary grants
Add this script to your crontab to run on a regular schedule; modify the UNTIL
calculation to match the interval you're running it at. For instance, if you're running it weekly, that line would look like this:
UNTIL = (datetime.timedelta(days=7) + datetime.datetime.utcnow()).isoformat() + 'Z'
This example script outputs to STDOUT, but you may prefer to have it write to a log file, and record any errors returned by the subprocess.call
function.
Script Listing
#!/usr/bin/env pythonimport requests,json,datetime,subprocess# requires datasource list,grant and user list,assignSDM_ADMIN_TOKEN = 'admin_token_here'SDM_BINARY = '/path/to/sdm'DATASOURCE = 'datasource_or_server_name'API_KEY = 'read_only_PagerDuty_API_key'# for the PD API requests. Modify UNTIL with the proper time offsetTIME_ZONE = 'UTC'SCHEDULE_IDS = ['choose_a_schedule_ID']UNTIL = (datetime.timedelta(days=1) + datetime.datetime.utcnow()).isoformat() + 'Z'def get_oncalls():url = 'https://api.pagerduty.com/oncalls'headers = {'Accept': 'application/vnd.pagerduty+json;version=2','Authorization': 'Token token={token}'.format(token=API_KEY)}payload = {'time_zone': TIME_ZONE,'schedule_ids[]': SCHEDULE_IDS,'until': UNTIL,}r = requests.get(url, headers=headers, params=payload)struct = r.json()output = []for record in struct["oncalls"]:# get user's email addressr = requests.get(record["user"]["self"], headers=headers)output.append({"email" : r.json()["user"]["email"],"from" : record["start"],"to" : record["end"]})return outputdef grant_access(access_list):for item in access_list:print("Granting access to {} to \"{}\" from {} to {}".format(item["email"], DATASOURCE, item["from"], item["to"]))subprocess.call([SDM_BINARY, "--admin-token", SDM_ADMIN_TOKEN,"admin users grant-temporary","--from",item["from"], "--until", item["to"],DATASOURCE, item["email"]])def main():access = get_oncalls()grant_access(access)main()
If you have any questions or problems with this, please reach out to strongDM support.