Introduction
The Uptycs API, based on REST principles, allows you to do most everything you can do in the API. The API requires an authorization header, which includes a using a JSON Web Token (JWT), is created with your key, secret, and customer ID.
Uptycs uses standard response codes as follows:
The resultant JSON will also show the error.
Each method for querying the APi requires that you first generate an API key and know your customer ID.
Go to your environment’s page, click configuration
In that page, click Users
Find your User and click Edit. If the Edit button is not available, request admin permissions.
Under Use API Key, hit create.
Download the file, by clicking on the Download button on the bottom right.
Find your key, secret, and customerId in the downloaded json file. The default filename is userid_apikey.json
Example of a downloaded file
One of the methods to access the API with is Postman.
To use Postman, you'll need your customerId, key, and secret. Obtain these by following the instructions in the prior sections called "Generating API Key + Customer ID"
Go to your environment’s page, click Software Downloads
Scroll down (to the bottom of the page) until you see Postman Collection
Click “here” to download the postman collection
Once downloaded, go to Postman and select File > Import…
Click Upload File, select the downloaded Postman Collection File, and click Import
Now that this is imported, go to Environments > Globals.
Copy the values for domain, key, secret, and customerId into Postman.
Once these are in place, you are ready to start making API calls to your environment using the Uptycs collection
Go to Environments and click on Globals. Ensure the values for domain, customerID, apiKey and apiSecret are correct.
Postman uses the Current Values, not the Initial Values, for variables to push into an API call. Make sure that these values match, or at least the Current Values are correct, or else the API call won’t work
This should be automatically configured by downloading the collection, but this could be an area where something got messed up. Ensure your pre-request script matches this. Download the Postman code via the attachments tab.
The collection is written with the domain suffix of 'uptycs.io' in mind. If your tenant has a different domain suffix, you'll need to change the domain suffix in each of the API commands you want to run.
To access the API via a simple curl statement, you will need your domain, your customer ID, and a token.
Find the username_apikey.json file downloaded after creating an API key, since it will have the necessary information. Example of a downloaded file:
Copy the generate_token.py script to your system. If you need help 'installing' the script, follow these directions.
Run the script giving it two arguments.
The first argument should be an integer number and represents the number of seconds that the token should be valid. We recommend no more than 300 seconds. Queries with a lot of results might need a higher number.
The second argument should be a /path/to/username_apikey.json
Example: /usr/bin/python3 ./generate_token.py 300 mycreds.json
The script will generate a token and it will also give an example curl.
The basic curl format is:
curl -H "Authorization: Bearer ${token}" "https://${domain}.${domainSuffix}/public/api/customers/${customerId}/${command}
${command} can be things like assets, alerts, detections, tags, . . .
The full list of available commands can be found by logging into your Uptycs account, clicking on the documentation button on the bottom left hand side of the screen, and then clicking on the links to the API documentation. Review these more detailed instructions for finding the available API commands if needed.
Using the API to run your own SQL query involves at least three different calls.
Post your query to the system using queryJobs as your command. Obtain the query id from the response. It will be a main key called 'id'.
Using the id, query the API to see if the SQL job has finished. Use the queryJobs command followed by a slash and the id.
Once queryJobs returns a main key status of 'FINISHED', query the API for the results with the id. Do this by appending /results to the last query. If the number of lines in the output exceeds the limit for the query, keep querying with the offset until all data is pulled.
Find the username_apikey.json file downloaded after creating an API key, since it will have the necessary information. Example of a downloaded file:
{
'other-fields': other fields',
'key' : 'long key looking thing',
'secret: 'long secret looking thing',
'customerId: 'hexa hexa hexa hexa looking thing',
'domain': 'your_tenant_name',
'domainSuffix': 'uptycs.dev',
'other-fields': other fields'
}
Copy the api_calls.py script to your system. If you need help 'installing' the script, follow these directions.
Run the script.
For this example, I have the api_calls.py script saved with executable permissions and the first line of the script points to the python interpreter. My credentials file that I downloaded from Configuration -> Users -> Create API -> Download is stored in the same directory as demo_apikey.json.
√: ls -la
total 40
drwxr-xr-x 4 gnicodemus staff 128 Feb 15 14:55 .
drwxr-xr-x 39 gnicodemus staff 1248 Feb 15 14:55 ..
-rwxr-xr-x@ 1 gnicodemus staff 15271 Feb 15 14:55 api_calls.py
-rw-r--r--@ 1 gnicodemus staff 464 Feb 15 14:55 demo_apikey.json
√: head -1 api_calls.py
#!/Users/gnicodemus/opt/anaconda3/bin/python
8:26 √%: ./api_calls.py -h
usage: ./api_calls.py [-h] [-t TIME] json_auth_file command sub
This script queries the Uptycs API. Most API results are limited to 10,000 rows. If there are
more than 10,000 results to the API call, the script continues to query until all data are
gathered. The output is put into a JSON array and saved as a JSON file.
positional arguments:
json_auth_file This argument should be a path to a JSON formatted authentication
file. The required keys in the file are: key, secret, customerId,
domain, and domainSuffix Download the file from the Uptycs UI by
logging in, going to Configuration-> Users, finding your name,
clicking on Edit, selecting Create under API keys, and clicking on the
Download link in the pop-up window. If your name in Configuration->
users does not have an Edit button, you will need to get admin
permissions. The downloaded files will have extra data that is not
needed, but will not harm the script, so you do not need to edit the
file. Example: { 'random-thing': 'unnecessary fields', 'key' : 'long
key looking thing', 'secret: 'long secret looking thing', 'customerId:
'hexa hexa hexa hexa looking thing', 'domain': 'your_tenant_name',
'domainSuffix': 'uptycs.dev', 'random-thing': 'unnecessary fields' }
command Valid commands are ['list', 'sql']. 'sql' will run the specified SQL.
If no time is specified with the -t option, default is 24 hours.
'custom' will change the url the API uses. 'list' will query for a
list of objects, like assets or tags.
sub If the command given is "sql", a string should follow. The string
should either contain valid SQL or the path to a file containing valid
SQL. Limit the times searched with the -t option followed by the
number of days in the past to go. If no time is specified, the default
used is 1. If the command given is "list", then it must be followed by
a valid thing to list. Valid objects to list are: alertRuleCategories,
alertrules, alerts, alertsReporting, assetGroupRules assets,
atcQueries, auditConfigurations, auditgroups, blockrules, carves
cloudAccounts, cloudKinesisStreams, cloudPubSub, cloudResourceTags
cloudResources, cloudServices, cloudTrailBuckets, complianceFailures
complianceProfiles, customProfiles, destinations
detectionDestinationPolicy, detections, diskScans,
eventExcludeProfiles eventRuleTables, eventrules, exceptions,
filePathGroups, flagConfig flagprofiles, fleet, graphJobs,
imageLoadExclusions, lookupTables malwareAccounts, notifications,
objectGroups, osqueryPackages, permissions permissionsGroups,
pivotQueryJobs, pivots, queryJobs, querypacks redactions,
registryPaths, reportRuns, reports, roles, scans scheduledGroups,
schema, secretScans, secrets, signatures, slackUsers tagrules, tags,
tags, threatBooks, threatIndicators, threatVendors thretSources,
users, validAwsJobs, validGcpJobs windowsDefenderPreferences,
yaraGroupRules, zerotrustProfiles
optional arguments:
-h, --help show this help message and exit
-t TIME, --time TIME SQL commands require time filters, but you do not need to put them
into the WHERE clause. Instead, add the number of days into the past
you want the query to go. -t 3 will run the query from 3 days ago to
right now. The default is 1 day.
There are three required arguments. The first argument is the path to the apikey. The second argument is the main command you want to do. The third argument is the sub command. Currently, the main command can be 'list' or 'sql'. If your main command is 'list', then the subcommand can be things you can list: assets, alerts, detections, tags, users, . . . If your main command is 'sql', then the subcommand should be a single string of SQL.
8:39 √%: ./api_calls.py demo_apikey.json list assets
Store Results:
File type: both
Base fn: /Users/gwen/uptycs/api/list_assets_2023_03_22_08_39
What to do:
Main Command: list
Sub Command: assets
Authentication:
Key: P3LR4XVMA2P3CELHUPNWMKZRA5TMILBD
Secret: Zfq+5WdaKVkYRPYnRxFI/synBbIcwecyRP5cE5NAOYHB6Re4ghlppkT7G+X1KTlw
Customer ID: 33d43cb1-2678-49ca-8498-db9a72bed72b
Domain: lowell.uptycs.io
Time Limit: 2023_09_18_08_39
Query Group Number (each group is unknown lines long): 1
Number of Rows: 102
Limit: 10000
Response saved as:
/Users/gwen/uptycs/api/list_assets_2023_03_22_08_39.csv
/Users/gwen/uptycs/api/list_assets_2023_03_22_08_39.json
8:41 √%: cat li*json | jq 'keys'
[
"items",
"limit",
"links",
"offset"
]
8:41 √%: cat li*json | jq '.items' | head
[
{
"gateway": "11.11.11.111",
"agentless": false,
"cityId": "a00b1681-7249-465b-b258-28b8c48dc8b5",
"createdAt": "2022-11-07T16:07:27.052Z",
"disabled": false,
"hostName": "Ubuntu18",
"id": "0e5f4d56-71ea-96b5-4d94-7f0927aaeb1c",
"lastEnrolledAt": "2023-03-20T19:30:39.943Z",
Either of these commands will retrieve alerts for the last day. The first command (using the SQL) limits the results to the last day. The second command pulls all the results. The resultant JSON will be structured differently.
./api_calls.py demo_apikey.json sql 'SELECT * FROM upt_alerts'
8:59 √%: cat sq*json | jq 'keys'
[
"columns",
"endTime",
"error",
"id",
"items",
"limit",
"links",
"offset",
"queryStats",
"resultStore",
"rowCount",
"startTime",
"status"
]
./api_calls.py demo_apikey.json list alerts
8:47 √%: cat li*json | jq 'keys' | head
[
0,
1,
2,
3,
4,
5,
6,
7,
8,
The API limits the number of records in each pull. Since this tenant has a lot of alerts, 33 pulls are done. Each of the results are added to a JSON array, so the indexes are numbers.
Pull alerts for the last 2 days
./api_calls.py demo_apikey.json sql 'SELECT * FROM upt_alerts' --time 2
Video: https://drive.google.com/file/d/1Aq0tAfYHtOowLqV7faY__f--upKYz5Hf/view?usp=share_link
Access swagger by going to https://{domain}/public/api/customers/{customerId} in a browser. If you have problems with that, log into your Uptycs tenant and click on the bottom icon on the left hand side of the screen to get to Swagger.
Once on the Uptycs Swagger page, set up an authenticated session.
Type in your domain name
Paste in your customer ID
Click on the Authorize button
A new, pop-up window will appear.
Past in your key followed by a # followed by your secret.
Click Authorize
Click on the various arrows to un-collapse information about available API calls.
Click the 'Try Out' Button.
Fill in any data that is needed. Check for an input box.
Click 'Execute'
Output from the API queries will be in JSON.
√: curl -sH "Authorization: Bearer ${token}" "https://${domain}/public/api/customers/${customer_id}/assets" | jq 'keys'
[
"items",
"limit",
"links",
"offset"
]
'items' - This field is the JSON array containing the information you want is under the 'items' key. For example:
√: curl -sH "Authorization: Bearer ${token}" "https://${domain}/public/api/customers/${customer_id}/assets" | jq '.items | length'
110
√: curl -sH "Authorization: Bearer ${token}" "https://${domain}/public/api/customers/${customer_id}/assets" | jq '.items[0] | keys'
[
"agentless",
"assetCloudInfo",
"assetLastActivityAt",
"assetObjectGroupId",
"assetUpgrade",
"atcQueries",
"auditConfigurations",
"auditGroups",
"auditRules",
"capabilities",
"city",
"cityId",
"createdAt",
"customProfile",
"customProfileId",
"disabled",
. . .
'limit' - The maximum number of rows the API will return per request for this type of query. Most API calls have a limit of 10,000.
'links' - This is a list of links (other API commands) that you might be interested in based on the query to the API you just did.
curl -sH "Authorization: Bearer ${token}" "https://${domain}/public/api/customers/${customer_id}/assets" | jq '.links'
[
{
"rel": "self",
"title": "Assets information",
"href": "/public/api/customers/33d43cb1-2678-49ca-8498-db9a72bed72b/assets?"
},
{
"rel": "parent",
"title": "Customer information",
"href": "/api/customers/33d43cb1-2678-49ca-8498-db9a72bed72b"
},
{
"rel": "tags",
"title": "Asset tags information",
"href": "/api/customers/33d43cb1-2678-49ca-8498-db9a72bed72b/assets/tags"
}
]
'offset' - The item number in the 'items' array you started with.
√: curl -sH "Authorization: Bearer ${token}" "https://${domain}/public/api/customers/${customer_id}/alerts" | jq '.offset'
0
Query length
The maximum number of rows the API will return per request is 10,000 for most of the API commands. To get the rest of the query, you need to make another request.
For example,
√: curl -sH "Authorization: Bearer ${token}" "https://${domain}/public/api/customers/${customer_id}/alerts" | jq 'keys'
[
"items",
"limit",
"links",
"offset"
]
√: curl -sH "Authorization: Bearer ${token}" "https://${domain}/public/api/customers/${customer_id}/alerts" | jq '.limit'
1000
√: curl -sH "Authorization: Bearer ${token}" "https://${domain}/public/api/customers/${customer_id}/alerts" | jq '.offset'
0
To get the next batch of items in your request, add ?offset=1000 to the query.
curl -sH "Authorization: Bearer ${token}" "https://${domain}/public/api/customers/${customer_id}/alerts?offset=1000"
There are three places to view the list of API commands.
In the Uptycs UI, under Software Downloads, there is an option to download the APi documentation on top of the link to download the Postman collection.
Go to your environment’s page, click help. The help button is the second from the bottom on the left-hand side of the screen.
On the help page, click API. This is the documentation you will need for using Uptycs API
Log into Swagger.
The Swagger site shows each of the available URL/commands along with example output, the schema of the output, and any needed parameters. Click on the collapse/uncollapse arrow to expand the commands to see the documentation on each.
Download the script to your system.
Decide how you want to run the script.
Make the script an executable
Find the location of python on your system.
Try the command: which python3
If which does not work, check the locations python is usually installed.
ls /usr/bin | grep python3
ls /bin | grep python3
If you can't find python in a common location, try user directories.
find /Users -type f -name "python3" -print 2> /dev/null
If you can't find python anywhere on the system, ask your system administrator to install python3.
Edit the script. The first line of the script needs to start with a shebang followed by the path to python 3.
Change the permissions on the file to make it executable.
Run the script as an argument to python
python script_name arguments
Both Python scripts require multiple modules to be installed. Most of these modules are part of the python standard library.
It's possible, when you run the generate_token.py script, that you might get an error indicating you need to install requests. To do this, run the below command.
pip3 install requests
The api_calls.py script has two modules that might not be installed: requests and jwt.
pip3 install requests
pip3 install jwt
See the attachments tab.