ZPA API Introduction

,

Introduction

This document provides steps for configuring APIs for ZPA and applying for a variety of use cases. The purpose of this document is to provide an introduction to different methods of making API calls and examples to jump start custom integrations and automate tasks.

This document uses Swagger and Postman as a starting point for validating the API integration and an easy way to convert the API access from Postman to one of many scripting languages. It continues with Python scripts that can be created from Postman. It finishes with using a Software Development Kit (SDK) to use pre-built libraries to simplify the Python scripting and removing the need to build scripts from scratch. Along the way examples are shown with expected results. The reader can utilize any of the methods described to create their own API calls based on their use case.

Please note that the ZPA API is a different configuration than the ZIA API configuration.

This document follows the API documentation provided in the Zscaler ZIA help documentation.

The examples in this document were created with Postman 10.0.15 and Python 3.10.6.

Prerequisites

Postman

  1. Install the Postman application and create an account. Postman can be accessed at Download Postman | Get Started for Free.

Obtain API parameters

There are three values that must be entered into Postman to validate API authorization. These are client ID, client secret, and customer ID. This section will walk through obtaining all three parameters to be used within the Postman, Python scripting, and pyZscaler SDK examples.

  1. Access the ZPA admin portal at https://admin.private.zscaler.com
  2. Access “Administration > Public API > API Keys”

NOTE: If API Keys is not seen, submit a ZPA ticket to provision API access for your ZPA tenant at https://help.zscaler.com/zpa-submit-ticket

  1. Click “Add API Key”

  1. Name the key

  1. Copy the client secret and save it for later use.

Please be sure to copy the key and keep it safe. You will not be able to retrieve it after leaving the page.

  1. Copy the client ID and save it for later use

  1. At the top of the screen, click on Copy Customer ID and save it for later use.

ZPA Postman Configuration

Postman is an API platform for building and using APIs. Postman simplifies each step of the API lifecycle and streamlines collaboration so you can create better APIs faster. Zscaler provides step by step instructions on setting up Postman with ZPA and the full JSON/Postman collection scripts for existing API calls. This significantly eases the ability to create API scripts for automation and integration. This document follows and augments that documentation. A link to the Zscaler ZPA API Postman documentation is linked below.

Create a Workspace

Postman workspaces provide an area for common configuration. For example, we can create a workspace for all Zscaler related configurations. This includes ZIA, ZPA, and ZDX.

  1. Click on Workspaces and create a new Workspace called Zscaler

Create an Environment

Within the Workspace, environments provide a space to save the variables associated with a particular application. This provides the benefit of having a centralized location for storing tokens, credentials, and URLs so that values can be reused across multiple ZPA API calls. If there is a change to a common variable the change can be made once to the environment for the benefit of all ZPA API calls that use the variable as part of the Postman ZPA script. In our case we will be creating an environment for all ZPA related variables.

  1. Click on the Environment tab. Click the + sign to create a new environment

  1. Click the … to the right of the environment and rename the environment ZPA

Create baseURL Variable

  1. Add a new variable called baseUrl with value https://config.private.zscaler.com

Create the customerId, clientId, and clientSecret Variables

  1. In Postman, create new environment variables called customerId, clientId, clientSecret using variable values obtained from the Obtain API parameters section above.

Create Collection

Collections provide the API calls that are imported into Postman and stored within the Workspace. Zscaler provides the APIs to import into Postman

  1. Access the ZPA API Portal at Zscaler Private Access API Portal. This URL can also be accessed from the ZPA Admin Portal at Administration > Public API > API Keys. At the top right corner is a link to the Swagger API Portal.

  1. Login with the client ID and client secret that were created in the Obtain API parameters section above.

  2. Click on the link below “Zscaler Private Access API Portal” to view a plain text format for APIs related to management configuration. The link for the URL should be https://config.private.zscaler.com/v2/customSwagger?tag=mgmtconfig

  1. Copy the full plain text

  1. Open Postman
  2. Navigate to your Zscaler Workspace
  3. Click on Import

  1. click the “Raw text” option and paste the API information

  1. A new directory is now created under API

  1. Expand Zscaler Private Access API Portal, right click on Zscaler Private Access API Portal, and click on Copy to Workspace

  1. A new Collection should now be seen under Collections.

  1. New APIs should be added under “APIs”

  1. Zscaler has separated out the User APIs from the management APIs. For the user APIs, access the Swagger UI at https://config.private.zscaler.com, login, and on the far right click the drop down and choose the USER MGMT definition.

  1. Click on the URL below Zscaler Private Access API Portal. This should be https://config.private.zscaler.com/v2/customSwagger?tag=userconfig

  1. Copy the plain text API listing and import into Postman using the same steps 6 - 14 above.

