PrivX API Guide
Methods
Common REST API conventions are followed for HTTP methods. GET
for retrieving a single object or a collection of objects. These must be side-effect free requests. POST
for creating new objects, PUT
for updating existing objects, and DELETE
for removing objects. POST
is used instead of GET
in cases where there are arguments to the request that better fit in the HTTP request body, such as for search APIs where search criteria are given as a JSON object.
Paths
All API paths start with the service name, followed by api
, followed by the version (e.g. v1
). The path of the resource in question comes after this. If the resource is a collection of objects, then the path contains the name of the object type in plural. A trailing slash is not used. E.g. /users
. Individual objects within the collection are accessed using their identifier, which is a UUID. E.g. /users/0125d3ec-ccb4-4fec-6afa-4540d6bfbd3e
. Search APIs for the collection use the collection name followed by /search
, e.g. /users/search
.
Creation of new objects is done with a POST
to the path of the collection. Object fetches, updates, and removal is done to the path of the specific object.
Examples of API paths:
Fetch a host:
GET /host-store/api/v1/hosts/ab2111c0-7a16-4f23-6bde-8add9782f478
Create a new host:
POST /host-store/api/v1/hosts
Update an existing host:
PUT /host-store/api/v1/hosts/ab2111c0-7a16-4f23-6bde-8add9782f478
Search hosts:
POST /host-store/api/v1/hosts/search
HTTP Responses
Successful requests use the HTTP status 200, with the exception of creation of new objects where 201 is used. When a new object is created, the response must contain a Location
header with the path to the newly created object, such that the identifier can be read from this path. E.g. Location: /host-store/api/v1/hosts/ab2111c0-7a16-4f23-6bde-8add9782f478
.
When a request cannot be successfully carried out due to data that is invalid in the request, HTTP status 400 is used. The body of the HTTP response must contain an error object in JSON format, as defined in the "Error Messages" section.
If a request is unauthorized e.g. due to a missing or expired access token, status 401 must be used to indicate this. 403 must be used when the access token is correct as such, but the requester has insufficient rights to the resource.
If an object is requested that does not exist, status 404 is used. No particular HTTP body is required in this case.
Status 5xx must only be used in unexpected situations when the request cannot be served, but never in situations where the request data or the state of some resource is invalid.
Error Messages
Error messages are given as JSON error objects. An error object contains the following properties:
error_code
- indicates what went wrong using one of previously agreed error code strings, e.g.REQUIRED_VALUE_MISSING
property
- a property path that poinst to the property in the request JSON body that contained an error (OPTIONAL)details
- an array of further error objects that describe the reasons for the error (OPTIONAL)message
- a human readable explanation of what went wrong, but is not shown in the UI since it is not localization aware (OPTIONAL)
For example if a user is created that has missing username
property, the following error message would be returned:
{ "error_code": "BAD_REQUEST", "details": [{ "error_code": "REQUIRED_VALUE_MISSING", "property": "username" }] }
The error code BAD_REQUEST
is used when there are validation errors specified within a details
array.
Property paths use a format of property names separated by periods to describe the location of a property within the request object. In case of arrays, the index of the object in the array is used as a property name.
Examples of property paths:
The start_time property, as a child of the context property:
context.start_time
The port property of the 2nd service object in a services array:
services.2.port
Authentication
HTTP requests are authenticated using an access token, which is provided using the Authorization
header as follows:
Authorization: Bearer ACCESS-TOKEN-HERE
The access token is obtained using OAuth 2.0 from the authentication token endpoint.
Sorting
Sorting is specified using query string parameters sortkey
and sortdir
. The sortkey
parameter indicates the object property to sort by. The sortdir
indicates the direction, and is either asc
for ascending or desc
for descending sort order. E.g. ?sortkey=name&sortdir=asc
to sort by name in ascending order. If sorting is omitted, then no particular sort order should be assumed by the requester.
Pagination
Pagination is specified using query string parameters offset
and limit
. The offset
parameter specifies the object index in the collection of the first object to be returned. The limit
parameter specifies the maximum number of objects to return. If offset
is omitted, 0 is implied. If limit
is omitted, then every object in the collection must be returned. In cases where this is not reasonable due to very large amounts of data, the API can assume a reasonable limit instead.
Collection Responses
The response data for collections should be structured as a JSON object with two key properties: items and count. The items property holds an array with the subset of objects that correspond to the requested pagination and search (if applicable)". The count property reflects the total number of objects in the collection, accounting for any search criteria applied, and is used to facilitate pagination. It is important to note that the count is not indicative of the number of objects actually returned in the response; rather, it represents the total number of items in the database from which the response is a subset.
Example:
{ "items": [{ ... }, { ... }, { ... }], "count": 3 }
Search Criteria
Search criteria are specified as JSON objects and passed in the HTTP body to POST
requests. The JSON object should accept properties for supported search criteria. If a criterion supports multiple values, then an array must be used to provide them. There must be a logical and
between the criteria, but a logical or
between values for a given criterion. For free text search, a property called keywords
must be used, that takes a single string as its value. The keywords string must not require delimiters between words and wildcards must be assumed.
Examples:
Keyword search:
{ "keywords": "example" }
Search for hosts with SSH or RDP services:
{ "service": ["SSH", "RDP"] }
Search for hosts with SSH or RDP, running status, matching keywords "test":
{ "service": ["SSH", "RDP"], "statuses": ["RUNNING"], "keywords": "test" }
Dates and Durations
Dates and durations must be in ISO-8601 format.
Date example:
2022-01-27T10:50:00Z
Duration example:
P1DT12H
Empty Arrays
A property that has an array as its type, but does not have any values, must use an empty array as the value rather than null.