## API
In this documentation we use local adresses. When you connect externaly then you should external IP under secure http - https://YOUR_IP.
### Base API Guide
#### Authentication
Most API calls require authentication. Credentials can be provided using a session cookie, an API key or directly using HTTP basic
authentication (when enabled).
##### Using API key
Session cookie is suitable for browser authentication, not for a dedicated tool. The easiest solution if you want to
write a tool that leverages Base module's API is to use API key authentication. API keys can be generated using the Web interface of the product, under the user admin area.
For example, to list cases, use the following curl
command:
```
curl -H 'Authorization: Bearer ***API*KEY***' http://127.0.0.1:9000/base/api/case
```
##### Using basic authentication
Base module also supports basic authentication (disabled by default). You can enable it by adding `auth.method.basic=true` in the configuration file.
```
curl -u mylogin:mypassword http://127.0.0.1:9000/base/api/case
```
#### Alert
##### Model definition
Required attributes:
- `title` (text) : title of the alert
- `description` (text) : description of the alert
- `severity` (number) : severity of the alert (1: low; 2: medium; 3: high) **default=2**
- `date` (date) : date and time when the alert was raised **default=now**
- `tags` (multi-string) : case tags **default=empty**
- `tlp` (number) : [TLP](https://www.us-cert.gov/tlp) (`0`: `white`; `1`: `green`; `2: amber`;
`3: red`) **default=2**
- `status` (AlertStatus) : status of the alert (*New*, *Updated*, *Ignored*, *Imported*) **default=New**
- `type` (string) : type of the alert (read only)
- `source` (string) : source of the alert (read only)
- `sourceRef` (string) : source reference of the alert (read only)
- `artifacts` (multi-artifact) : artifact of the alert. It is a array of JSON object containing artifact attributes
**default=empty**
- `follow` (boolean) : if true, the alert becomes active when updated **default=true**
Optional attributes:
- `caseTemplate` (string) : case template to use when a case is created from this alert. If the alert specifies a non-existent case template or doesn't supply one, Energy SOAR Base will import the alert into a case using a case template that has the exact same name as the alert's type if it exists. For example, if you raise an alert with a type value of `splunk` and you do not provide the `caseTemplate` attribute or supply a non-existent one (for example `splink`), Base module will import the alert using the case template called `splunk` if it exists. Otherwise, the alert will be imported using an empty case (i.e. from scratch).
Attributes generated by the backend:
- `lastSyncDate` (date) : date of the last synchronization
- `case` (string) : id of the case, if created
Alert ID is computed from `type`, `source` and`sourceRef`.
##### Alert Manipulation
###### Alert methods
| HTTP Method | URI | Action |
| GET | /api/alert | List alerts |
| POST | /api/alert/_search | Find alerts |
| PATCH | /api/alert/_bulk | Update alerts in bulk |
| POST | /api/alert/_stats | Compute stats on alerts |
| POST | /api/alert | Create an alert |
| GET | /api/alert/:alertId | Get an alert |
| PATCH | /api/alert/:alertId | Update an alert |
| DELETE | /api/alert/:alertId | Delete an alert |
| POST | /api/alert/:alertId/markAsRead | Mark an alert as read |
| POST | /api/alert/:alertId/markAsUnread | Mark an alert as unread |
| POST | /api/alert/:alertId/createCase | Create a case from an alert |
| POST | /api/alert/:alertId/follow | Follow an alert |
| POST | /api/alert/:alertId/unfollow | Unfollow an alert |
| POST | /api/alert/:alertId/merge/:caseId | Merge an alert in a case) |
| POST | /api/alert/merge/_bulk | Merge several alerts in one case |
###### Get an alert
An alert's details can be retrieve using the url:
```
GET /api/alert/:alertId
```
The alert ID is obtained by List alerts or Find alerts API.
If the parameter `similarity` is set to "1" or "true", this API returns information on cases which have similar observables.
With this feature, output will contain the `similarCases` attribute which list case details with:
- artifactCount: number of observables in the original case
- iocCount: number of observables marked as IOC in original case
- similarArtifactCount: number of observables which are in alert and in case
- similarIocCount: number of IOCs which are in alert and in case
*warning* IOCs are observables
**Examples**
Get alert without similarity data:
```
curl -H 'Authorization: Bearer ***API*KEY***' http://127.0.0.1:9000/base/api/alert/ce2c00f17132359cb3c50dfbb1901810
```
It returns:
```
{
"_id": "ce2c00f17132359cb3c50dfbb1901810",
"_type": "alert",
"artifacts": [],
"createdAt": 1495012062014,
"createdBy": "myuser",
"date": 1495012062016,
"description": "N/A",
"follow": true,
"id": "ce2c00f17132359cb3c50dfbb1901810",
"lastSyncDate": 1495012062016,
"severity": 2,
"source": "instance1",
"sourceRef": "alert-ref",
"status": "New",
"title": "New Alert",
"tlp": 2,
"type": "external",
"user": "myuser"
}
```
Get alert with similarity data:
```
curl -H 'Authorization: Bearer ***API*KEY***' http://127.0.0.1:9000/base/api/alert/ce2c00f17132359cb3c50dfbb1901810?similarity=1
```
It returns:
```
{
"_id": "ce2c00f17132359cb3c50dfbb1901810",
"_type": "alert",
"artifacts": [],
"createdAt": 1495012062014,
"createdBy": "myuser",
"date": 1495012062016,
"description": "N/A",
"follow": true,
"id": "ce2c00f17132359cb3c50dfbb1901810",
"lastSyncDate": 1495012062016,
"severity": 2,
"source": "instance1",
"sourceRef": "alert-ref",
"status": "New",
"title": "New Alert",
"tlp": 2,
"type": "external",
"user": "myuser",
"similarCases": [
{
"_id": "AVwwrym-Rw5vhyJUfdJW",
"artifactCount": 5,
"endDate": null,
"id": "AVwwrym-Rw5vhyJUfdJW",
"iocCount": 1,
"resolutionStatus": null,
"severity": 1,
"similarArtifactCount": 2,
"similarIocCount": 1,
"startDate": 1495465039000,
"status": "Open",
"tags": [
"src:MISP"
],
"caseId": 1405,
"title": "TEST",
"tlp": 2
}
]
}
```
###### Create an alert
An alert can be created using the following url:
```
POST /api/alert
```
Required case attributes (cf. models) must be provided.
If an alert with the same tuple `type`, `source` and `sourceRef` already exists, Base module will refuse to create it.
This call returns attributes of the created alert.
**Examples**
Creation of a simple alert:
```
curl -XPOST -H 'Authorization: Bearer ***API*KEY***' -H 'Content-Type: application/json' http://127.0.0.1:9000/base/api/alert -d '{
"title": "New Alert",
"description": "N/A",
"type": "external",
"source": "instance1",
"sourceRef": "alert-ref"
}'
```
It returns:
```
{
"_id": "ce2c00f17132359cb3c50dfbb1901810",
"_type": "alert",
"artifacts": [],
"createdAt": 1495012062014,
"createdBy": "myuser",
"date": 1495012062016,
"description": "N/A",
"follow": true,
"id": "ce2c00f17132359cb3c50dfbb1901810",
"lastSyncDate": 1495012062016,
"severity": 2,
"source": "instance1",
"sourceRef": "alert-ref",
"status": "New",
"title": "New Alert",
"tlp": 2,
"type": "external",
"user": "myuser"
}
```
Creation of another alert:
```
curl -XPOST -H 'Authorization: Bearer ***API*KEY***' -H 'Content-Type: application/json' http://127.0.0.1:9000/base/api/alert -d '{
"title": "Other alert",
"description": "alert description",
"type": "external",
"source": "instance1",
"sourceRef": "alert-ref",
"severity": 3,
"tlp": 3,
"artifacts": [
{ "dataType": "ip", "data": "127.0.0.1", "message": "localhost" },
{ "dataType": "domain", "data": "energysoar.com", "tags": ["home", "file"] },
{ "dataType": "file", "data": "logo.svg;image/svg+xml;PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxOC4wLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgNjI0IDIwMCIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgNjI0IDIwMCIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+DQo8Zz4NCgk8Zz4NCgkJPHBhdGggZmlsbD0iIzE1MTYzMiIgZD0iTTE3Mi4yLDczdjY2LjRoLTIwLjdWNzNoLTI3LjRWNTQuOGg3NS41VjczSDE3Mi4yeiIvPg0KCQk8cGF0aCBmaWxsPSIjMTUxNjMyIiBkPSJNMjcyLjgsMTAwLjV2MzguOWgtMjAuMXYtMzQuNmMwLTcuNC00LjQtMTIuNS0xMS0xMi41Yy03LjgsMC0xMyw1LjQtMTMsMTcuN3YyOS40aC0yMC4yVjQ4LjVoMjAuMlY4Mg0KCQkJYzQuOS01LDExLjUtNy45LDE5LjYtNy45QzI2Myw3NC4xLDI3Mi44LDg0LjYsMjcyLjgsMTAwLjV6Ii8+DQoJCTxwYXRoIGZpbGw9IiMxNTE2MzIiIGQ9Ik0zNTYuMywxMTIuOGgtNDYuNGMxLjYsNy42LDYuOCwxMi4yLDEzLjYsMTIuMmM0LjcsMCwxMC4xLTEuMSwxMy41LTcuM2wxNy45LDMuNw0KCQkJYy01LjQsMTMuNC0xNi45LDE5LjgtMzEuNCwxOS44Yy0xOC4zLDAtMzMuNC0xMy41LTMzLjQtMzMuNmMwLTE5LjksMTUuMS0zMy42LDMzLjYtMzMuNmMxNy45LDAsMzIuMywxMi45LDMyLjcsMzMuNlYxMTIuOHoNCgkJCSBNMzEwLjMsMTAwLjVoMjYuMWMtMS45LTYuOC02LjktMTAtMTIuNy0xMEMzMTgsOTAuNSwzMTIuMiw5NCwzMTAuMywxMDAuNXoiLz4NCgkJPHBhdGggZmlsbD0iI0YzRDAyRiIgZD0iTTQ0NS41LDEzOS4zaC0yMC43di0zMy40aC0zNS42djMzLjRoLTIwLjhWNTQuOGgyMC44djMyLjloMzUuNlY1NC44aDIwLjdWMTM5LjN6Ii8+DQoJCTxwYXRoIGZpbGw9IiNGM0QwMkYiIGQ9Ik00NzguNiw1Ny4zYzAsNi40LTQuOSwxMS4yLTExLjcsMTEuMmMtNi44LDAtMTEuNi00LjgtMTEuNi0xMS4yYzAtNi4yLDQuOC0xMS41LDExLjYtMTEuNQ0KCQkJQzQ3My43LDQ1LjgsNDc4LjYsNTEuMSw0NzguNiw1Ny4zeiBNNDU2LjgsMTM5LjNWNzZoMjAuMnY2My4zSDQ1Ni44eiIvPg0KCQk8cGF0aCBmaWxsPSIjRjNEMDJGIiBkPSJNNTI4LjUsMTM5LjNoLTIwLjZsLTI2LjItNjMuNUg1MDNsMTUuMywzOS4xbDE1LjEtMzkuMWgyMS4zTDUyOC41LDEzOS4zeiIvPg0KCQk8cGF0aCBmaWxsPSIjRjNEMDJGIiBkPSJNNjE4LjMsMTEyLjhoLTQ2LjRjMS42LDcuNiw2LjgsMTIuMiwxMy42LDEyLjJjNC43LDAsMTAuMS0xLjEsMTMuNS03LjNsMTcuOSwzLjcNCgkJCWMtNS40LDEzLjQtMTYuOSwxOS44LTMxLjQsMTkuOGMtMTguMywwLTMzLjQtMTMuNS0zMy40LTMzLjZjMC0xOS45LDE1LjEtMzMuNiwzMy42LTMzLjZjMTcuOSwwLDMyLjMsMTIuOSwzMi43LDMzLjZWMTEyLjh6DQoJCQkgTTU3Mi4yLDEwMC41aDI2LjFjLTEuOS02LjgtNi45LTEwLTEyLjctMTBDNTc5LjksOTAuNSw1NzQuMSw5NCw1NzIuMiwxMDAuNXoiLz4NCgk8L2c+DQoJPGc+DQoJCTxnPg0KCQkJPHBhdGggZmlsbD0iI0YzRDAyRiIgZD0iTTU3LDcwLjNjNi42LDAsMTIuMiw2LjQsMTIuMiwxMS41YzAsNi4xLTEwLDYuNi0xMiw2LjZsMCwwYy0yLjIsMC0xMi0wLjMtMTItNi42DQoJCQkJQzQ0LjgsNzYuNyw1MC40LDcwLjMsNTcsNzAuM0w1Nyw3MC4zeiBNNDQuMSwxMzMuNmwyNS4yLDAuMWwyLjIsNS42bC0yOS42LTAuMUw0NC4xLDEzMy42eiBNNDcuNiwxMjUuNmwyLjItNS42bDE0LjIsMGwyLjIsNS42DQoJCQkJTDQ3LjYsMTI1LjZ6IE01MywxMTIuMWwzLjktOS41bDMuOSw5LjVMNTMsMTEyLjF6IE0yMy4zLDE0My42Yy0xLjcsMC0zLjItMC4zLTQuNi0xYy02LjEtMi43LTkuMy05LjgtNi41LTE1LjkNCgkJCQljNi45LTE2LjYsMjcuNy0yOC41LDM5LTMwLjJsLTcuNCwxOC4xbDAsMEwzOC4zLDEyOGwwLDBsLTMuNSw4LjFDMzIuNiwxNDAuNywyOC4yLDE0My42LDIzLjMsMTQzLjZMMjMuMywxNDMuNnogTTU2LjcsMTYxLjgNCgkJCQljLTguMSwwLTE0LjctNS45LTE3LjMtMTVsMzQuNywwLjFDNzEuNCwxNTYuMiw2NC44LDE2MS44LDU2LjcsMTYxLjhMNTYuNywxNjEuOHogTTk1LDE0Mi45Yy0xLjUsMC43LTMuMiwxLTQuNiwxDQoJCQkJYy00LjksMC05LjMtMy0xMS4yLTcuNmwtMy40LTguMWwwLDBsLTUuMS0xMi43YzAtMC41LTAuMi0xLTAuNS0xLjVsLTctMTcuNmMxMS4yLDIsMzIsMTQsMzguOCwzMC41DQoJCQkJQzEwNC4zLDEzMy4zLDEwMS4zLDE0MC40LDk1LDE0Mi45TDk1LDE0Mi45eiIvPg0KCQkJDQoJCQkJPGxpbmUgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjRjNEMDJGIiBzdHJva2Utd2lkdGg9IjUuMjE0NiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHgxPSI0Ny44IiB5MT0iNjcuNSIgeDI9IjQzLjciIHkyPSI1OC45Ii8+DQoJCQkNCgkJCQk8bGluZSBmaWxsPSJub25lIiBzdHJva2U9IiNGM0QwMkYiIHN0cm9rZS13aWR0aD0iNS4yMTQ2IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgeDE9IjY2LjEiIHkxPSI2Ny41IiB4Mj0iNzAuMSIgeTI9IjU4LjkiLz4NCgkJPC9nPg0KCQkNCgkJCTxwb2x5bGluZSBmaWxsPSJub25lIiBzdHJva2U9IiNGM0QwMkYiIHN0cm9rZS13aWR0aD0iNS4yMTQ2IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgcG9pbnRzPSINCgkJCTk0LjgsMTAzLjUgMTA1LjUsODQuMiA4MS4xLDQyLjEgMzIuNyw0Mi4xIDguMyw4NC4yIDIwLDEwMy41IAkJIi8+DQoJPC9nPg0KPC9nPg0KPC9zdmc+DQo=", "message": "logo" }
],
"caseTemplate": "external-alert"
}'
```
###### Merge an alert
An alert can be merge in a case using the URL:
```
POST /api/alert/:alertId/merge/:caseId
```
Each observable of the alert will be added to the case if it doesn't exist in the case. The description of the alert will be appended to the case's description.
The HTTP response contains the updated case.
**Example**
Merge the alert `ce2c00f17132359cb3c50dfbb1901810` in case `AVXeF-pZmeHK_2HEYj2z`:
```
curl -XPOST -H 'Authorization: Bearer ***API*KEY***' http://127.0.0.1:9000/base/api/alert/ce2c00f17132359cb3c50dfbb1901810/merge/AVXeF-pZmeHK_2HEYj2z
```
The call returns:
```
{
"severity": 3,
"createdBy": "myuser",
"createdAt": 1488918582777,
"caseId": 1,
"title": "My first case",
"startDate": 1488918582836,
"owner": "myuser",
"status": "Open",
"description": "This case has been created by my custom script
### Merged with alert #10 my alert title
This is my alert description",
"user": "myuser",
"tlp": 2,
"flag": false,
"id": "AVXeF-pZmeHK_2HEYj2z",
"_id": "AVXeF-pZmeHK_2HEYj2z",
"_type":"case"
}
```
###### Bulk merge alert
This API merge several alerts with one case:
```
POST /api/alert/merge/_bulk
```
The observable of each alert listed in `alertIds` field will be imported into the case (identified by `caseId` field). The description of the case *is not* modified.
The HTTP response contains the case.
**Example**
Merge the alerts `ce2c00f17132359cb3c50dfbb1901810` and `a97148693200f731cfa5237ff2edf67b` in case `AVXeF-pZmeHK_2HEYj2z`:
```
curl -XPOST -H 'Authorization: Bearer ***API*KEY***' -H 'Content-Type: application/json' http://127.0.0.1:9000/base/api/alert/merge/_bulk -d '{
"caseId": "AVXeF-pZmeHK_2HEYj2z",
"alertIds": ["ce2c00f17132359cb3c50dfbb1901810", "a97148693200f731cfa5237ff2edf67b"]
}'
```
The call returns:
```
{
"severity": 3,
"createdBy": "myuser",
"createdAt": 1488918582777,
"caseId": 1,
"title": "My first case",
"startDate": 1488918582836,
"owner": "myuser",
"status": "Open",
"description": "This case has been created by my custom script",
"user": "myuser",
"tlp": 2,
"flag": false,
"id": "AVXeF-pZmeHK_2HEYj2z",
"_id": "AVXeF-pZmeHK_2HEYj2z",
"_type":"case"
}
```
#### Observable
##### Model definition
Required attributes:
- `data` (string) : content of the observable (read only). An observable can't contain data and attachment attributes
- `attachment` (attachment) : observable file content (read-only). An observable can't contain data and attachment
attributes
- `dataType` (enumeration) : type of the observable (read only)
- `message` (text) : description of the observable in the context of the case
- `startDate` (date) : date of the observable creation **default=now**
- `tlp` (number) : [TLP](https://www.us-cert.gov/tlp) (`0`: `white`; `1`: `green`; `2`: `amber`;
`3`: `red`) **default=2**
- `ioc` (boolean) : indicates if the observable is an IOC **default=false**
- `status` (artifactStatus) : status of the observable (*Ok* or *Deleted*) **default=Ok**
Optional attributes:
- `tags` (multi-string) : observable tags
##### Observable manipulation
###### Observable methods
| HTTP Method | URI | Action |
| POST | /api/case/artifact/_search | Find observables |
| POST | /api/case/artifact/_stats | Compute stats on observables |
| POST | /api/case/:caseId/artifact | Create an observable |
| GET | /api/case/artifact/:artifactId | Get an observable |
| DELETE | /api/case/artifact/:artifactId | Remove an observable |
| PATCH | /api/case/artifact/:artifactId | Update an observable |
| GET | /api/case/artifact/:artifactId/similar | Get list of similar observables |
| PATCH | /api/case/artifact/_bulk | Update observables in bulk |
###### List Observables of a Case
Complete observable list of a case can be retrieved by performing a search:
```
POST /api/case/artifact/_search
```
Parameters:
- `query`: `{ "_parent": { "_type": "case", "_query": { "_id": "<>" } } }`
- `range`: `all`
\<\\> must be replaced by case id (not the case number !)
#### Case
##### Model definition
Required attributes:
- `title` (text) : title of the case
- `description` (text) : description of the case
- `severity` (number) : severity of the case (1: low; 2: medium; 3: high) **default=2**
- `startDate` (date) : date and time of the begin of the case **default=now**
- `owner` (string) : user to whom the case has been assigned **default=use who create the case**
- `flag` (boolean) : flag of the case **default=false**
- `tlp` (number) : [TLP](https://www.us-cert.gov/tlp) (`0`: `white`; `1`: `green`; `2: amber`;
`3: red`) **default=2**
- `tags` (multi-string) : case tags **default=empty**
Optional attributes:
- `resolutionStatus` (caseResolutionStatus) : resolution status of the case (*Indeterminate*, *FalsePositive*,
*TruePositive*, *Other* or *Duplicated*)
- `impactStatus` (caseImpactStatus) : impact status of the case (*NoImpact*, *WithImpact* or *NotApplicable*)
- `summary` (text) : summary of the case, to be provided when closing a case
- `endDate` (date) : resolution date
- `metrics` (metrics) : list of metrics
Attributes generated by the backend:
- `status` (caseStatus) : status of the case (*Open*, *Resolved* or *Deleted*) **default=Open**
- `caseId` (number) : Id of the case (auto-generated)
- `mergeInto` (string) : ID of the case created by the merge
- `mergeFrom` (multi-string) : IDs of the cases that were merged
##### Case Manipulation
###### Case methods
| HTTP Method | URI | Action |
| GET | /api/case | List cases |
| POST | /api/case/_search | Find cases |
| PATCH | /api/case/_bulk | Update cases in bulk |
| POST | /api/case/_stats | Compute stats on cases |
| POST | /api/case | Create a case |
| GET | /api/case/:caseId | Get a case |
| PATCH | /api/case/:caseId | Update a case |
| DELETE | /api/case/:caseId | Remove a case |
| GET | /api/case/:caseId/links | Get list of cases linked to this case |
| POST | /api/case/:caseId1/_merge/:caseId2 | Merge two cases |
###### Create a Case
A case can be created using the following url :
```
POST /api/case
```
Required case attributes (cf. models) must be provided.
This call returns attributes of the created case.
**Examples**
Creation of a simple case:
```
curl -XPOST -H 'Authorization: Bearer ***API*KEY***' -H 'Content-Type: application/json' http://127.0.0.1:9000/base/api/case -d '{
"title": "My first case",
"description": "This case has been created by my custom script"
}'
```
It returns:
```
{
"severity": 3,
"createdBy": "myuser",
"createdAt": 1488918582777,
"caseId": 1,
"title": "My first case",
"startDate": 1488918582836,
"owner": "myuser",
"status": "Open",
"description": "This case has been created by my custom script",
"user": "myuser",
"tlp": 2,
"flag": false,
"id": "AVqqdpY2yQ6w1DNC8aDh",
"_id": "AVqqdpY2yQ6w1DNC8aDh",
"_type":"case"
}
```
Creation of another case:
```
curl -XPOST -H 'Authorization: Bearer ***API*KEY***' -H 'Content-Type: application/json' http://127.0.0.1:9000/base/api/case -d '{
"title": "My second case",
"description": "This case has been created by my custom script, its severity is high, tlp is red and it contains tags",
"severity": 3,
"tlp": 3,
"tags": ["automatic", "creation"]
}'
```
Creating a case with Tasks & Customfields:
```
curl -XPOST -H 'Authorization: Bearer ***API*KEY***' -H 'Content-Type: application/json' http://127.0.0.1:9000/base/api/case -d '{
"title": "My first case",
"description": "This case has been created by my custom script"
"tasks": [{
"title": "mytask",
"description": "description of my task"
}],
"customFields": {
"cvss": {
"number": 9,
},
"businessImpact": {
"string": "HIGH"
}
}
}'
```
For the `customFields` object, the attribute names should correspond to the `ExternalReference` (cvss and businessImpact in the example above) not to the name of custom fields.
#### Log
##### Model definition
Required attributes:
- `message` (text) : content of the Log
- `startDate` (date) : date of the log submission **default=now**
- `status` (logStatus) : status of the log (*Ok* or *Deleted*) **default=Ok**
Optional attributes:
- `attachment` (attachment) : file attached to the log
##### Log manipulation
###### Log methods
| HTTP Method | URI | Action |
| GET | /api/case/task/:taskId/log | Get logs of the task |
| POST | /api/case/task/:taskId/log/_search | Find logs in specified task |
| POST | /api/case/task/log/_search | Find logs |
| POST | /api/case/task/:taskId/log | Create a log |
| PATCH | /api/case/task/log/:logId | Update a log |
| DELETE | /api/case/task/log/:logId | Remove a log |
| GET | /api/case/task/log/:logId | Get a log |
###### Create a log
The URL used to create a task is:
```
POST /api/case/task/<>/log
```
\<\\> must be replaced by task id
Required log attributes (cf. models) must be provided.
This call returns attributes of the created log.
**Examples**
Creation of a simple log in task `AVqqeXc9yQ6w1DNC8aDj`:
```
curl -XPOST -H 'Authorization: Bearer ***API*KEY***' -H 'Content-Type: application/json' http://127.0.0.1:9000/base/api/case/task/AVqqeXc9yQ6w1DNC8aDj/log -d '{
"message": "Some message"
}'
```
It returns:
```
{
"startDate": 1488919949497,
"createdBy": "admin",
"createdAt": 1488919949495,
"user": "myuser",
"message":"Some message",
"status": "Ok",
"id": "AVqqi3C-yQ6w1DNC8aDq",
"_id": "AVqqi3C-yQ6w1DNC8aDq",
"_type":"case_task_log"
}
```
If log contains an attachment, the request must be in multipart format:
```
curl -XPOST -H 'Authorization: Bearer ***API*KEY***' http://127.0.0.1:9000/base/api/case/task/AVqqeXc9yQ6w1DNC8aDj/log -F '_json={"message": "Screenshot of fake site"};type=application/json' -F 'attachment=@screenshot1.png;type=image/png'
```
It returns:
```
{
"createdBy": "myuser",
"message": "Screenshot of fake site",
"createdAt": 1488920587391,
"startDate": 1488920587394,
"user": "myuser",
"status": "Ok",
"attachment": {
"name": "screenshot1.png",
"hashes": [
"086541e99743c6752f5fd4931e256e6e8d5fc7afe47488fb9e0530c390d0ca65",
"8b81e038ae0809488f20b5ec7dc91e488ef601e2",
"c5883708f42a00c3ab1fba5bbb65786c"
],
"size": 15296,
"contentType": "image/png",
"id": "086541e99743c6752f5fd4931e256e6e8d5fc7afe47488fb9e0530c390d0ca65"
},
"id": "AVqqlSy0yQ6w1DNC8aDx",
"_id": "AVqqlSy0yQ6w1DNC8aDx",
"_type": "case_task_log"
}
```
#### Task
##### Model definition
Required attributes:
- `title` (text) : title of the task
- `status` (taskStatus) : status of the task (*Waiting*, *InProgress*, *Completed* or *Cancel*) **default=Waiting**
- `flag` (boolean) : flag of the task **default=false**
Optional attributes:
- `owner` (string) : user who owns the task. This is automatically set to current user when status is set to
*InProgress*
- `description` (text) : task details
- `startDate` (date) : date of the beginning of the task. This is automatically set when status is set to *Open*
- `endDate` (date) : date of the end of the task. This is automatically set when status is set to *Completed*
##### Task manipulation
###### Task methods
| HTTP Method | URI | Action |
| POST | /api/case/:caseId/task/_search | Find tasks in a case (deprecated) |
| POST | /api/case/task/_search | Find tasks |
| POST | /api/case/task/_stats | Compute stats on tasks |
| GET | /api/case/task/:taskId | Get a task |
| PATCH | /api/case/task/:taskId | Update a task |
| POST | /api/case/:caseId/task | Create a task) |
###### Create a task
The URL used to create a task is:
```
POST /api/case/<>/task
```
\<\\> must be replaced by case id (not the case number !)
Required task attributes (cf. models) must be provided.
This call returns attributes of the created task.
**Examples**
Creation of a simple task in case `AVqqdpY2yQ6w1DNC8aDh`:
```
curl -XPOST -H 'Authorization: Bearer ***API*KEY***' -H 'Content-Type: application/json' http://127.0.0.1:9000/base/api/case/AVqqdpY2yQ6w1DNC8aDh/task -d '{
"title": "Do something"
}'
```
It returns:
```
{
"createdAt": 1488918771513,
"status": "Waiting",
"createdBy": "myuser",
"title": "Do something",
"order": 0,
"user": "myuser",
"flag": false,
"id":"AVqqeXc9yQ6w1DNC8aDj",
"_id":"AVqqeXc9yQ6w1DNC8aDj",
"_type":"case_task"
}
```
Creation of another task:
```
curl -XPOST -H 'Authorization: Bearer ***API*KEY***' -H 'Content-Type: application/json' http://127.0.0.1:9000/base/api/case/AVqqdpY2yQ6w1DNC8aDh/task -d '{
"title": "Analyze the malware",
"description": "The malware XXX is analyzed using sandbox ...",
"owner": "Joe",
"status": "InProgress"
}'
```
#### Base module Model Definition
##### Field Types
- `string` : textual data (example "malware").
- `text` : textual data. The difference between `string` and `text` is in the way content can be searched.`string` is
searchable as-is whereas `text`, words (token) are searchable, not the whole content (example "Ten users have received
this ransomware").
- `date` : date and time using timestamps with milliseconds format.
- `boolean` : true or false
- `number` : numeric value
- `metrics` : JSON object that contains only numbers
Field can be prefixed with `multi-` in order to indicate that multiple values can be provided.
##### Common Attributes
All entities share the following attributes:
- `createdBy` (text) : login of the user who created the entity
- `createdAt` (date) : date and time of the creation
- `updatedBy` (text) : login of the user who last updated the entity
- `upadtedAt` (date) : date and time of the last update
- `user` (text) : same value as `createdBy` (this field is deprecated)
These attributes are handled by the back-end and can't be directly updated.
#### Request formats
Base module accepts several parameter formats within a HTTP request. They can be used indifferently. Input data can be:
- a query string
- URL-encoded form
- multi-part
- JSON
Hence, the requests below are equivalent.
##### Query String
```
curl -XPOST 'http://127.0.0.1:9000/base/api/login?user=me&password=secret'
```
##### URL-encoded Form
```
curl -XPOST 'http://127.0.0.1:9000/base/api/login' -d user=me -d password=secret
```
##### JSON
```
curl -XPOST http://127.0.0.1:9000/base/api/login -H 'Content-Type: application/json' -d '{
"user": "me",
"password": "secret"
}'
```
##### Multi-part
```
curl -XPOST http://127.0.0.1:9000/base/api/login -F '_json=<-;type=application/json' << _EOF_
{
"user": "me",
"password": "secret"
}
_EOF_
```
##### Response Format
Base module outputs JSON data.
#### User
##### Model definition
Required attributes:
- `login` / `id` (string) : login of the user
- `userName` (text) : Full name of the user
- `roles` (multi-userRole) : Array containing roles of the user (`read`, `write` or `admin`)
- `status` (userStatus) : `Ok` or `Locked` **default=Ok**
- `preference` (string) : JSON object containing user preference **default={}**
Optional attributes:
- `avatar` (string) : avatar of user. It is an image encoded in base 64
- `password` (string) : user password if local authentication is used
Attributes generated by the backend:
- `key` (uuid) : API key to authenticate this user (deprecated)
##### User Manipulation
###### User methods
| HTTP Method | URI | Action |
| GET | /api/logout | Logout |
| POST | /api/login | User login |
| GET | /api/user/current | Get current user |
| POST | /api/user/_search | Find user |
| POST | /api/user | Create a user |
| GET | /api/user/:userId | Get a user |
| DELETE | /api/user/:userId | Delete a user |
| PATCH | /api/user/:userId | Update user details |
| POST | /api/user/:userId/password/set | Set password |
| POST | /api/user/:userId/password/change | Change password |
- `with-key` (boolean)
###### Create a User
A user can be created using the following URL:
```
POST /api/user
```
Required case attributes (cf. models) must be provided.
This call returns attributes of the created user.
This call is authenticated and requires admin role.
**Examples**
Creation of a user:
```
curl -XPOST -H 'Authorization: Bearer ***API*KEY***' -H 'Content-Type: application/json' http://127.0.0.1:9000/base/api/user -d '{
"login": "georges",
"name": "Georges Abitbol",
"roles": ["read", "write"],
"password": "La classe"
}'
```
It returns:
```
{
"createdBy": "myuser",
"name":"Georges Abitbol",
"roles": ["read", "write" ],
"_id": "georges",
"user": "myuser",
"createdAt": 1496561862924,
"status": "Ok",
"id": "georges",
"_type": "user",
"has-key":false
}
```
If external authentication is used (LDAP or AD) password field must not be provided.
#### EnergySOAR events webhook activation
EnergySOAR supports webhooks, but each one needs to be activated, or EnergySOAR needs to be restarted.
##### Methods
| HTTP Method | URI | Action |
| PUT | /api/config/organisation/webhook/endpoint | Add new webhook |
| DELETE | /api/config/organisation/webhook/endpoint/$name | Delete existing webhook |
| POST | /api/config/organisation/webhook/endpoint/$name | Update existing webhook |
| GET | /api/config/organisation/webhook/endpoint/$name | Get webhook configuration |
| GET | /api/config/organisation/webhook/endpoint | Get webhook list |
Example definition:
```
curl -u'socadmin:socadmin' -XPUT http://localhost:9000/base/api/config/organisation/webhook/endpoint \
-H "Content-Type: application/json" \
-d '{
"name": "new_energysoar_base_wehbook",
"url": "http://localhost:5678/webhook/########-####-####-####-############/webhook",
"version": 0,
"wsConfig": {},
"includedTheHiveOrganisations": ["*"],
"excludedTheHiveOrganisations": [],
"auth": {
"type": "basic",
"username": "admin",
"password": "admin"
}
}'
```
To activate configuration add trigger types, and provide correct endpoint name
**Important**
At this moment there is no POST method implemeted.
In order to add new value you need to manually get current config, append your config, and PUT all together as new value
```
curl -u "socadmin:socadmin" "http://127.0.0.1:9000/base/api/config/organisation/notification"
```
You should get something like this on fresh install:
```
{
"path": "notification",
"defaultValue": [],
"value": [
{
"delegate": false,
"trigger": {
"name": "AnyEvent"
},
"notifier": {
"name": "webhook",
"endpoint": "n8n"
}
}
]
}
```
Copy all elements in `value` field, and overwrite this using PUT:
```
curl -XPUT -u "socadmin:socadmin" -H 'Content-type: application/json' "http://127.0.0.1:9000/base/api/config/organisation/notification"
-d '{
"value": [
{
"delegate": false,
"trigger": {
"name": "AnyEvent"
},
"notifier": {
"name": "webhook",
"endpoint": "n8n"
}
},
{
"delegate": false,
"trigger": {
"name": "AlertCreated"
},
"notifier": {
"name": "webhook",
"endpoint": "new_energysoar_base_wehbook"
}
}
]
}'
```
##### Trigger types:
| Event types |
|-------|
| AnyEvent |
| FilteredEvent |
| ActionFinished |
| CaseCreated |
| CaseFlagged |
| CaseUpdated |
| CaseShared |
| CaseClosed |
| AlertClosed |
| AlertCreated |
| AlertImported |
| JobFinished |
| AlertObservableCreated |
| CaseObservableCreated |
| ObservableCreated |
| TaskClosed |
| TaskMandatory |
### Automation API Guide
#### Introduction
Automation module offers a REST API that can be leveraged by various applications and programs to interact with it. The following guide describe the Automation API to allow developers to interface the powerful observable analysis engine with other SIRPs (Security Incident Response Platforms) besides Base module, TIPs (Threat Intelligence Platforms), SIEMs or scripts. Please note that the Web UI of Automation module exclusively leverage the REST API to interact with the back-end.
**Note**: You can use Python library we provide, to facilitate interaction with the REST API of Automation module.
All the exposed APIs share the same [request & response formats](#request--response-formats) and [authentication strategies](#authentication) as described below.
There are also some transverse parameters supported by several calls, in addition to [utility APIs](#miscellaneous-apis).
If you want to create an analyzer, please read the [How to Write and Submit an Analyzer ](how-to-create-an-analyzer.md) guide.
##### Request & Response Formats
Automation module accepts several parameter formats within a HTTP request. They can be used indifferently. Input data can be:
- A query string
- A URL-encoded form
- A multi-part
- JSON
Hence, the requests shown below are equivalent.
###### Query String
```bash
curl -XPOST 'https://127.0.0.1/automation/api/login?user=me&password=secret'
```
###### URL-encoded Form
```bash
curl -XPOST 'https://127.0.0.1/automation/api/login' -d user=me -d password=secret
```
###### JSON
```bash
curl -XPOST https://127.0.0.1/automation/api/login -H 'Content-Type: application/json' -d '{
"user": "me",
"password": "secret"
}'
```
###### Multi-part
```bash
curl -XPOST https://127.0.0.1/automation/api/login -F '_json=<-;type=application/json' << _EOF_
{
"user": "me",
"password": "secret"
}
_EOF_
```
###### Response Format
For each request submitted, Automation module will respond back with JSON data. For example, if the authentication request is successful, Automation module should return the following output:
```json
{"id":"me","name":"me","roles":["read","analyze","orgadmin"]}
```
If not, Automation module should return an authentication error:
```json
{"type":"AuthenticationError","message":"Authentication failure"}
```
##### Authentication
Most API calls require authentication. Credentials can be provided using a **session cookie**, an **API key** or directly using HTTP **basic
authentication** (if this method is specifically enabled).
Session cookies are better suited for browser authentication. Hence, **we recommend authenticating with API keys** when calling the Automation module APIs.
###### Generating API Keys with an orgAdmin Account
API keys can be generated using the Web UI. To do so, connect using an `orgAdmin` account then click on *Organization* and then on the `Create API Key` button in the row corresponding to the user you intend to use for API authentication. Once the API key has been created, click on `Reveal` to display the API key then click on the *copy to clipboard* button if you wish to copy the key to your system's clipboard.
If the user is not yet created, start by clicking on `Add user` to create it then follow the steps mentioned above.
###### Generating API Keys with a superAdmin Account
You can use a `superAdmin` account to achieve the same result as described above. Once authenticated, click on *Users* then on the `Create API Key` button in the row corresponding to the user you intend to use for API authentication. Please **make sure the user is in the right organization** by thoroughly reading its name, which is shown below the user name. Once the API key has been created, click on `Reveal` to display the API key then click on the *copy to clipboard* button if you wish to copy the key to your system's clipboard.
###### Authenticating with an API Key
Once you have generated an API key you can use it, for example, to list the Automation module jobs thanks to the following `curl` command:
```bash
### Using API key
curl -H 'Authorization: Bearer **API_KEY**' https://127.0.0.1/automation/api/job
```
As you can see in the example above, we instructed `curl` to add the *Authorization* header to the request. The value of the header is `Bearer: **API_KEY**`. So if your API key is `GPX20GUAQWwpqnhA6JpOwNGPMfWuxsX3`, the `curl` command above would look like the following:
```bash
### Using API key
curl -H 'Authorization: Bearer GPX20GUAQWwpqnhA6JpOwNGPMfWuxsX3' https://127.0.0.1/automation/api/job
```
###### Using Basic Authentication
Automation module also supports basic authentication but it is disabled by default for security reasons. **If you absolutely need to use it**, you can enable it by adding `auth.method.basic=true` to the configuration file (`/etc/cortex/application.conf` by default). Once you do, restart the Automation module service. You can then, for example, list the Automation module jobs using the following `curl` command:
```bash
### Using basic authentication
curl -u mylogin:mypassword https://127.0.0.1/automation/api/job
```
#### Organization APIs
Automation module offers a set of APIs to create, update and list organizations.
##### Organization Model
An organization (org) is defined by the following attributes:
| Attribute | Description | Type |
| `id` | Copy of the org's name (see next row) | readonly |
| `name` | Name | readonly |
| `status` | Status (`Active` or `Locked`) | writable |
| `description` | Description | writable |
| `createdAt` | Creation date | computed |
| `createdBy` | User who created the org | computed |
| `updatedAt` | Last update | computed |
| `updatedBy` | User who last updated the org | computed |
Please note that `id` and `name` are essentially the same. Also, `createdAt` and `updatedAt` are in *epoch*.
##### List
It is possible to list all the organizations using the following API call, which requires the API key associated with a `superAdmin` account:
```bash
curl -H 'Authorization: Bearer **API_KEY**' 'https://127.0.0.1/automation/api/organization'
```
You can also search/filter organizations using the following query:
```bash
curl -H 'Authorization: Bearer **API_KEY**' -H 'Content-Type: application/json' 'https://127.0.0.1/automation/api/organization/_search' -d '{
"query": {"status": "Active"}
}'
```
Both APIs supports the `range` and `sort` query parameters described in [paging and sorting details](#paging-and-sorting).
##### Create
It is possible to create an organization using the following API call, which requires the API key associated with a `superAdmin` account:
```bash
curl -XPOST -H 'Authorization: Bearer **API_KEY**' -H 'Content-Type: application/json' 'https://127.0.0.1/automation/api/organization' -d '{
"name": "demo",
"description": "Demo organization",
"status": "Active"
}'
```
##### Update
You can update an organization's description and status (`Active` or `Locked`) using the following API call. This requires the API key associated with a `superAdmin` account:
```bash
curl -XPATCH -H 'Authorization: Bearer **API_KEY**' -H 'Content-Type: application/json' 'https://127.0.0.1/automation/api/organization/ORG_ID' -d '{
"description": "New Demo organization",
}'
```
or
```bash
curl -XPATCH -H 'Authorization: Bearer **API_KEY**' -H 'Content-Type: application/json' 'https://127.0.0.1/automation/api/organization/ORG_ID' -d '{
"status": "Active",
}'
```
##### Delete
Deleting an organization just marks it as `Locked` and doesn't remove the associated data from the DB. To "delete" an organization, you can use the API call shown below. It requires the API key associated with a `superAdmin` account.
```bash
curl -XDELETE -H 'Authorization: Bearer **API_KEY**' 'https://127.0.0.1/automation/api/organization/ORG_ID'
```
##### Obtain Details
This API call returns the details of an organization as described in the [Organization model](#organization-model) section.
```bash
curl -H 'Authorization: Bearer **API_KEY**' 'https://127.0.0.1/automation/api/organization/ORG_ID'
```
Let's assume that the organization we are seeking to obtain details about is called *demo*. The `curl` command would be:
```bash
curl -H 'Authorization: Bearer **API_KEY**' 'https://127.0.0.1/automation/api/organization/demo'
```
and it should return:
```json
{
"id": "demo",
"name": "demo",
"status": "Active",
"description": "Demo organization",
"createdAt": 1520258040437,
"createdBy": "superadmin",
"updatedBy": "superadmin",
"updatedAt": 1522077420693
}
```
##### List Users
As mentioned above, you can use the API to return the list of **all** the users declared withing an organization. For that purpose, use the API call shown below with the API key of an `orgAdmin` or `superAdmin` account. It supports the `range` and `sort` query parameters declared in [paging and sorting details](#paging-and-sorting).
```bash
curl -H 'Authorization: Bearer **API_KEY**' 'https://127.0.0.1/automation/api/organization/ORG_ID/user'
```
and should return a list of [users](#user-model).
If one wants to filter/search for some users (active ones for example), there is a search API to use as below:
```bash
curl -XPOST -H 'Authorization: Bearer **API_KEY**' -H 'Content-Type: application/json' 'https://127.0.0.1/automation/api/organization/ORG_ID/user/_search' -d '{
"query": {}
}'
```
It also supports the `range` and `sort` query parameters declared in [paging and sorting details](#paging-and-sorting).
##### List Enabled Analyzers
To list the analyzers that have been enabled within an organization, use the following API call with the API key of an `orgAdmin` user:
```bash
curl -H 'Authorization: Bearer **API_KEY**' 'https://127.0.0.1/automation/api/analyzer'
```
It should return a list of [Analyzers](#analyzer-model).
Please note that this API call does not display analyzers that are disabled. It supports the `range` and `sort` query parameters declared in [paging and sorting details](#paging-and-sorting).
#### User APIs
The following section describes the APIs that allow creating, updating and listing users within an organization.
##### User Model
A user is defined by the following attributes:
| Attribute | Description | Type |
| `id` | ID/login | readonly |
| `name` | Name | writable |
| `roles` | Roles. Possible values are: `read`, `read,analyze`, `read,analyze,orgadmin` and `superadmin` | writable |
| `status` | Status (`Active` or `Locked`) | writable |
| `organization` | organization to which the user belongs (set upon account creation) | readonly |
| `createdAt` | Creation date | computed |
| `createdBy` | User who created the account | computed |
| `updatedAt` | Last update date | computed |
| `updatedBy` | User who last updated the account | computed |
| `hasKey` | true when the user has an API key | computed |
| `hasPassword` | true if the user has a password | computed |
##### List All
This API call allows a `superAdmin` to list and search all the users of all defined organizations:
```bash
curl -H 'Authorization: Bearer **API_KEY**' 'https://127.0.0.1/automation/api/user'
```
This call supports the `range` and `sort` query parameters declared in [paging and sorting details](#paging-and-sorting).
##### List Users within an Organization
This call is described in [organization APIs](#organization-apis).
##### Search
This API call allows a `superAdmin` to perform search on the user accounts created in a Automation module instance:
```bash
curl -XPOST -H 'Authorization: Bearer **API_KEY**' -H 'Content-Type: application/json' 'https://127.0.0.1/automation/api/user/_search' -d '{
"query": {}
}'
```
This call supports the `range` and `sort` query parameters declared in [paging and sorting details](#paging-and-sorting)
##### Create
This API calls allows you to programmatically create user creation. If the call is made by a `superAdmin` user, the request must specify the organization to which the user belong in the `organization` field.
If the call is made by an `orgAdmin` user, the value of `organization` field must be the same as the user who makes the call: `orgAdmin` users are allowed to create users only in their organization.
```bash
curl -XPOST -H 'Authorization: Bearer **API_KEY**' -H 'Content-Type: application/json' 'https://127.0.0.1/automation/api/user' -d '{
"name": "Demo org Admin",
"roles": [
"read",
"analyze",
"orgadmin"
],
"organization": "demo",
"login": "demo"
}'
```
If successful, the call returns a JSON object representing the created user as described [above](#user-model).
```json
{
"id": "demo",
"organization": "demo",
"name": "Demo org Admin",
"roles": [
"read",
"analyze",
"orgadmin"
],
"status": "Ok",
"createdAt": 1526050123286,
"createdBy": "superadmin",
"hasKey": false,
"hasPassword": false
}
```
##### Update
This API call allows updating the writable attributed of a user account. It's available to users with `superAdmin` or `orgAdmin` roles. Any user can also use it to update their own information (but obviously not their roles).
```bash
curl -XPATCH -H 'Authorization: Bearer **API_KEY**' -H 'Content-Type: application/json' 'https://127.0.0.1/automation/api/user/USER_LOGIN' -d '{
"name": "John Doe",
"roles": [
"read",
"analyze"
],
"status": "Locked"
}'
```
It returns a JSON object representing the updated user as described [above](#user-model).
##### Get Details
This call returns the user details. It's available to users with `superAdmin` roles and to users in the same organization. Every user can also use it to read their own details.
```bash
curl -H 'Authorization: Bearer **API_KEY**' 'https://127.0.0.1/automation/api/user/USER_LOGIN'
```
It returns a JSON object representing the user as described [previously](#user-model).
##### Set a Password
This call sets the user's password. It's available to users with `superAdmin` or `orgAdmin` roles. Please note that the request needs to be made using HTTPS with a valid certificate on the server's end to prevent credential sniffing or other PITM (Person-In-The-Middle) attacks.
```bash
curl -XPOST -H 'Authorization: Bearer **API_KEY**' -H 'Content-Type: application/json' 'https://127.0.0.1/automation/api/user/USER_LOGIN/password/set' -d '{
"password": "SOMEPASSWORD"
}'
```
If successful, the call returns 204 (success / no content).
##### Change a password
This call allows a given user to change only **their own** existing password. It is available to all users including `superAdmin` and `orgAdmin` ones. Please note that if a `superAdmin` or an `orgAdmin` needs to update the password of another user, they must use the `/password/set` call described in the previous subsection.
```bash
curl -XPOST -H 'Authorization: Bearer **API_KEY**' -H 'Content-Type: application/json' 'https://127.0.0.1/automation/api/user/USER_LOGIN/password/change' -d '{
"currentPassword": "password",
"password": "new-password"
}'
```
If successful, the call returns 204 (success / no content).
##### Set and Renew an API Key
This calls allows setting and renewing the API key of a user. It's available to users with `superAdmin` or `orgAdmin` roles. Any user can also use it to renew their own API key. Again, the request needs to be made using HTTPS with a valid certificate on the server's end to prevent credential sniffing or other PITM (Person-In-The-Middle) attacks. You know the drill ;-)
```bash
curl -XPOST -H 'Authorization: Bearer **API_KEY**' 'https://127.0.0.1/automation/api/user/USER_LOGIN/key/renew'
```
If successful, it returns the generated API key in a `text/plain`response.
##### Get an API Key
This calls allows getting a user's API key. It's available to users with `superAdmin` or `orgAdmin` roles. Any user can also use it to obtain their own API key.
```bash
curl -H 'Authorization: Bearer **API_KEY**' 'https://127.0.0.1/automation/api/user/USER_LOGIN/key'
```
If successful, the generated API key is returned in `text/plain`response
##### Revoke an API Key
This calls allow revoking a user's API key. This calls allow revoking a user's API key.
```bash
curl -XDELETE -H 'Authorization: Bearer **API_KEY**' 'https://127.0.0.1/automation/api/user/USER_LOGIN/key'
```
A successful request returns nothing (HTTP 200 OK).
#### Job APIs
The following section describes the APIs that allow manipulating jobs. Jobs are basically submissions made to analyzers and the resulting reports.
##### Job Model
A job is defined by the following attributes:
| Attribute | Description | Type |
| `id` | Job ID | computed |
| `organization` | The organization to which the job belongs | readonly |
| `analyzerDefinitionId` | Analyzer definition name | readonly |
| `analyzerId` | Instance ID of the analyzer to which the job is associated | readonly |
| `organization` | Organization to which the user belongs (set upon account creation) | readonly |
| `analyzerName` | Name of the analyzer to which the job is associated | readonly |
| `dataType` | the datatype of the analyzed observable | readonly |
| `status` | Status of the job (`Waiting`, `InProgress`, `Success`, `Failure`, `Deleted`) | computed |
| `data` | Value of the analyzed observable (does not apply to `file` observables) | readonly |
| `attachment` | JSON object representing `file` observables (does not apply to non-`file` observables). It defines the`name`, `hashes`, `size`, `contentType` and `id` of the `file` observable | readonly |
| `parameters` | JSON object of key/value pairs set during job creation | readonly |
| `message` | A free text field to set additional text/context for a job | readonly |
| `tlp` | The TLP of the analyzed observable | readonly |
| `startDate` | Start date | computed |
| `endDate` | End date | computed |
| `createdAt` | Creation date. Please note that a job can be requested but not immediately honored. The actual time at which it is started is the value of `startDate` | computed |
| `createdBy` | User who created the job | computed |
| `updatedAt` | Last update date (only Automation module updates a job when it finishes) | computed |
| `updatedBy` | User who submitted the job and which identity is used by Automation module to update the job once it is finished | computed |
##### List and Search
This call allows a user with `read`,`analyze` or `orgAdmin` role to list and search all the analysis jobs made by their organization.
If you want to list all the jobs:
```bash
curl -XPOST -H 'Authorization: Bearer **API_KEY**' 'https://127.0.0.1/automation/api/job/_search?range=all'
```
If you want to list 10 jobs:
```bash
curl -XPOST -H 'Authorization: Bearer **API_KEY**' 'https://127.0.0.1/automation/api/job/_search'
```
If you want to list 100 jobs:
```bash
curl -XPOST -H 'Authorization: Bearer **API_KEY**' 'https://127.0.0.1/automation/api/job/_search?range=0-100'
```
If you want to search jobs according to various criteria:
```bash
curl -XPOST -H 'Authorization: Bearer **API_KEY**' -H 'Content-Type: application/json' 'https://127.0.0.1/automation/api/job/_search' -d '{
"query": {
"_and": [
{"status": "Success"},
{"dataType": "ip"}
]
}
}'
```
This call supports the `range` and `sort` query parameters declared in [paging and sorting details](#paging-and-sorting)
##### Get Details
This call allows a user with `read`,`analyze` or `orgAdmin` role to get the details of a job. It does not fetch the job report.
```bash
curl -H 'Authorization: Bearer **API_KEY**' 'https://127.0.0.1/automation/api/job/JOB_ID'
```
It returns a JSON response with the following structure:
```json
{
"id": "AWNei4vH3rJ8unegCPB9",
"analyzerDefinitionId": "Abuse_Finder_2_0",
"analyzerId": "220483fde9608c580fb6a2508ff3d2d3",
"analyzerName": "Abuse_Finder_2_0",
"status": "Success",
"data": "8.8.8.8",
"parameters": "{}",
"tlp": 0,
"message": "",
"dataType": "ip",
"organization": "demo",
"startDate": 1526299593923,
"endDate": 1526299597064,
"date": 1526299593633,
"createdAt": 1526299593633,
"createdBy": "demo",
"updatedAt": 1526299597066,
"updatedBy": "demo"
}
```
##### Get Details and Report
This call allows a user with `read`,`analyze` or `orgAdmin` role to get the details of a job including its report.
```bash
curl -H 'Authorization: Bearer **API_KEY**' 'https://127.0.0.1/automation/api/job/JOB_ID/report'
```
It returns a JSON response with the structure below. If the job is not yet completed, the `report` field contains a string representing the job status:
```json
{
"id": "AWNei4vH3rJ8unegCPB9",
"analyzerDefinitionId": "Abuse_Finder_2_0",
"analyzerId": "220483fde9608c580fb6a2508ff3d2d3",
"analyzerName": "Abuse_Finder_2_0",
"status": "Success",
"data": "8.8.8.8",
"parameters": "{}",
"tlp": 0,
"message": "",
"dataType": "ip",
"organization": "demo",
"startDate": 1526299593923,
"endDate": 1526299597064,
"date": 1526299593633,
"createdAt": 1526299593633,
"createdBy": "demo",
"updatedAt": 1526299597066,
"updatedBy": "demo",
"report": {
"summary": {
"taxonomies": [
{
"predicate": "Address",
"namespace": "Abuse_Finder",
"value": "network-abuse@google.com",
"level": "info"
}
]
},
"full": {
"abuse_finder": {
"raw": "...",
"abuse": [
"network-abuse@google.com"
],
"names": [
"Google LLC",
"Level 3 Parent, LLC"
],
"value": "8.8.8.8"
}
},
"success": true,
"artifacts": []
}
}
```
##### Wait and Get Job Report
This call is similar the one described above but allows the user to provide a timeout to wait for the report in case it is not available at the time the query was made:
```bash
curl -H 'Authorization: Bearer **API_KEY**' 'https://127.0.0.1/automation/api/job/JOB_ID/waitreport?atMost=1minute'
```
The `atMost` is a duration using the format `Xhour`, `Xminute` or `Xsecond`.
##### Get Artifacts
This call allows a user with `read`,`analyze` or `orgAdmin` role to get the extracted artifacts from a job if such extraction has been enabled in the corresponding analyzer configuration. Please note that extraction is imperfect and you might have inconsistent or incorrect data.
```bash
curl -H 'Authorization: Bearer **API_KEY**' 'https://127.0.0.1/automation/api/job/JOB_ID/artifacts'
```
It returns a JSON array with the following structure:
```json
[
{
"dataType": "ip",
"createdBy": "demo",
"data": "8.8.8.8",
"tlp": 0,
"createdAt": 1525432900553,
"id": "AWMq4tvLjidKq_asiwcl"
}
]
```
##### Delete
This API allows a user with `analyze` or `orgAdmin` role to delete a job:
```bash
curl -XDELETE -H 'Authorization: Bearer **API_KEY**' 'https://127.0.0.1/automation/api/job/JOB_ID'
```
This marks the job as `Deleted`. However the job's data is not removed from the database.
#### Analyzer APIs
The following section describes the APIs that allow manipulating analyzers.
##### Analyzer Model
An analyzer is defined by the following attributes:
| Attribute | Description | Type |
| `id` | Analyzer ID once enabled within an organization | readonly |
| `analyzerDefinitionId` | Analyzer definition name | readonly |
| `name` | Name of the analyzer | readonly |
| `version` | Version of the analyzer | readonly |
| `description` | Description of the analyzer | readonly |
| `author` | Author of the analyzer | readonly |
| `url` | URL where the analyzer has been published | readonly |
| `license` | License of the analyzer | readonly |
| `dataTypeList` | Allowed datatypes | readonly |
| `baseConfig` | Base configuration name. This identifies the shared set of configuration with all the analyzer's flavors | readonly |
| `jobCache` | Report cache timeout in minutes, visible for `orgAdmin` users only | writable |
| `rate` | Numeric amount of analyzer calls authorized for the specified `rateUnit`, visible for `orgAdmin` users only | writable |
| `rateUnit` | Period of availability of the rate limite: `Day` or `Month`, visible for `orgAdmin` users only | writable |
| `configuration` | A JSON object where key/value pairs represent the config names, and their values. It includes the default properties `proxy_http`, `proxy_https`, `auto_extract_artifacts`, `check_tlp`, and `max_tlp`, visible for `orgAdmin` users only | writable |
| `createdBy` | User who enabled the analyzer | computed |
| `updatedAt` | Last update date | computed |
| `updatedBy` | User who last updated the analyzer | computed |
##### Enable
This call allows a user with an `orgAdmin` role to enable an analyzer.
```bash
curl -XPOST -H 'Authorization: Bearer **API_KEY**' 'https://127.0.0.1/automation/api/organization/analyzer/:analyzerId' -d '{
"name": "Censys_1_0",
"configuration": {
"uid": "XXXX",
"key": "XXXXXXXXXXXXXXXXXXXX",
"proxy_http": "http://proxy:9999",
"proxy_https": "http://proxy:9999",
"auto_extract_artifacts": false,
"check_tlp": true,
"max_tlp": 2
},
"rate": 1000,
"rateUnit": "Day",
"jobCache": 5
}'
```
##### List and Search
These calls allow a user with a `analyze` or `orgAdmin` role to list and search all the enabled analyzers within the organization.
```bash
curl -H 'Authorization: Bearer **API_KEY**' 'https://127.0.0.1/automation/api/analyzer'
```
or
```bash
curl -XPOST -H 'Authorization: Bearer **API_KEY**' -H 'Content-Type: application/json' 'https://127.0.0.1/automation/api/analyzer/_search' -d '{
"query": {}
}'
```
Both calls supports the `range` and `sort` query parameters declared in [paging and sorting details](#paging-and-sorting), and both return a JSON array of analyzer objects as described in [Analyzer Model section](#analyzer-model).
If called by a user with only an `nalyzer` role, the `configuration` attribute is not included on the JSON objects.
##### Get Details
This call allows a user with a `analyze` or `orgAdmin` role to get an analyzer's details.
```bash
curl -H 'Authorization: Bearer **API_KEY**' 'https://127.0.0.1/automation/api/analyzer/ANALYZER_ID'
```
It returns a analyzer JSON object as described in [Analyzer Model section](#analyzer-model).
If called by a user with only an `nalyzer` role, the `configuration` attribute is not included on the JSON objects.
##### Get By Type
This call is mostly used by Energy SOAR Base and allows to quickly get the list of analyzers that can run on the given datatype. It requires an `analyze` or `orgAdmin` role.
```bash
curl -H 'Authorization: Bearer **API_KEY**' 'https://127.0.0.1/automation/api/analyzer/type/DATA_TYPE'
```
It returns a JSON array of analyzer objects as described in [Analyzer Model section](#analyzer-model) without the `configuration` attribute, which could contain sensitive data.
##### Update
This call allows an `orgAdmin` user to update the `name`, `configuration` and `jobCache` of an enabled analyzer.
```bash
curl -XPATCH -H 'Authorization: Bearer **API_KEY**' -H 'Content-Type: application/json' 'https://127.0.0.1/automation/api/analyzer/ANALYZER_ID' -d '{
"configuration": {
"key": "XXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"polling_interval": 60,
"proxy_http": "http://localhost:8080",
"proxy_https": "http://localhost:8080",
"auto_extract_artifacts": true,
"check_tlp": true,
"max_tlp": 1
},
"name": "Shodan_Host_1_0",
"rate": 1000,
"rateUnit": "Day",
"jobCache": null
}'
```
It returns a JSON object describing the analyzer as defined in [Analyzer Model section](#analyzer-model).
##### Run
This API allows a user with a `analyze` or `orgAdmin` role to run analyzers on observables of different datatypes.
For `file` observables, the API call must be made as described below:
```bash
curl -XPOST -H 'Authorization: Bearer **API_KEY**' -H 'Content-Type: application/json' 'https://127.0.0.1/automation/api/analyzer/ANALYZER_ID/run' \
-F 'attachment=@/path/to/observable-file' \
-F '_json=<-;type=application/json' << _EOF_
{
"dataType":"file",
"tlp":0
}
_EOF_
```
for all the other types of observerables, the request is:
```bash
curl -XPOST -H 'Authorization: Bearer **API_KEY**' -H 'Content-Type: application/json' 'https://127.0.0.1/automation/api/analyzer/ANALYZER_ID/run' -d '{
"data":"8.8.8.8",
"dataType":"ip",
"tlp":0,
"message": "A message that can be accessed from the analyzer",
"parameters": {
"key1": "value1",
"key2": "value2"
}
}'
```
This call will fetch a similar job from the cache, and if it finds one, it returns it from the cache, based on the duration defined in `jobCache` attribute of the analyzer.
To force bypassing the cache, one can add the following query parameter: `force=1`
```bash
curl -XPOST -H 'Authorization: Bearer **API_KEY**' -H 'Content-Type: application/json' 'https://127.0.0.1/automation/api/analyzer/ANALYZER_ID/run?force=1' -d '{
"data":"8.8.8.8",
"dataType":"ip",
"tlp":0,
"message": "A message that can be accessed from the analyzer",
"parameters": {
"key1": "value1",
"key2": "value2"
}
}'
```
##### Disable
This API allows an `orgAdmin` to disable an existing analyzer in their organization and delete the corresponding configuration.
```bash
curl -XDELETE -H 'Authorization: Bearer **API_KEY**' 'https://127.0.0.1/automation/api/analyzer/ANALYZER_ID'
```
#### Miscellaneous APIs
##### Paging and Sorting
All the `search` API calls allow sorting and paging parameters, in addition to a query in the request's body. These calls usually have URLs ending with the `_search` keyword but that's not always the case.
The followings are query parameters:
- `range`: `all` or `x-y` where `x` and `y` are numbers (ex: 0-10).
- `sort`: you can provide multiple sort criteria such as: `-createdAt` or `+status`.
Example:
```bash
curl -XPOST -H 'Authorization: Bearer **API_KEY**' -H 'Content-Type: application/json' 'http://127.0.0.1/automation/api/organization/ORG_ID/user?range=0-10&sort=-createdAt&sort=+status' -d '{
"query": {}
}'
```