Create Login

You must create an authenticated session to run the API commands. With ZPA the authentication creates a bearer token that must be presented in any subsequent API requests as authorization. The steps in the section explain how to authenticate and generate the bearer token.

Set Environment

  1. Access Postman
  2. Select the ZPA environment created earlier on the top right

Create Login Request

  1. Right click the Zscaler Private Access API Portal collection and click Add Folder. Either of the mgmt or user collection can be used.
  2. Rename the folder “Login Tokens”

  1. Right click on “Login Tokens” and click “Add Request”

  1. Rename the request “Login”
  2. Click Login

  1. Click the request type drop down menu and select Post
  2. Enter the URL {{baseUrl}}/signin
  3. Click Body and then click x-www-form-urlencoded
  4. Under KEY field, enter client_id
  5. Under VALUE field, enter the client id variable created in the Environment called {{clientId}}
  6. Create a new KEY field, and enter client_secret
  7. Under VALUE field, enter the client secret variable created in the Environment called {{clientSecret}}

  1. Click “Send”. The result should be similar to below. The access token is required to be added to the Authorization tab for subsequent API requests. Copy the “access token” to be used as the bearer token for subsequent API requests. Keep in mind that the access token is only valid for a limited amount of time defined in ZPA. By default this is 60 minutes.

Example: Get All Application Segments

Use the steps below as an example of creating an API request

  1. Access Postman
  2. Click on the Login request created above
  3. Click Send

  1. Copy the access token value.
  2. Navigate in the Collection tree to Zscaler Private Access AP Portal > mgmtconfig > v1/admin > customer/{customer Id} > segment Group > Get all the configured Segment Groups

  1. Click the Authorization tab (This shows up as Auth if the screen is too narrow)
  2. Change the Type to Bearer Token and paste the access token from above

  1. Click the Params tab and make sure search is unchecked and the customerId variable value has {{customerId}} as the variable.

  1. Click Send. Results should be similar to below.

ZPA Python Scripts

Python scripts provide a way to include multiple API calls to add more customization and automation to the individual API calls shown with Postman. One way to utilize the APIs is to utilize Postman to create Python script snippets to add into a more comprehensive script to accomplish use cases. The section below provides additional details to get started with creating scripts.

Authentication Best Practices

The initial authentication request requires sensitive username, password, and API key credentials. This information should be protected as much as possible. With this in mind, the following three methods can be used in order of best to worst options. Environment variables should be used whenever possible. The second two options should only be used if the environment variables method cannot be used.

In each method the following information must be provided

  1. Client id
  2. Client secret
  3. Customer id

Authentication Method 1: Environment Variables (Preferred Method)

This is the most secure method of storing sensitive information. For Linux systems the commands below would be added to the .zshrc or .bashrc file depending on which shell is being used. To reapply the file to the current shell, enter “. ./.zshrc”

For Linux systems this would look similar to the following

export ZPA_CLIENT_ID=”Mjdksdflksjkdfsfds”
export ZPA_CLIENT_SECRET=”HBRMdddsdfs”
export ZPA_CUSTOMER_ID=”2324242343”

For Windows systems this would look similar to the following

$env:ZPA_CLIENT_ID=”Mjdksdflksjkdfsfds”
$env:ZPA_CLIENT_SECRET=”HBRMdddsdfs”
$env:ZPA_CUSTOMER_ID=”2324242343”

Once the parameters are within the environment variables it is just a matter of importing them into the python script. This example shows it can be done. It shows how environment variables can be saved to python variables that can be used within a script.

Script

import os
 
# Get all environment variables
print ("----------------------------------------------------------------")
print (os.environ)
print ("----------------------------------------------------------------")
 
# method that does not create error message if variable does not exist
zpa_client_id=os.environ.get('ZPA_CLIENT_ID')
 
print(zpa_client_id)
print ("----------------------------------------------------------------")

Script Output

rchee@Robs-MacBook-Pro-2 ZPA API % python3 os.pl
----------------------------------------------------------------
environ({'__CFBundleIdentifier': 'com.apple.Terminal', 'TMPDIR': '/var/folders/nf/0fhd08w92bgfng9_fgr3y_040000gn/T/', 'XPC_FLAGS': '0x0', 'TERM': 'xterm-256color', 'SSH_AUTH_SOCK': '/private/tmp/com.apple.launchd.xDJvlGFAEf/Listeners', 'XPC_SERVICE_NAME': '0', 'TERM_PROGRAM': 'Apple_Terminal', 'TERM_PROGRAM_VERSION': '445', 'TERM_SESSION_ID': 'B533916F-3C3D-45AF-8377-08D260176969', 'SHELL': '/bin/zsh', 'HOME': '/Users/rchee', 'LOGNAME': 'rchee', 'USER': 'rchee', 'PATH': '/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/MacGPG2/bin', 'SHLVL': '1', 'PWD': '/Users/rchee/Documents/ZPA API', 'OLDPWD': '/Users/rchee/Documents', 'HOMEBREW_PREFIX': '/opt/homebrew', 'HOMEBREW_CELLAR': '/opt/homebrew/Cellar', 'HOMEBREW_REPOSITORY': '/opt/homebrew', 'MANPATH': '/opt/homebrew/share/man::', 'INFOPATH': '/opt/homebrew/share/info:', 'ZIA_USERNAME': 'api@azuretwo.cheeworld.com', 'ZIA_PASSWORD': '3yw6ioQ*sS$I', 'ZIA_API_KEY': '475RVV2XwtvX', 'ZIA_CLOUD': 'zscalertwo', 'ZPA_CLIENT_ID': 'Mjg4MjU4NjMyNzQxNTUyMjI1LTkxMTQyMWU1LWEzNDAtNDc0OC1hMDc3LTU0M2MzNTZiMDI1Ng==', 'ZPA_CLIENT_SECRET': "-0mf|.D-r}R3-V537X-uI6<'7(:eCUmt", 'ZPA_CUSTOMER_ID': '288258632741552128', 'LANG': 'en_US.UTF-8', '_': '/opt/homebrew/bin/python3', '__CF_USER_TEXT_ENCODING': '0x1F5:0x0:0x0'})
----------------------------------------------------------------
Mjg4MjU4NjMyNzQxNTUyMjI1LTkxMTQyMWU1LWEzNDAtNDc0OC1hMDc3LTU0M2MzNTZiMDI1Ng==
----------------------------------------------------------------

Authentication Method 2: Static Credentials

In this method, the parameters are hard coded in a configuration file.

Authentication Method 3: JSON Configuration File

In this method, the parameters are housed in a JSON configuration file that is in a safe location that is referenced by the Python script.

Authentication Script Snippet

Use the following steps to create a python script from the Postman authentication request. This script will be used at the beginning of all Python scripts to complete the authentication and create the BEARER TOKEN that will be used for API calls.

  1. Open Postman and navigate to the Login request created Login Section above.

  1. On the right side click on </> and view the Python code associated with the Login. Click on the copy icon to copy the code and paste into an editor.

  1. Create a script similar to below.

Script

import requests
import json
import time
import http.client
import os
 
if os.environ.get('ZPA_CLIENT_ID') is not None:
  zpa_client_id = os.environ.get('ZPA_CLIENT_ID')
else:
    print("ZPA_CLIENT_ID environment variable does not exist. Please create it.")
    sys.exit(1)
 
if os.environ.get('ZPA_CLIENT_SECRET') is not None:
    zpa_client_secret = os.environ.get('ZPA_CLIENT_SECRET')
else:
    print("ZPA_CLIENT_SECRET environment variable does not exist. Please create it.")
    sys.exit(1)
 
if os.environ.get('ZPA_CUSTOMER_ID') is not None:
    zpa_customer_id = os.environ.get('ZPA_CUSTOMER_ID')
else:
    print("ZPA_CUSTOMER_ID environment variable does not exist. Please create it.")
    sys.exit(1) 
 
url = "https://config.private.zscaler.com/signin"
 
payload='client_id=' + zpa_client_id + '&client_secret=' + zpa_client_secret
headers = {
  'Content-Type': 'application/x-www-form-urlencoded',
}
 
#  'Cookie': ''
response = requests.request("POST", url, headers=headers, data=payload)
 
response_json = response.json()
#print(response.text)
 
for key in response_json:
  if key=="access_token":
    print (key,":",response_json[key])

Script Output

rchee@Robs-MacBook-Pro-2 ZPA API % python3 zpa-api-auth.pl
access_token : eyJraWQiOiI0bzZFS1k4STFqS1kwN2tQdjlqWV9xd3AyYmt4eTd2Y1V1WGhUSGJBazgwIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiJNamc0TWpVNE5qTXlOelF4TlRVeU1qSTFMVGt4TVRReU1XVTFMV0V6TkRBdE5EYzBPQzFoTURjM0xUVTBNMk16TlRaaU1ESTFOZz09IiwiYXVkIjoiaHR0cHM6XC9cL2F1dGh6MS5wcm9kLnpwYXRoLm5ldCIsInJlc3RyaWN0ZWRSb2xlIjpmYWxzZSwicm9sZUlkIjoyOCwiY3VzdElkIjoiMjg4MjU4NjMyNzQxNTUyMTI4IiwiaXNzIjoiaHR0cHM6XC9cL3VzMS16cGEtYXV0aG4ucHJpdmF0ZS56c2NhbGVyLmNvbSIsInR5cGUiOiJDTElFTlRfQ1JFREVOVElBTFMiLCJleHAiOjE2NjYwNDk0NzIsImlhdCI6MTY2NjA0NTg3MiwianRpIjoiMWpiNzJlYjdna2RjMHpuaDFoYWR0cnR6bCJ9.xLbhs5gOgUstqN8B4DUlBQ0a9vg-xmILFKAVxigTvdZqzLpLrQXey2ppWtVO2Vyl49AaD7i-1uV3QIEHhrsdROu6Xq36Na0Nl2aSRnnBD9r73xne9nZhMXjuuxAFTcc1nFExEV7LMmdF5ycZnb_pWVt77TNiGBzZCzHZI_CDcw1DBNXjz6XB082cm9KjJBGoJgwO_gtKbLzT5cWhny0G5oOsjjeD0pqiAGpLImXVUFpNYlNXd7wbzgJN33qBlxPth11UWEZIgDgRpIiq9uu6lg95j56nY_MgqMy_3ppDMYIG5YpU4Z-Sv43f-CWdzQ6Eb4rIRBwJiR64sbxjbdKW1w

Example: Get All App Segments

This example uses the same steps in the Postman example above and takes the output to create the Python script. This script will use Postman as the basis and the authentication script snippet above to get the BEARER TOKEN. This script also requires the CUSTOMER ID which is stored as an environment variable.

Steps

  1. Follow the steps in the ZPA Postman Configuration > Example: Get All App Segments section to run the Postman script
  2. Start a Python script with the Authentication script snippet above as the first part of the script.
  3. Click on the </> in the Postman script and paste below the authentication script snippet.

  1. The end result should look similar to below. The assumption is that the client ID, client secret, and customer ID are provided as environment variables. Notice that the customerId must be added to the URL. This is shown in bold in the script below.
import requests
import json
import time
import http.client
import os
 
if os.environ.get('ZPA_CLIENT_ID') is not None:
  zpa_client_id = os.environ.get('ZPA_CLIENT_ID')
else:
    print("ZPA_CLIENT_ID environment variable does not exist. Please create it.")
    sys.exit(1)
 
if os.environ.get('ZPA_CLIENT_SECRET') is not None:
    zpa_client_secret = os.environ.get('ZPA_CLIENT_SECRET')
else:
    print("ZPA_CLIENT_SECRET environment variable does not exist. Please create it.")
    sys.exit(1)
 
if os.environ.get('ZPA_CUSTOMER_ID') is not None:
    zpa_customer_id = os.environ.get('ZPA_CUSTOMER_ID')
else:
    print("ZPA_CUSTOMER_ID environment variable does not exist. Please create it.")
    sys.exit(1)
 
######################################################################
# Authentication
######################################################################
url = "https://config.private.zscaler.com/signin"
 
payload='client_id=' + zpa_client_id + '&client_secret=' + zpa_client_secret
headers = {
  'Content-Type': 'application/x-www-form-urlencoded',
}
 
#  'Cookie': ''
response = requests.request("POST", url, headers=headers, data=payload)
 
response_json = response.json()
#print(response.text)
 
for key in response_json:
  if key=="access_token":
    #print (key,":",response_json[key])
    bearer_token = response_json[key]
 
###############################################
 
url = "https://config.private.zscaler.com/mgmtconfig/v1/admin/customers/" + zpa_customer_id + "/application?page=1&pagesize=20&search="
 
payload={}
headers = {
  'Accept': '*/*',
  'Authorization': 'Bearer ' + bearer_token 
}
 
response = requests.request("GET", url, headers=headers, data=payload)
response_json = response.json()
print(response.text)

Script Output (truncated)

{“totalPages”:“1”,“list”:[{“modifiedTime”:“1661378206”,“creationTime”:“1660874595”,“modifiedBy”:“288258632741552129”,“id”:“288258632741552164”,“domainNames”:[“10.0.0.2”,“dvwa.azuretwo.cheeworld.com”],“name”:“DVWA App Segment”,“serverGroups”:[{“id”:“288258632741552159”,“modifiedTime”:“1660943069”,“creationTime”:“1660702637”,“modifiedBy”:“288258632741552129”,“name”:“Skytap Server Group”,“enabled”:true,“configSpace”:“DEFAULT”,“dynamicDiscovery”:false}],“enabled”:true,“passiveHealthEnabled”:true,“tcpPortRanges”:[“8000”,“8000”],“tcpPortRange”:[{“from”:“8000”,“to”:“8000”}],“doubleEncrypt”:false,“configSpace”:“DEFAULT”,“bypassType”:“NEVER”,“healthCheckType”:“DEFAULT”,“icmpAccessType”:“NONE”,“isCnameEnabled”:true,“clientlessApps”:[{“id”:“288258632741552179”,“name”:“dvwa.azuretwo.cheeworld.com”,“enabled”:true,“certificateId”:“288258632741552163”,“certificateName”:“Wildcart Cert”,“applicationPort”:“8000”,“applicationProtocol”:“HTTP”,“domain”:“dvwa.azuretwo.cheeworld.com”,“appId”:“288258632741552164”,“path”:“/”,“hidden”:false,“portal”:false,“trustUntrustedCert”:false,“allowOptions”:false,“cname”:“17850.288258632741552128.h.p.zpa-app.net”}],“inspectionApps”:[{“id”:“288258632741552219”,“name”:“dvwa.azuretwo.cheeworld.com”,“enabled”:true,“applicationPort”:“8000”,“applicationProtocol”:“HTTP”,“domain”:“dvwa.azuretwo.cheeworld.com”,“appId”:“288258632741552164”,“trustUntrustedCert”:true}],“ipAnchored”:false,“healthReporting”:“ON_ACCESS”,“tcpKeepAlive”:“0”,“selectConnectorCloseToApp”:false,“segmentGroupId”:“288258632741552132”,“segmentGroupName”:“Internal Application Group”},{“modifiedTime”:“1661039978”,“creationTime”:“1660875488”,“modifiedBy”:“288258632741552129”,“id”:“288258632741552167”,“domainNames”:[“gitlab.azuretwo.cheeworld.com”,“10.0.0.2”],“name”:“Gitlab”,“serverGroups”:[{“id”:“288258632741552159”,“modifiedTime”:“1660943069”,“creationTime”:“1660702637”,“modifiedBy”:“288258632741552129”,“name”:"Skytap Server

truncated…

ZPA pyZscaler Software Development Kit (SDK)

Software Development Kits (SDK) are the best way to create scalable scripts as complexity increases. There are a number of unofficial SDKs that can be used to allow easier development of scripts to address ZIA API use cases. This section utilizes pyZscaler Python SDK. pyZscaler is an SDK that provides a uniform and easy-to-use interface for each of the Zscaler product APIs. One nice feature the use of Python Box . Box is designed to be an easy drop in as a transparent replacement for dictionaries that adds dot notation access and a load of other features. Keep in mind that the pyZscaler SDK is not a Zscaler supported SDK since there are currently no Zscaler supported SDKs, but this SDK is the most full featured and well documented. It is also unofficially supported by a Zscaler engineer, Mitch Kelly.

The Zscaler APIs expect and return JSON structures with key names in CamelCase. This violates PEP-8 and results in code that’s hard to read. pyZscaler will seamlessly convert to PEP-8 compliant Snake Case so that your code can remain readable and beautiful. Refer to the pyZscaler Library Documentation at ReadTheDocs to ensure that you are passing correctly named parameters to the class methods.

Create Scripts

The methods are well defined in the pyZscaler library. They each simplify the creation by incorporating many of the steps into the method to eliminate as much additional code as possible and implement error checking.

The prerequisite for running pyZscaler is to have Python 3.7+ installed with pip3 installed as well.

The pyZscaler SDK is installed using “pip3 install pyzscaler”. When creating the Python script, you must import the module using “from pyzscaler.zia import ZIA” at the top of the script. Notice that the top portion is the same Python code to obtain the sensitive information from the environment variables.

With this in mind, the following steps can be taken to utilize a method.

  1. Access ZIA
  2. View the methods available

  1. Click on a method to implement. List App Segments is chosen in the screenshot below

  1. Validate the required parameters
  2. Use the examples provided at the bottom of the method description to show the correct syntax
  3. Create the script. The examples in the section below provide a good representation of what can be done.

Example: Get All App Segments

This example uses the pyZscaler SDK to obtain the current App Segments associated with a tenant. This is the same example used in the Postman and Python examples above. This assumes that the pyZscaler SDK has been installed using “pip3 install pyzscaler”. Notice that the top portion is the same Python code to obtain the sensitive information from the environment variables. Only the short bottom part is the pyZscaler portion.

Script

import requests
import os
from pyzscaler.zpa import ZPA
from pprint import pprint
 
########################################
# Get environment variables
########################################
if os.environ.get('ZPA_CLIENT_ID') is not None:
  zpa_client_id = os.environ.get('ZPA_CLIENT_ID')
else:
    print("ZPA_CLIENT_ID environment variable does not exist. Please create it.")
    sys.exit(1)
 
if os.environ.get('ZPA_CLIENT_SECRET') is not None:
    zpa_client_secret = os.environ.get('ZPA_CLIENT_SECRET')
else:
    print("ZPA_CLIENT_SECRET environment variable does not exist. Please create it.")
    sys.exit(1)
 
if os.environ.get('ZPA_CUSTOMER_ID') is not None:
    zpa_customer_id = os.environ.get('ZPA_CUSTOMER_ID')
else:
    print("ZIA_API_KEY environment variable does not exist. Please create it.")
    sys.exit(1)
########################################
 
zpa = ZPA(client_id=zpa_client_id, client_secret=zpa_client_secret, customer_id=zpa_customer_id)
 
for app_segment in zpa.app_segments.list_segments():
  # To show raw data
  # pprint(app_segment) 
 
  # To show nicely formatted parameters of app segments
  for k in app_segment:
    print(k,":",app_segment[k])
  print("-----------------------------") 
 
  # To print just the app segment name
  #for k in app_segment:
  #  if k=="name":
  #    print(k,":",app_segment[k])
  #print("-----------------------------")

Script Output

rchee@Robs-MacBook-Pro-2 pyZscaler % python3 zpa-list-app-segments.pl
modified_time : 1661378206
creation_time : 1660874595
modified_by : 288258632741552129
id : 288258632741552164
domain_names : ['10.0.0.2', 'dvwa.azuretwo.cheeworld.com']
name : DVWA App Segment
server_groups : [{'id': '288258632741552159', 'modified_time': '1660943069', 'creation_time': '1660702637', 'modified_by': '288258632741552129', 'name': 'Skytap Server Group', 'enabled': True, 'config_space': 'DEFAULT', 'dynamic_discovery': False}]
enabled : True
passive_health_enabled : True
tcp_port_ranges : ['8000', '8000']
tcp_port_range : [{'from': '8000', 'to': '8000'}]
double_encrypt : False
config_space : DEFAULT
bypass_type : NEVER
health_check_type : DEFAULT
icmp_access_type : NONE
is_cname_enabled : True
clientless_apps : [{'id': '288258632741552179', 'name': 'dvwa.azuretwo.cheeworld.com', 'enabled': True, 'certificate_id': '288258632741552163', 'certificate_name': 'Wildcart Cert', 'application_port': '8000', 'application_protocol': 'HTTP', 'domain': 'dvwa.azuretwo.cheeworld.com', 'app_id': '288258632741552164', 'path': '/', 'hidden': False, 'portal': False, 'trust_untrusted_cert': False, 'allow_options': False, 'cname': '17850.288258632741552128.h.p.zpa-app.net'}]
inspection_apps : [{'id': '288258632741552219', 'name': 'dvwa.azuretwo.cheeworld.com', 'enabled': True, 'application_port': '8000', 'application_protocol': 'HTTP', 'domain': 'dvwa.azuretwo.cheeworld.com', 'app_id': '288258632741552164', 'trust_untrusted_cert': True}]
ip_anchored : False
health_reporting : ON_ACCESS
tcp_keep_alive : 0
select_connector_close_to_app : False
segment_group_id : 288258632741552132
segment_group_name : Internal Application Group
-----------------------------
modified_time : 1661039978
creation_time : 1660875488
modified_by : 288258632741552129
id : 288258632741552167
domain_names : ['gitlab.azuretwo.cheeworld.com', '10.0.0.2']
name : Gitlab
server_groups : [{'id': '288258632741552159', 'modified_time': '1660943069', 'creation_time': '1660702637', 'modified_by': '288258632741552129', 'name': 'Skytap Server Group', 'enabled': True, 'config_space': 'DEFAULT', 'dynamic_discovery': False}]
enabled : True
passive_health_enabled : True
tcp_port_ranges : ['8003', '8003']
tcp_port_range : [{'from': '8003', 'to': '8003'}]
double_encrypt : False
config_space : DEFAULT
bypass_type : NEVER
health_check_type : DEFAULT
icmp_access_type : NONE
is_cname_enabled : True
clientless_apps : [{'id': '288258632741552183', 'name': 'gitlab.azuretwo.cheeworld.com', 'enabled': True, 'certificate_id': '288258632741552163', 'certificate_name': 'Wildcart Cert', 'application_port': '8003', 'application_protocol': 'HTTP', 'domain': 'gitlab.azuretwo.cheeworld.com', 'app_id': '288258632741552167', 'hidden': False, 'portal': False, 'trust_untrusted_cert': False, 'allow_options': False, 'cname': '17989.288258632741552128.h.p.zpa-app.net'}]
ip_anchored : False
health_reporting : ON_ACCESS
tcp_keep_alive : 0
select_connector_close_to_app : False
segment_group_id : 288258632741552132
segment_group_name : Internal Application Group
-----------------------------

Summary

This guide provided an introduction on how to use APIs with Zscaler ZPA. Postman was used as a low barrier to entry method of running the APIs and seeing the results within an easy to use framework. For organizations looking to meet automation and integration requirements, it was shown how to take the Postman API calls and create Python snippets that can be incorporated into larger, more comprehensive Python scripts. Finally, the use of the pyZscaler SDK was introduced as means of creating Python scripts in a simplified manner that also improved security by using a best practices methodology for direct API calls.

Organizations can use this guide as a first step towards automation, orchestration, and integration goals with Zscaler Private Access (ZPA). The example scripts provide a good starting point for creating custom scripts to meet business and technical requirements. As sophistication grows, organizations may also be interested in how to use Terraform to automate and orchestrate the ZPA configuration. This will be explored in a future guide.

References

Documentation References

ZPA API

Integrated Development Environments (IDEs)

PyCharm

ZPA Examples

Mark Ryan’s Github repository

Youtube Video

pyZscaler SDK

Library Reference

User Documentation

Github Repository

Videos

ZPA Terraform provider Video Series Ep1

Terraform

Terraform Github Information

Blogs and Articles

ZPA API Resource Roundup

ZPA Service Now Integration Example

4 Likes