URL: https://workbench.expel.io/api/v2
The Workbench Public API gives organizations the means to access and manipulate their Expel Workbench data using custom API clients. Want to extract information into your reporting system? Use this API! Have some innovative data science idea for analyzing Expel alert evidence? Use this API! Want to write your own custom browser plugin to make your team's analysts more efficient? Use this API!
The majority of the Workbench API implements the jsonapi spec.
jsonapi-server Post Processing
Only the routes that do not follow the JSON:API spec have been defined in the 'CUSTOM ROUTES' section below.
User authentication is accomplished using the /login
API route. This route is used to pass user authentication credentials
to the API. If authentication is successful, the /login
returns a temporary (default: 13 hours) Bearer Token (access_token
) that can be used to
access the API.
The request body requires a flat json document with three properties: username
, password
, and an otp
.
curl 'https://workbench.expel.io/auth/v0/login' \
-X POST \
-H 'Content-Type: application/json' \
--data-binary '{ "username": "sample_user@expel.io", "password": "secret", "otp": "123456" }'
{
"access_token": "<access_token>",
"created_at": 1532537770,
"expires_in": 46800,
"token_type": "bearer",
"user_id": "0796cba8-3c96-4984-8d51-22222381f870",
"username": "sample_user@expel.io",
"role": "expel_admin",
"organization_id": "2ca75135-5a84-4298-b8ba-b5e0fd6fb576",
"realm": "public"
}
Note: as an alternative to the otp
property, you can pass an X-ExpelInc-Otp
http request header with the otp token. This is useful when interfacing with single login frameworks
The otp
property or X-ExpelInc-Otp
header must be populated with the correct 6 digit two-factor authentication code
(e.g. Google Auth code) for authentication to succeed. If the Workbench API is not given an OTP token, authentication will
fail with a 401 with the response header X-ExpelInc-Otp
set to required
.
After authentication, the rest of the API may be accessed using the Bearer Token returned in the access_token
field. Pass
that token back to the API in the Authorization
header using Bearer
as the credential type.
curl 'https://workbench.expel.io/api/v2/expel_alerts' \
-H 'Authorization: Bearer <access_token>'
Browser authentication uses the same user authentication mechanism described in the previous sections of this document.
However, if you wish for the Workbench API to set a browser cookie in addition to a Bearer Token, you can pass the
optional X-Accepts-Auth-Cookie
http request header set to true
.
curl 'https://workbench.expel.io/auth/v0/login' \
-D - -o /dev/null \
-X POST \
-H 'Content-Type: application/json' \
-H 'X-Accepts-Auth-Cookie: true' \
--data-binary '{ "username": "sample_user@expel.io", "password": "secret", "otp": "123456" }'
. . .
Set-Cookie: token=<access_token>; Path=/; Expires=Thu, 26 Jul 2018 06:05:41 GMT; HttpOnly; Secure
. . .
That cookie will then be used to authenticate all future API calls in a browser. The cookie will expire in tandem with the access_token.
API keys are self-service via Workbench by going to Organization Settings > Service Accounts (only users with API access can view this page and generate API keys - contact sales to upgrade). The API key amounts to a Bearer access_token
without an
expiration that is tied to a specific service account with a standard admin or analyst role. This is particularly useful for daemon
services, automated scripts, ETL jobs, etc. API key Bearer tokens are used in the same manner as the temporary user Bearer tokens as described in the previous sections of this document.
curl 'https://workbench.expel.io/api/v2/expel_alerts' \
-H 'Authorization: Bearer <api_key>'
See jsonapi spec for more details of request and response formatting of this request.
Use this route to query or list records of a particular resource type (e.g. investigations, expel_alerts, security_devices, etc). All common query parameters may be used on this route. See Common Query Parameters for information on the available query parameters.
# querying the expel_alerts resource
curl 'https://workbench.expel.io/api/v2/expel_alerts` \
-H 'Authorization: Bearer <access_token>'
See jsonapi spec for more details of request and response formatting of this request.
Use this route to retrieve a specific document. The include
query parameter may be used on this route.
# Get a specific investigation, and include its related expel_alerts in the response.
curl 'https://workbench.expel.io/api/v2/investigations/10e7bfac-27ff-4381-a0ec-5c479b73342b?include=expel_alerts' \
-H 'Authorization: Bearer <access_token>'
See jsonapi spec for more details of request and response formatting of this request.
Use this route to create a new document of a particular resource type.
# Create a new user account
curl 'https://workbench.expel.io/api/v2/user_accounts' \
-X POST \
-H 'Authorization: Bearer <access_token>' \
-H 'Content-Type: application/json' \
--data-binary '{
"data": {
"type": "user_accounts",
"attributes": {
"display_name": "Sample User",
"email": "sample_user@expel.io",
"role": "organization_analyst"
}
}
}'
See jsonapi spec for more details of request and response formatting of this request.
Use this route to update fields and/or overwrite relationships on a specific document. The include
query parameter may be used on this route to
include related resources in the response.
# Change the title of an investigation AND set (overwrite!) the expel_alerts relationship
curl 'https://workbench.expel.io/api/v2/investigations/155901f0-d5b1-4158-a1a1-85370c6db07f' \
-X PATCH
-H 'Authorization: Bearer <access_token>' \
-H 'Content-Type: application/json' \
--data-binary '{
"data": {
"type": "investigations",
"attributes": {
"title": "Sample Investigation"
},
"relationships": {
"expel_alerts": {
"data": [
{ "id": "d3d4edaa-8acc-40f5-bc0a-5d40c910cac0", "type": "expel_alerts" },
{ "id": "80f72c0f-6f03-421c-8436-61fc9ca6c356", "type": "expel_alerts" }
]
}
}
}
}'
See jsonapi spec for more details of request and response formatting of this request.
Use this route to delete a specific document.
# Delete a timeline entry
curl 'https://workbench.expel.io/api/v2/timeline_entries/ddd488d8-d0e4-4cbe-bfba-aa3e75a9d103' \
-X DELETE
-H 'Authorization: Bearer <access_token>'
See jsonapi spec for more details of request and response formatting of this request.
Use this route to query or list records related to a particular known record. All common query parameters may be used on this route. See Common Query Parameters for information on the available query parameters.
# querying all expel_alerts related to investigation with the id of 6e8def26-a645-49b6-9688-ed2fd5385726
curl 'https://workbench.expel.io/api/v2/investigations/6e8def26-a645-49b6-9688-ed2fd5385726/expel_alerts` \
-H 'Authorization: Bearer <access_token>'
This route is used to query actual related resource records and only offers a GET method. It's behavior is similar
to the GET /:resource route. If you are looking to get information about (or modify) the actual relationship links between
records, see the various GET|POST|PATCH|DELETE /:resource/:id/relationship/:relationship
routes.
See jsonapi spec for more details of request and response formatting of this request.
Use this route to return the meta information about a specific relationship. This route does NOT return the actual related
records (see GET /:resource/:id/:relation
for that). You can use the ?include=<relation>
query parameter to get the
records returned in this call, but this is not recommended as the include
query parameter is resource intensive, is
not paginated, and does not support filtering/sorting. Instead, use this route to discover links and meta information
about the relationship.
# querying information about the vendor_alerts relationship of a specific expel_alert
curl 'https://workbench.expel.io/api/v2/expel_alerts/27340b1e-6f3f-43f1-9ba5-d7c1d9d0dcae/relationships/vendor_alerts` \
-H 'Authorization: Bearer <access_token>'
See jsonapi spec for more details of request and response formatting of this request.
Use this route to append new records to an existing relationship on a specific resource.
# see what expel_alerts are related to a specific investigation
curl 'http://workbench.expel.io/api/v2/investigations/70f5c8c9-5b7f-4295-a1e6-0e6e4dfa8c6e/expel_alerts?fields%5Bexpel_alerts%5D=id' \
-H 'Authorization: Bearer <access_token>' \
| jq '.data[] | .id'
"a61863e5-e15f-4586-9612-a40bf7e2ab64"
"20bce40b-654a-4830-91a2-701524b0668a"
# Append two new expel_alerts to an investigation
curl 'https://workbench.expel.io/api/v2/investigations/70f5c8c9-5b7f-4295-a1e6-0e6e4dfa8c6e/relationships/expel_alerts' \
-X POST \
-H 'Authorization: Bearer <access_token>' \
-H 'Content-Type: application/json' \
--data-binary '{
"data": [
{ "type": "expel_alerts", "id": "6ff0cc08-23b2-4afd-9e98-6aa072c621d5" },
{ "type": "expel_alerts", "id": "6084b93c-506e-4594-87e9-1c0198045b55" }
]
}'
# check to see if the relationships were appended. Note that the expel_alerts that were already related to this
# investigation are still there.
curl 'http://workbench.expel.io/api/v2/investigations/70f5c8c9-5b7f-4295-a1e6-0e6e4dfa8c6e/expel_alerts?fields%5Bexpel_alerts%5D=id' \
-H 'Authorization: Bearer <access_token>' \
| jq '.data[] | .id'
"a61863e5-e15f-4586-9612-a40bf7e2ab64"
"20bce40b-654a-4830-91a2-701524b0668a"
"6ff0cc08-23b2-4afd-9e98-6aa072c621d5"
"6084b93c-506e-4594-87e9-1c0198045b55"
See jsonapi spec for more details of request and response formatting of this request.
Use this route to overwrite a relationship of a specific resource.
# see what expel_alerts are related to a specific investigation
curl 'http://workbench.expel.io/api/v2/investigations/70f5c8c9-5b7f-4295-a1e6-0e6e4dfa8c6e/expel_alerts?fields%5Bexpel_alerts%5D=id' \
-H 'Authorization: Bearer <access_token>' \
| jq '.data[] | .id'
"a61863e5-e15f-4586-9612-a40bf7e2ab64"
"20bce40b-654a-4830-91a2-701524b0668a"
# Overwrite the expel_alerts related to this investigation
curl 'https://workbench.expel.io/api/v2/investigations/70f5c8c9-5b7f-4295-a1e6-0e6e4dfa8c6e/relationships/expel_alerts' \
-X PATCH \
-H 'Authorization: Bearer <access_token>' \
-H 'Content-Type: application/json' \
--data-binary '{
"data": [
{ "type": "expel_alerts", "id": "6ff0cc08-23b2-4afd-9e98-6aa072c621d5" },
{ "type": "expel_alerts", "id": "6084b93c-506e-4594-87e9-1c0198045b55" }
]
}'
# check to see if the relationships were appended. Note that the expel_alerts that were already related to this
# investigation have been overwritten!
curl 'http://workbench.expel.io/api/v2/investigations/70f5c8c9-5b7f-4295-a1e6-0e6e4dfa8c6e/expel_alerts?fields%5Bexpel_alerts%5D=id' \
-H 'Authorization: Bearer <access_token>' \
| jq '.data[] | .id'
"6ff0cc08-23b2-4afd-9e98-6aa072c621d5"
"6084b93c-506e-4594-87e9-1c0198045b55"
This route can also be used to set parent relationships. Note that when setting a parent relationship like this, "data" is NOT an array, since there can only ever be a single value.
# Establish a parent security_device for an existing security_device (self-referencing m:1 relationship)
curl 'https://workbench.expel.io/api/v2/security_devices/4819bb1e-bad4-4b9b-a154-7a9aac9654a2/relationships/parent_security_device' \
-X PATCH \
-H 'Authorization: Bearer <access_token>' \
-H 'Content-Type: application/json' \
--data-binary '{
"data": { "type": "security_device", "id": "1dd4ee04-792a-4052-9968-66cf347fe1b7" }
}'
See jsonapi spec for more details of request and response formatting of this request.
Use this route to unlink specific records in a relationship. Note that unlike traditional HTTP DELETE
calls, this
call requires a body. Only the records listed in the body will be removed from the relationship.
Tip: If you want to remove all records from the relationship, use PATCH /:resource/:id/relationships/:relation
with an
empty array!
# see what expel_alerts are related to a specific investigation
curl 'http://workbench.expel.io/api/v2/investigations/70f5c8c9-5b7f-4295-a1e6-0e6e4dfa8c6e/expel_alerts?fields%5Bexpel_alerts%5D=id' \
-H 'Authorization: Bearer <access_token>' \
| jq '.data[] | .id'
"a61863e5-e15f-4586-9612-a40bf7e2ab64"
"20bce40b-654a-4830-91a2-701524b0668a"
"6ff0cc08-23b2-4afd-9e98-6aa072c621d5"
"6084b93c-506e-4594-87e9-1c0198045b55"
# Remove two expel_alerts from this investigation
curl 'https://workbench.expel.io/api/v2/investigations/70f5c8c9-5b7f-4295-a1e6-0e6e4dfa8c6e/relationships/expel_alerts' \
-X DELETE \
-H 'Authorization: Bearer <access_token>' \
-H 'Content-Type: application/json' \
--data-binary '{
"data": [
{ "type": "expel_alerts", "id": "6ff0cc08-23b2-4afd-9e98-6aa072c621d5" },
{ "type": "expel_alerts", "id": "6084b93c-506e-4594-87e9-1c0198045b55" }
]
}'
# check to see if the relationships were appended. Note that the expel_alerts that were already related to this
# investigation are still there.
curl 'http://workbench.expel.io/api/v2/investigations/70f5c8c9-5b7f-4295-a1e6-0e6e4dfa8c6e/expel_alerts?fields%5Bexpel_alerts%5D=id' \
-H 'Authorization: Bearer <access_token>' \
| jq '.data[] | .id'
"a61863e5-e15f-4586-9612-a40bf7e2ab64"
"20bce40b-654a-4830-91a2-701524b0668a"
Syntax: ?include=<relation>[,<relation>[...]]
The include
query parameter allows you to specify which relationship records you want included in the response. This is
useful when you are querying for a record, and want to resolve specific relationship data without making multiple calls.
# request a specific investigation, and include that investigation's organization and create/update actors in the response.
curl 'http://workbench.expel.io/api/v2/investigations/aa8492a2-b1f2-4ccb-a4dd-ff76d4903ee9?include=organization,created_by,updated_by' \
-H 'Authorization: Bearer <access_token>'
Using the include
query parameter will have the following effects on the API's response:
data
element of the included 1:m ("has many") relationships will be populated with the array of id's{
"data": {
"attributes": {},
"relationships": {
"<relation>": {
"data": [
{ "type": "<resource>", "id": "<uuid>" },
{ "type": "<resource>", "id": "<uuid>" }
]
}
}
},
"included": []
}
included
array at the top level of the response will include the records references in the relationships
sections across all returned records.{
"data": {},
"included": [
{
"type": "<resource>",
"id": "<uuid>",
"attributes": {},
"relationships": {}
},
{
"type": "<resource>",
"id": "<uuid>",
"attributes": {},
"relationships": {}
}
]
}
include
query parameter can be resource intensive.include
query parameter cannot be paginated. It's all or nothing.include
query parameter cannot be filtered or sorted.Because of these limitations, it is not recommended to use include
when listing multiple records (GET /:resource
) that are likely to
have a large number of related records (e.g. /investigations?include=expel_alerts
or /expel_alerts?include=vendor_alerts
).
Instead, in cases like these, it may be more efficient to query the relationships you're interested in using separate calls
or using includes only for specific records.
# query all investigations and return all their expel_alerts (NOT RECOMMENDED! all expel_alerts associated with all
# investigations returned for each page will be returned without pagination)
curl 'http://workbench.expel.io/api/v2/investigations?include=expel_alerts
-H 'Authorization: Bearer <access_token>'
# query all expel alerts for a specific investigation using includes (warning, no pagination on the expel_alerts)
curl 'http://workbench.expel.io/api/v2/investigations/aa8492a2-b1f2-4ccb-a4dd-ff76d4903ee9?include=expel_alerts
-H 'Authorization: Bearer <access_token>'
# query all expel alerts for a specific investigation using relationships (with pagination, filtering, and sorting available)
curl 'http://workbench.expel.io/api/v2/investigations/aa8492a2-b1f2-4ccb-a4dd-ff76d4903ee9/expel_alerts
-H 'Authorization: Bearer <access_token>'
Syntax: ?sort=[+|-]<field>[,[+|-]<field>[...]]
The sort
query parameter allows you to sort by a particular attribute of a resource. Each field may be prefixed by
a +
or -
to signify ascending or descending sorts respectively.
# sort investigations ascending by created_at date.
curl 'http://workbench.expel.io/api/v2/investigations?sort=created_at' \
-H 'Authorization: Bearer <access_token>'
# sort investigations descending by created_at date
curl 'http://workbench.expel.io/api/v2/investigations?sort=-created_at' \
-H 'Authorization: Bearer <access_token>'
# sort investigations by title, and then descending by created_at date
curl 'http://workbench.expel.io/api/v2/investigations?sort=title,-created_at' \
-H 'Authorization: Bearer <access_token>'
Note:
Syntax: ?page[limit|offset]=<value>
Pagination in the Workbench API uses an limit/offset system. For most resources, the limit
is defaulted to 50 if not supplied.
The limit
may be set to zero. This is useful if your api client needs a count of records without needing to retrieve the actual content of those records.
The record offset
is defaulted to 0
if not supplied.
# paginate the first 25 records using page[limit]=25&page[offset]=0
curl 'http://workbench.expel.io/api/v2/investigations?page%5Blimit%5D=25&page%5Boffset%5D=0' \
-H 'Authorization: Bearer <access_token>'
# paginate the next 25 records using page[limit]=25&page[offset]=25
curl 'http://workbench.expel.io/api/v2/investigations?page%5Blimit%5D=25&page%5Boffset%5D=25' \
-H 'Authorization: Bearer <access_token>'
# get a count of investigations without actually returning any investigation records (using page[limit]=0).
curl 'http://workbench.expel.io/api/v2/investigations?page%5Blimit%5D=0' \
-H 'Authorization: Bearer <access_token>' \
| jq '.meta.page.total'
Syntax: ?filter[<field>]=[<operator>]<value>
[]
)Workbench supports filtering on most attributes and relationships on most of the resources it serves.
By default (i.e. if no operator is provided), the case-sensitive equals operator is used.
Note: Because the Workbench API only supports a single character operator (long story...), we had to get a bit clever with unicode characters to support certain operators as the API's operator support grew. Remember that the operators will need to be URL Encoded when actually sent to the Workbench API. For brevity, the following examples are NOT url encoded.
Operator | Url Encoded | Description | Examples |
---|---|---|---|
Equals operator. (Case sensitive, default) | remediation_actions?filter[status]=CLOSED : Remediation actions where status = CLOSED |
||
~ |
~ |
Equals operator. (Case insensitive) | remediation_actions?filter[action]=~SomeValue : Remediation actions where action LIKE 'SomeValue' (case-insensitive) |
! |
%21 |
Not equals operator (Case sensitive) | remediation_actions?filter[status]=!CLOSED : Remediation actions where status != CLOSED |
: |
%3A |
Partial match operator. (Case insensitive) | remediation_actions?filter[action]=:SomeValue : Remediation actions where action ILIKE '%SomeValue%' (case-insensitive) |
∌ |
%E2%88%8C |
Not partial match operator. (Case insensitive) | remediation_actions?filter[comment]=∌SomeValue : Remediation actions where comment NOT ILIKE '%SomeValue%' (case-insensitive) |
^ |
%5E |
Starts with operator. (Case insensitive) | remediation_actions?filter[comment]=^SomeValue : Remediation actions where comment ILIKE 'SomeValue%' (case-insensitive) |
␀ |
%E2%90%80 |
Is null operator. Value should be boolean. =␀ OR =␀true for null. =␀false for NOT null. |
remediation_actions?filter[close_reason]=␀true : Remediation actions where the close_reason IS NULL remediation_actions?filter[close_reason]=␀false : Remediation actions where the close_reason IS NOT NULL |
> |
%3E |
Greater than operator. | remediation_actions?filter[created_at]=>2020-01-01T00:00:00Z : Remediation actions where created_at > 2020-01-01T00:00:00Z |
< |
%3C |
Less than operator. | remediation_actions?filter[created_at]=<2020-01-01T00:00:00Z : Remediation actions where created_at < 2020-01-01T00:00:00Z |
Each model has attributes as detailed in the resources documentation. Most attributes on most resources are filterable.
Examples:
filter[source_reason]=!HUNTING
filter[created_at]=>2019-02-28T00:00:00.000Z
Each object may contain relationships. The relationships exist in response.data[].relationships
.
You can filter based on relationship attributes.
I.e. The investigation
model contains the lead_expel_alert
relationship
containing an expel_alert
. The expel_alert
model has the attribute created_at
.
You can filter attributes of a relationship from the investigations
API endpoint.
Examples:
filter[lead_expel_alert][id]=␀
filter[lead_expel_alert][created_at]=>2019-02-28T00:00:00.000Z
You can apply multiple filters in a single request. All filters are joined using an AND
operation with the exception of the equals operator. Multiple equals filters on the same field will be joined using an OR
operation.
Examples:
remediation_actions?filter[status]=CLOSED&filter[status]=IN_PROGRESS
: filter for remediation actions where status IN (CLOSED, IN_PROGRESS)
remediation_actions?filter[status]=CLOSED&filter[status]=IN_PROGRESS&filter[action]=^SomeValue
: filter for remediation actions where status IN (CLOSED, IN_PROGRESS) AND action ILIKE 'SomeValue%'
investigations?filter[lead_expel_alert][id]=␀false&filter[title]=:SomeValue
: filter for investigations where lead_expel_alert.id IS NOT NULL AND title ILIKE '%SomeValue%'
While many of the most commonly filtered attributes in the API's underlying data sources have been optimized and indexed, please keep in mind that there may be attributes that, when filtered, result in slower API response times. This is especially true of nested filters (filters on relationship values) and also on unanchored text search operators (e.g. :
/contains)
# find investigations where the analyst severity is CRITICAL or HIGH created on or after January 1, 2020.
curl 'http://workbench.expel.io/api/v2/investigations?filter%5Banalyst_severity%5D=CRITICAL&filter%5Banalyst_severity%5D=HIGH&filter%5Bcreated_at%5D=%3E2020-01-01T00%3A00%3A00Z' \
-H 'Authorization: Bearer <access_token>'
# find investigations that have a lead_expel_alert with an expel_name that contains `Windows` (case insensitive)
curl 'http://workbench.expel.io/api/v2/investigations?filter%5Blead_expel_alert%5D%5Bexpel_name%5D=%3AWindows' \
-H 'Authorization: Bearer <access_token>'
Syntax: ?flag[<variable>]=<value>
In addition to filter
query parameter, as specified by the jsonapi spec, our API supports a custom API query parameter of flags
that allows callers to pass variables to the backend.
Flags are defined on a resource by resource basis, and will alter the behavior of a given API call.
Syntax: ?flag[scope]=<scope_name>
The scope
flag enables callers to specify scopes for resources backed by Sequelize. When adding a scope that should
be accessible from the API, after adding the scope to the scopes
object in the resource model definition, add the
scope's name to the api_scopes
array to allow it to be accessible via API. You can specify the scope as a comma-delimited
string (e.g. flag[scope]=firstScope,secondScope
) or as an array (e.g. flag[scope][]=firstScope&flag[scope][]=secondScope
).
remediation_actions?flag[scope]=assigned_to_expel_but_no_user_assigned
: Remediation actions where the assigned_to_org_id === EXPEL_ORGANIZATION_ID && assigned_to_user_id IS NULL
.expel_alerts?flag[scope]=assigned_to_expel_but_no_user_assigned
: Expel alerts where assigned_to_org_id === EXPEL_ORGANIZATION_ID && assigned_to_user_id IS NULL
.investigations?flag[scope]=assigned_to_expel_but_no_user_assigned
: Investigations where assigned_to_org_id === EXPEL_ORGANIZATION_ID && assigned_to_user_id IS NULL
.investigative_actions?flag[scope]=assigned_to_expel_but_no_user_assigned
: Investigative actions where assigned_to_org_id === EXPEL_ORGANIZATION_ID && assigned_to_user_id IS NULL
.
Will check analysis_assigned_to_org_id/analysis_assigned_to_user_id
if the status
of the action is in an analysis state (e.g. !RUNNING
).expel_alerts
assigned_to_organization
: Expel alerts where assigned_to_org_id === organization_id
.assigned_to_organization_user
: Expel alerts where assigned_to_org_id === organization_id AND assigned_to_user_id IS NOT NULL
.assigned_to_organization_but_no_user_assigned
: Expel alerts where assigned_to_org_id === organization_id AND assigned_to_user_id NOT NULL
.assigned_to_expel
: Expel alerts where assigned_to_org_id === EXPEL_ORGANIZATION_ID
.assigned_to_user_account
: Expel alerts where assigned_to_org_id === EXPEL_ORGANIZATION_ID AND assigned_to_user_id IS NOT NULL
.assigned_to_expel_but_no_user_assigned
: Expel alerts where assigned_to_org_id === EXPEL_ORGANIZATION_ID AND assigned_to_user_id NOT NULL
.assigned_to_user
: Expel alerts assigned to the calling user (e.g. "Assigned to me")investigations
assigned_to_organization
: Investigations where assigned_to_org_id === organization_id
.assigned_to_organization_user
: Investigations where assigned_to_org_id === organization_id AND assigned_to_user_id IS NOT NULL
.assigned_to_organization_but_no_user_assigned
: Investigations where assigned_to_org_id === organization_id AND assigned_to_user_id NOT NULL
.assigned_to_expel
: Investigations where assigned_to_org_id === EXPEL_ORGANIZATION_ID
.assigned_to_user_account
: Investigations where assigned_to_org_id === EXPEL_ORGANIZATION_ID AND assigned_to_user_id IS NOT NULL
.assigned_to_expel_but_no_user_assigned
: Investigations where assigned_to_org_id === EXPEL_ORGANIZATION_ID AND assigned_to_user_id NOT NULL
.assigned_to_user
: Investigations assigned to the calling user (e.g. "Assigned to me")open
: Investigations where decision null (open)closed
: Investigations where decision is not null (closed)remediation_actions
assigned_to_organization
: Actions where assigned_to_org_id === organization_id
.assigned_to_organization_user
: Actions where assigned_to_org_id === organization_id AND assigned_to_user_id IS NOT NULL
.assigned_to_organization_but_no_user_assigned
: Actions where assigned_to_org_id === organization_id AND assigned_to_user_id NOT NULL
.assigned_to_expel
: Actions where assigned_to_org_id === EXPEL_ORGANIZATION_ID
.assigned_to_user_account
: Actions where assigned_to_org_id === EXPEL_ORGANIZATION_ID AND assigned_to_user_id IS NOT NULL
.assigned_to_expel_but_no_user_assigned
: Actions where assigned_to_org_id === EXPEL_ORGANIZATION_ID AND assigned_to_user_id NOT NULL
.assigned_to_user
: Actions assigned to the calling user (e.g. "Assigned to me")investigative_actions
completed_auto_actions
: Actions that have result_task_id IS NOT NULL
assigned_to_organization
: Actions where assigned to an organization.assigned_to_organization_user
: Actions where assigned to an organization and a user.assigned_to_organization_but_no_user_assigned
: Actions assigned to an organization but not yet assigned to a user.assigned_to_expel
: Actions where assigned to EXPEL_ORGANIZATION_ID.assigned_to_user_account
: Actions where assigned to EXPEL_ORGANIZATION_ID and a user.assigned_to_expel_but_no_user_assigned
: Actions assigned to EXPEL_ORGANIZATION_ID but not yet assigned to a user.assigned_to_user
: Actions assigned to the calling user (e.g. "Assigned to me")is_assigned_to_a_user
: Actions where current_assigned_actor.actor_type === "user"
.is_assigned_to_an_organization
: Actions where current_assigned_actor.actor_type === "organization"
.With the exception of non-jsonapi resources and tasking resources, you can upload csv files to the jsonapi resources exposed by this API.
There are two ways to import csv:
Option A: text/csv
If you POST with Content-Type of text/csv
, the request body must contain the csv text. Note that field overrides
are NOT supported when posting directly as text/csv
Option B: multipart/form-data
This is useful for browsers. Create an HTML form with a file input field with the name csv
.
NOTE: You can add other fields to the form, and these fields will override the values of the csv
import (useful for establishing relationships), but these fields MUST COME SEQUENTIALLY BEFORE THE csv
FIELD.
The csv MUST contain field headers in the first row. The field headers should match the attribute and relationship names documented in the API; However; the csv upload is more forgiving in its syntax. The field names when uploading a csv are case-insensitive, and spaces MAY be used in lieu of underscores.
Example: Both of the following evaluate to the same field names
event,comment,is_selected,event_date,investigation
Event, Comment, Is Selected, Event Date, Investigation
Sometimes a 3rd party csv doesn't have headers that match the headers the API expects. To resolve these
issues, the request body can contain an attribute called fields
. The value must be formatted as a
JSON array of strings and/or objects. If provided, then the only fields
explicitly added to the fields
array will be included in the import. All other fields will be
ignored. To map custom csv field names to API field names, use an object in the format of
{"from": "csvField", "to": "apiField"}
, The fields request field MUST COME SEQUENTIALLY BEFORE THE csv
FIELD.
Example: adding the fields attribute will rename the incoming csv fields to fields accepted by the API
fields=[ "event", { "from": "message", "to":"comment" }, { "from": "datetime", "to": "event_date"} ]
If there are conflicts (i.e. two csv fields map to the same API field name), then the "winner" will be determined by the order of the fields in the field map, with the first one "winning". NOTE: Only the headers of the csv are checked... the API does NOT check the value of individual rows.
Example: In this example, the message_1
field will be mapped to the event
API field. The message_2
field will be ignored. This is because message_2
comes after the message_1
fields map. If the csv
had not included a "message_1" header, then the "message_2" header would be used. Think of "message_2' as a "fallback".
fields=[ { "from": "message_1", "to":"event" }, { "from": "message_2", "to": "event"} ]
message_1,message_2
"i win", "i lose"
For relationships, use the relationship name as the field name.
Belongs To
(aka Many-To-One
) relationships should contain a single guid.Has Many
(aka One-To-Many
or Many-To-Many
) relationships are a semi-colon delimited list of guids.Upload using Content-Type text/csv with a Many-To-One column included.
curl -X POST 'http://localhost:7550/api/v2/timeline_entry' -H 'Content-Type: text/csv' --data-binary @- <<-EOF
event,comment,is_selected,event_date,investigation
"Lateral movement","Type 3 Network Logon",true,"2018-01-15T21:14:35.000Z",c7195a33-7e66-49d3-a59c-2810f224d03e
"Exploit execution","Process: ""powershell.exe""",true,"2018-01-15T21:14:36.000Z",c7195a33-7e66-49d3-a59c-2810f224d03e
"Beacon deployment","C:\Users\admin\appdata\local\temp\payload.exe",false,"2018-01-15T20:14:35.000Z",c7195a33-7e66-49d3-a59c-2810f224d03e
"MIMIKATZ","C:\Users\admin\appdata\local\temp\1.exe",true,"2018-01-15T20:14:35.000Z",c7195a33-7e66-49d3-a59c-2810f224d03e
EOF
Upload using Content-Type text/csv
with a Many-To-Many column included.
curl -X POST 'http://localhost:7550/api/v2/expel_alerts' -H 'Content-Type: text/csv' --data-binary @- <<-EOF
alert_type,expel_name, Vendor Alerts
CLOUD,Test Alert 1,7962ae2-8b8c-4371-9fc8-376300d3d6e0;1b842323-8f54-4958-b14c-af384dd345cf;
NETWORK,Test Alert 2,
SIEM,Test Alert 3,
ENDPOINT,Test Alert 4,
EOF
Upload using Content-Type multipart/form-data
, overriding the investigation relationship via a form field.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Upload Example</title>
</head>
<body>
<!-- NOTE there are loads of libraries that do this stuff for you, but this example is shown in raw HTML5 and
javascript to as a proof of concept -->
<!-- start with an input field so that the user can select a file -->
<input type="file" name="csv" id="csv" accept=".csv">
<button id="go">Submit</button>
<script>
document.getElementById('go').onclick = function () {
const csv = document.getElementById('csv');
// using XHR2 and FormData to send the file so that we can set the authorization headers before
// sending the file.
const fd = new FormData();
// NOTE: field overrides MUST BE appended BEFORE the file field is appended.
// in this case, we'll override the investigation_id on all imported records so that
// all the timeline entry rows are associated with with my investigation.
fd.append("investigation", "c7195a33-7e66-49d3-a59c-2810f224d03e");
// now we can append the file!
fd.append("csv", csv.files[0]);
const xhr = new XMLHttpRequest();
xhr.open('POST', '/api/v2/timeline_entry', true);
// Set headers after request is open
// replace the <mytoken_here> placeholder with an actual token
xhr.setRequestHeader('Authorization', 'Bearer <mytoken_here>');
// Send the form. Bask in the glory of a successfully uploaded csv file!
xhr.send(fd);
};
</script>
</body>
</html>
Upload using Content-Type multipart/form-data
, overriding the fields AND applying a field map (using curl).
curl -X POST \
http://localhost:7550/api/v2/timeline_entry \
-H 'authorization: Bearer ...' \
-F 'fields=[ "event", { "from": "message", "to":"event" }, { "from": "datetime", "to": "event_date"} ]' \
-F investigation=cc916c39-d099-4761-a4a8-3d7790d88a93 \
-F created_by=d5758a91-4f09-4f77-886c-959983e9a533 \
-F csv=@entries.csv
You can also download csv files from some resource endpoints. We currently only support exporting from vendor_alerts and investigations. The signature for exporting csv is GET /api/v2/[resource]/export
. The endpoint also supports query filter params: to (datetime),
from (datetime) and organization_id (guid) which can be used to further narrow down the result set.
Exporting resources
curl -X GET 'http://localhost:7550/api/v2/vendor_alerts/export'
curl -X GET 'http://localhost:7550/api/v2/investigations/export'
Exporting with filter params
curl -X GET 'http://localhost:7550/api/v2/vendor_alerts/export?filter[to]=2015-01-01'
curl -X GET 'http://localhost:7550/api/v2/investigations/export?filter[from]=2011-01-13'
curl -X GET 'http://localhost:7550/api/v2/vendor_alerts/export?filter[organization_id]=c7195a33-7e66-49d3-a59c-2810f224d03e'
Remediation actions include one or more associated remediation action assets. This is because there can be more than one item per remediation action (for example, do CONTAIN_HOSTS
action against two HOST
assets of value "host-a" and "host-b").
A remediation action asset defines something like the target host (for example, host-a) and/or the target device (for example, Crowdstrike Falcon). Remediation action asset's asset_type
field indicates the type of asset it is (for example, HOST
, DEVICE
, IP_ADDRESS
). Assets also have their own status field, which can be open or completed.
Below is the mapping between remediation action_type
and the asset_type
they support:
BLOCK_COMMAND_AND_CONTROL_COMMUNICATIONS
- Block malicious domains, subdomains, and IPs (for MDR only)
DOMAIN_NAME
- Domain name that should be blocked or sinkholedIP_ADDRESS
- IP address that should be blockedBLOCK_KNOWN_BAD_HASHES
- Block known bad hashes
HASH
- A hash object with value containing information about the file to block; specifically the file hash, its hash type, and optional its filename (e.g. {"hash": "<file hash>", "type": "<type of hash (md5, sha1, sha256, sha512)>", "filenames": ["<file name 1>"]}
)DEVICE
- A label for the security device that the host we recommend block hash belongs to (e.g. Crowdstrike Falcon on East Coast, or Microsoft Defender on East Coast). Used for display purposes. The label normally matches the security device "name" field in the security devices model.BLOCK_MALICIOUS_DOMAINS_AND_IPS
- Block malicious domains, subdomains, URLs, and IPs (for Phishing only)
DOMAIN_NAME
- Domain name that should be blocked or sinkholedIP_ADDRESS
- IP address that should be blockedBLOCK_SENDER_ADDRESS
- Block sender address (for Phishing only)
ACCOUNT
- The sender address that should be blockedBLOCK_SENDER_DOMAIN
- Block sender domain (for Phishing only)
DOMAIN_NAME
- Domain name that should be blockedCONTAIN_HOSTS
- Contain hosts (for MDR only)
HOST
- The recommended host to contain (e.g. host-my-machine)DEVICE
- A label for the security device that the host we recommend containment belongs to (e.g. Crowdstrike Falcon on East Coast, or Microsoft Defender on East Coast). Used for display purposes. The label normally matches the security device "name" field in the security devices model.CONTAIN_INFECTED_REMOVABLE_MEDIA
- Contain infected removable media (for MDR only)
HASH
- A hash object with value containing information about the removable media to contain (e.g. {"mountedAs": "<removable media file path (e.g. E:)>", "deviceSerialNumber": "<device serial number>"}
)DELETE_MALICIOUS_FILES
- Delete malicious files
HASH
- A hash object with value containing information about the malicious file to remove and the hostname containing the file (e.g. {"hostname": "<host name>", "file": "<file path>"}
)KILL_PROCESS
- Kill process
HASH
- A hash object with value containing information about the process to kill and the hostname running the process (e.g. {"hostname": "<host name>", "process_id": "<process ID>", "process_path": "<absolute process path>"}
)DISABLE_AND_MODIFY_AWS_ACCESS_KEYS
- Disable and modify AWS access keys (for MDR only). Deprecated in favor of two separated out DISABLE_AWS_ACCESS_KEYS and ROTATE_AWS_ACCESS_KEYS actions.
ACCESS_KEY
- The recommended compromised access key to disable or modifyDISABLE_AWS_ACCESS_KEYS
- Deactivate AWS access key (for MDR only).
ACCESS_KEY
- A hash object with value containing information about the recommended compromised access key to deactivate (e.g. {"access_key_id": "<access key id>"
)ROTATE_AWS_ACCESS_KEYS
- Rotate AWS access keys (for MDR only).
ACCESS_KEY
- A hash object with value containing information about the recommended compromised access key to delete after creation of a different access key (e.g. {"access_key_id": "<access key id>"
)DISABLE_USER_ACCOUNT
- Disable accounts (for MDR only)
ACCOUNT
- The recommended account name to disable (e.g. my-user-account)DEVICE
- A label for the security device that the host we recommend disabling account belongs to (e.g. Office 365 on East Coast). Used for display purposes. The label normally matches the security device "name" field in the security devices model.MITIGATE_VULNERABILITY
- Mitigate vulnerability (for MDR only)
HASH
- A hash object with value containing information about the vulnerability to mitigate and an optional description (e.g. {"name": "<vulnerability name>", "description": "<description of vulnerability>"}
)OTHER_REMEDIATION
- Any custom free-form remediation title (for MDR only)
DESCRIPTION
- Custom description for this free-form remediationREMOVE_AND_BLOCK_EMAIL_FORWARDING_ADDRESS
- Remove and block email forwarding address(es) (for MDR only)
EMAIL
- The compromised email addressFORWARDING_ADDRESS
- Forwarding addressREMOVE_COMPROMISED_SYSTEMS_FROM_NETWORK_AWS
- Delete compromised instances
HASH
- A hash object with value containing information about the instance to delete and optional connected cloud account ID (e.g. {"cloudAccount": "<cloud account id>", "compromisedInstances": "<instance id>"}
)REMOVE_COMPROMISED_SYSTEMS_FROM_NETWORK_OTHER
- Reimage compromised hosts (for MDR only)
HOST
- The recommended host to reimage (e.g. host-my-machine)REMOVE_INBOX_RULES_FOR_KNOWN_COMPROMISED_ACCOUNTS
- Remove inbox rules for known compromised accounts (for MDR only)
HASH
- A hash object with value containing information about the inbox rule to remove for a given compromised email address (e.g. {"compromisedEmail": "<compromised email address>", "inboxRuleNames": "<inbox rule name>"}
)REMOVE_MALICIOUS_EMAIL
- Remove malicious email (Phishing only)
HASH
- A hash object with value containing information about the sender, subject, and submission date for the email that should be removed (e.g. {"sender": "<sender email address>", "subject": "<email subject>", "submissionDate": "<submission timestamp>"}
)REMOVE_TAP_THREAT_ID
- Remove emails using Proofpoint ThreatIDs (Phishing only)
HASH
- A hash object with value containing information about the thread IDs whose linked emails should be removed (e.g. "623cba1fa44ae31976ea010fdb2c897dcb9c40aa9b4eaa3d6d2a89e1acc86836"
)RESET_CREDENTIALS*
- Reset credentials
ACCOUNT
- The recommended account name to reset credentials for (e.g. my-user-account)Server sent events are a means to stream events from the API server to a client application (such as a browser) over an persistent tcp connection (see EventSource spec for more details).
If you are connecting to an sse stream from a browser, there are some shortcomings in the EventSource spec that require the use of a polyfill (Mainly, that the EventSource implementation on most browsers do not support setting headers). To allow API clients to subscribe to events relevant to their organization scope, a polyfill is required that supports setting request headers (specifically, the Authorization header). In our testing, we used the polyfill provided by https://github.com/EventSource/eventsource.
Also, please note that each SSE connection will consume one of the 3 to 10 total http connections allocated to each distinct domain by each of the major browsers. As an alternative, the Workbench API also supports websockets. See Websockets below.
Subscribing to events is as simple as calling GET /api/v2/sse with the proper Authorization headers.
GET /api/v2/sse
In a browser (using the eventsource polyfill)
<script src="eventsource-polyfill.js"></script>
<script>const evtSrc = new EventSourcePolyfill(`/api/v2/sse`, { headers: { Authorization: 'Bearer <mytoken_here>' }});</script>
Using curl
curl -X POST -s http://localhost:7550/api/v2/sse -H 'Authorization: Bearer <mytoken_here>'
This request will remain open indefinitely, and will follow the specification outlined here: EventSource spec. As events are received by the server, they will be broadcast to the subscribers that are within the scope of the event. To prevent clients (specifically browsers) from timing out a connection due to inactivity in times of infrequent events, a regular heartbeat will be sent to all clients every 30 seconds. This heartbeat will not interfere with the EventSource spec.
If using a browser, add event listeners to subscribe to the custom events supported by the API. EventSource.onmessage WILL NOT FIRE
i.e. do this:
evtSrc.addEventListener('security_device_status_change', (msg) => console.log('security_device_status_change', msg));
not this
evtSrc.onmessage = (msg) => console.log(msg); // never fires because the API doesn't throw a 'message' event.
Currently, all events will contain a record_id
, which will be the id of the record that triggered the event.
These are the supported events:
When using a browser EventSource instance, subscribe to these events using
evtSource.addEventListener('<event>', handler);
e.g.
const evt = new EventSourcePolyfill(url, { headers: { Authorization: 'Bearer <token>'}});
evt.addEventListener('security_device_status_change', (msg) => console.log('security_device_status_change', msg));
curl
# replace <mytoken_here> with an actual auth token
curl -X POST -s http://localhost:7550/api/v2/sse -H 'Authorization: Bearer <mytoken_here>'
:connected
:heartbeat
id: a4124f77-1609-48a9-a05d-8b71e3fea284
event: security_device_status_change
data: {"record_id":"7dd20e87-9e55-488b-b559-ec0ed3b5aece","type":"UPDATE"}
id: d2ed6848-fda5-457e-afc9-f79f9563bcaf
event: expel_alert_critical
data: {"record_id":"7dd20e87-9e55-488b-b559-ec0ed3b5aead","type":"INSERT"}
:heartbeat
:heartbeat
:heartbeat
:heartbeat
:heartbeat
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>SSE Example</title>
</head>
<body onload="connect_sse();">
<!-- NOTE there are loads of libraries that do this stuff for you, but this example is shown in raw HTML5 and
javascript as a proof of concept -->
<div>
<ul id="out">
</ul>
</div>
<!-- using https://github.com/EventSource/eventsource polyfill which supports headers. -->
<script src="eventsource-polyfill.js"></script>
<script>
function connect_sse() {
const out = document.getElementById('out');
function addLine(line) {
const li = document.createElement("li");
li.textContent = line;
out.appendChild(li);
}
addLine('connecting to sse stream');
// see comment about the event source polyfill we're using. https://github.com/EventSource/eventsource
// replace the <mytoken_here> placeholder with an actual authentication token
const sse = new EventSourcePolyfill(`/api/v2/sse`, { headers: { Authorization: 'Bearer <mytoken_here>' }});
sse.onopen = () => addLine('subscribed');
// the sse.onmessage function just subscribes to the 'message' event, which we do not use.
// instead, subscribe to our custom events.
sse.addEventListener('security_device_status_change', msg => addLine(`security_device_status_change: ${msg.data}`));
sse.addEventListener('expel_alert_critical', msg => addLine(`expel_alert_critical: ${msg.data}`));
sse.addEventListener('expel_alert_high', msg => addLine(`expel_alert_high: ${msg.data}`));
}
</script>
</body>
</html>
The Workbench API supports Websockets using the socket.io
javascript library. Currently, the only websocket namespace supported
by the API is /sse
, which will emit the same events as are emitted by Server Sent Events (/api/v2/sse
).
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Socket.io Test Page</title>
</head>
<body onload="connect_socketio()">
<h1>Socket.io Test Page</h1>
<div>
<input type="text" id="token" />
<button id="reset">Reset</button>
</div>
<div>
<ul id="out"></ul>
</div>
<script>
function connect_socketio() {
const out = document.getElementById('out');
const token = document.getElementById('token');
const reset = document.getElementById('reset');
function addLine(line) {
const li = document.createElement("li");
li.textContent = line;
out.appendChild(li);
}
let socket;
function doReset() {
if (socket) { socket.disconnect(); }
socket = io('/sse', { query: { 'token': token.value }, path: '/api/v2/socket.io' });
socket.on('error', err => addLine(`error: ${err.toString()}`));
socket.on('connect', () => addLine('connected'));
socket.on('disconnect', () => addLine('disconnected'));
socket.on('security_device_status_change', msg => addLine(JSON.stringify(msg)));
socket.on('expel_alert_critical', msg => addLine(JSON.stringify(msg)));
socket.on('expel_alert_high', msg => addLine(JSON.stringify(msg)));
}
reset.onclick = doReset;
doReset();
}
</script>
<script src="./socket.io.dev.js"></script>
</body>
</html>
Alert count by severity
filter | object filters to apply when querying for data |
filter[alert_type] | string filter by alert type |
filter[close_reason] | string filter by close reason |
filter[organization_id] | string filter by organization |
filter[status] | string filter by status |
flag | object flags that alter the output or behavior of the api |
flag[scope] | string filter by assigned to scope |
Deletes a context variable and all associated labels provided none of those labels have been created by Expel actors. This is more permissive and powerful than DELETE /context_variables/:id which will not allow a context variable to be deleted if any label is referencing it.
id required | string context variable ID to delete |
Creates a new context variable, context categories, and optionally a tagged context label referencing the new variable if tags are provided.
required | object |
{- "data": {
- "name": "string",
- "description": "string",
- "context_type": "cidr_block",
- "value_type": "cidr_block",
- "surface_context": true,
- "value": "string",
- "categories": "string",
- "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
- "tags": "string",
- "annotate": false,
- "is_array": false
}
}
Creates context variables, context categories, and optionally tagged context labels referencing the variables based on the rows in a CSV (see template in Workbench).
csv required | string <binary> |
organization_id required | string <uuid> |
annotate | boolean whether an annotate label should be created when there are no tags |
tags | string comma separated list of tag names |
Downloading expel_alerts csv data
filter | object filters to apply when querying for data |
filter[from] | string end date from which to pull csv data |
filter[to] | string start date from which to pull csv data |
flag | object flags that alter the output or behavior of the api |
flag[bool_format] | string the bool format to use. One of "short", "long", "tf", "yn", or "yesno" |
flag[date_format] | string the date format to use. One of "iso" or "excel" |
Downloading vendor_alerts csv data
filter | object filters to apply when querying for data |
filter[from] | string end date from which to pull csv data |
filter[to] | string start date from which to pull csv data |
flag | object flags that alter the output or behavior of the api |
flag[bool_format] | string the bool format to use. One of "short", "long", "tf", "yn", or "yesno" |
flag[date_format] | string the date format to use. One of "iso" or "excel" |
Downloading context label csv data
filter | object filters to apply when querying for data |
filter[alert_type] | string the alert_type to pull, SUPPRESS, BOLO or CCTX |
filter[from] | string end date from which to pull csv data |
filter[to] | string start date from which to pull csv data |
flag | object flags that alter the output or behavior of the api |
flag[bool_format] | string the bool format to use. One of "short", "long", "tf", "yn", or "yesno" |
flag[date_format] | string the date format to use. One of "iso" or "excel" |
Downloading auto rememdiation settings csv data
filter | object filters to apply when querying for data |
filter[from] | string end date from which to pull csv data |
filter[to] | string start date from which to pull csv data |
flag | object flags that alter the output or behavior of the api |
flag[bool_format] | string the bool format to use. One of "short", "long", "tf", "yn", or "yesno" |
flag[date_format] | string the date format to use. One of "iso" or "excel" |
Downloading auto remediation actions csv data
filter | object filters to apply when querying for data |
filter[from] | string end date from which to pull csv data |
filter[to] | string start date from which to pull csv data |
flag | object flags that alter the output or behavior of the api |
flag[bool_format] | string the bool format to use. One of "short", "long", "tf", "yn", or "yesno" |
flag[date_format] | string the date format to use. One of "iso" or "excel" |
Downloading investigations csv data
filter | object filters to apply when querying for data |
filter[from] | string end date from which to pull csv data |
filter[to] | string start date from which to pull csv data |
flag | object flags that alter the output or behavior of the api |
flag[bool_format] | string the bool format to use. One of "short", "long", "tf", "yn", or "yesno" |
flag[date_format] | string the date format to use. One of "iso" or "excel" |
Downloading service_metrics csv data
filter | object filters to apply when querying for data |
filter[close_reasons] | string filter by expel alert close_reason. Include multiple filters to filter by multiple close_reasons (e.g. filter[close_reason]=SUPPRESSED&filter[close_reason]=SUPPRESSED_NEW_DEVICE). Add ! prefix to severity to exclude close_reasons (e.g. filter[close_reason]=!SUPPRESSED&filter[close_reason]=!SUPPRESSED_NEW_DEVICE) |
filter[from] | string end date from which to pull csv data |
filter[severity] | string filter by expel alert severity. Include multiple filters to filter by multiple severities (e.g. filter[expel_severity]=CRITICAL&filter[expel_severity]=HIGH). Add ! prefix to severity to exclude a severity (e.g. filter[expel_severity]=!TESTING) |
filter[to] | string start date from which to pull csv data |
flag | object flags that alter the output or behavior of the api |
flag[bool_format] | string the bool format to use. One of "short", "long", "tf", "yn", or "yesno" |
flag[date_format] | string the date format to use. One of "iso" or "excel" |
Downloading activity_metrics csv data
filter | object filters to apply when querying for data |
filter[from] | string end date from which to pull csv data |
filter[to] | string start date from which to pull csv data |
flag | object flags that alter the output or behavior of the api |
flag[bool_format] | string the bool format to use. One of "short", "long", "tf", "yn", or "yesno" |
flag[date_format] | string the date format to use. One of "iso" or "excel" |
Downloading timeline_entries csv data
filter | object filters to apply when querying for data |
filter[from] | string end date from which to pull csv data |
filter[investigation_id] | string filter csv data by investigation guid |
filter[to] | string start date from which to pull csv data |
flag | object flags that alter the output or behavior of the api |
flag[bool_format] | string the bool format to use. One of "short", "long", "tf", "yn", or "yesno" |
flag[date_format] | string the date format to use. One of "iso" or "excel" |
Downloading nist subcategory score csv data
filter | object filters to apply when querying for data |
filter[organization_id] | string filter csv data by organization guid (required for multi-organization users) |
flag | object flags that alter the output or behavior of the api |
flag[bool_format] | string the bool format to use. One of "short", "long", "tf", "yn", or "yesno" |
flag[date_format] | string the date format to use. One of "iso" or "excel" |
Downloading phishing submission malicious subject csv data
filter | object filters to apply when querying for data |
filter[endAt] | string end date from which to pull csv data |
filter[organization_id] | string filter csv data by organization guid (required for multi-organization users) |
filter[range] | string interval from which to pull csv data (24hours, 7days, 30days, 1year) |
filter[startAt] | string start date from which to pull csv data |
flag | object flags that alter the output or behavior of the api |
flag[bool_format] | string the bool format to use. One of "short", "long", "tf", "yn", or "yesno" |
flag[date_format] | string the date format to use. One of "iso" or "excel" |
Downloading phishing submission malicious sender domain csv data
filter | object filters to apply when querying for data |
filter[endAt] | string end date from which to pull csv data |
filter[organization_id] | string filter csv data by organization guid (required for multi-organization users) |
filter[range] | string interval from which to pull csv data (24hours, 7days, 30days, 1year) |
filter[startAt] | string start date from which to pull csv data |
flag | object flags that alter the output or behavior of the api |
flag[bool_format] | string the bool format to use. One of "short", "long", "tf", "yn", or "yesno" |
flag[date_format] | string the date format to use. One of "iso" or "excel" |
Downloading phishing submission frequent domain csv data
filter | object filters to apply when querying for data |
filter[endAt] | string end date from which to pull csv data |
filter[organization_id] | string filter csv data by organization guid (required for multi-organization users) |
filter[range] | string interval from which to pull csv data (24hours, 7days, 30days, 1year) |
filter[startAt] | string start date from which to pull csv data |
flag | object flags that alter the output or behavior of the api |
flag[bool_format] | string the bool format to use. One of "short", "long", "tf", "yn", or "yesno" |
flag[date_format] | string the date format to use. One of "iso" or "excel" |
Downloading phishing submission frequent submitter csv data
filter | object filters to apply when querying for data |
filter[endAt] | string end date from which to pull csv data |
filter[organization_id] | string filter csv data by organization guid (required for multi-organization users) |
filter[range] | string interval from which to pull csv data (24hours, 7days, 30days, 1year) |
filter[startAt] | string start date from which to pull csv data |
flag | object flags that alter the output or behavior of the api |
flag[bool_format] | string the bool format to use. One of "short", "long", "tf", "yn", or "yesno" |
flag[date_format] | string the date format to use. One of "iso" or "excel" |
Downloading context variable csv data
filter | object filters to apply when querying for data |
filter[context_categories][name] | string[] filter data by context variable categories |
filter[description] | string[] filter data by partial match on context variable description. Array of strings combined with 'AND' |
filter[from] | string start date from which to pull csv data |
filter[name] | string[] filter data by partial match on context variable name. Array of strings combined with 'AND' |
filter[organization_id] | string filter data by organization guid |
filter[to] | string end date from which to pull csv data |
filter[value] | string[] filter data by partial match on context variable value. Array of strings combined with 'AND' |
flag | object flags that alter the output or behavior of the api |
flag[context_types] | string[] used with 'context_type' scope, flag to filter data by context type |
flag[excel_dates] | string the date format to use. One of "iso" or "excel" |
flag[scope] | string[] apply special filtering with 'search' and 'context_type' scopes |
flag[search_string] | string used with 'search' scope, filter data by partial match on context variable name or value. Ignored if name or value filters exist |
flag[value_types] | string[] used with context_type scope, flag to filter data by context type 'other' and the provided value_types |
sort | string option to sort data by context variable name, context_type, value_type, updated_at, created_at or description |
Downloading phishing submission outcome csv data
excel_dates | boolean Default: false Whether to use excel date format instead of iso. |
filter | object filters to apply when querying for data |
filter[endAt] | string end date from which to pull csv data |
filter[organization_id] | string filter csv data by organization guid (required for multi-organization users) |
filter[range] | string interval from which to pull csv data (24hours, 7days, 30days, 1year) |
filter[startAt] | string start date from which to pull csv data |
flag | object flags that alter the output or behavior of the api |
flag[bool_format] | string the bool format to use. One of "short", "long", "tf", "yn", or "yesno" |
flag[date_format] | string the date format to use. One of "iso" or "excel" |
flag[excel_dates] | boolean Default: false Whether to use excel date format instead of iso. |
Downloading event search log csv data
filter | object filters to apply when querying for data |
filter[from] | string start date from which to pull csv data |
filter[organization_id] | string filter data by organization guid |
filter[to] | string end date from which to pull csv data |
Downloading classified hunt leads csv data
filter | object filters to apply when querying for data |
filter[classification] | string[] filter hunt leads by classification (ignored when investigation_finding_id is set) |
filter[investigation_finding_id] | string the id of the investigation finding |
filter[investigative_action_id] | string the id of the leads investigative action |
flag | object flags that alter the output or behavior of the api |
flag[filename] | string flag to set the filename |
Downloading indicators of compromise csv data
filter | object filters to apply when querying for data |
filter[emerging_threat_id] | string filter data by emerging threat guid |
filter[organization_id] | string filter data by organization guid |
flag | object flags that alter the output or behavior of the api |
flag[filename] | string flag to set the filename |
aggregate time to triage data grouped by severity for every alert in the past 90 days
filter | object filters to apply when querying for data |
filter[end_at] | string only consider alerts created before this date |
filter[organization_id] | string an array of organization IDs to scope the response to |
filter[range] | string Enum: "7days" "30days" "90days" "180days" a string representing a specific date range |
filter[start_at] | string only consider alerts created after this date |
list of all non-testing severity alerts that breach expel's time to triage targets
filter | object filters to apply when querying for data |
filter[end_at] | string only consider alerts created before this date |
filter[organization_id] | string an array of organization IDs to scope the response to |
filter[range] | string Enum: "7days" "30days" "90days" "180days" a string representing a specific date range |
filter[sort] | string Default: "timeToTriage" Enum: "severity" "timeToTriage" if severity, the alerts will be sorted from highest to lowest severity and then highest to lowest time to triage. if timeToTriage, the alerts will be sorted from highest to lowest time to triage and then highest to lowest severity. |
filter[start_at] | string only consider alerts created after this date |
count of all non-testing severity alerts that breach Expel's time to triage targets
filter | object filters to apply when querying for data |
filter[end_at] | string only consider alerts created before this date |
filter[organization_id] | string an array of organization IDs to scope the response to |
filter[range] | string Enum: "7days" "30days" "90days" "180days" a string representing a specific date range |
filter[start_at] | string only consider alerts created after this date |
uniformly random sample of alerts at each non-testing severity with time to triage
filter | object filters to apply when querying for data |
filter[end_at] | string only consider alerts created before this date |
filter[organization_id] | string an array of organization IDs to scope the response to |
filter[range] | string Enum: "7days" "30days" "90days" "180days" a string representing a specific date range |
filter[start_at] | string only consider alerts created after this date |
flag | object flags that alter the output or behavior of the api |
flag[sample_size] | string [ 1 .. 1000 ] Default: 1000 maximum number of alerts in the random sample |
median and mean alert counts grouped by day of the week and hour
filter | object filters to apply when querying for data |
filter[end_at] | string only consider alerts created before this date |
filter[organization_id] | string an array of organization IDs to scope the response to |
filter[range] | string Enum: "7days" "30days" "90days" "180days" a string representing a specific date range |
filter[start_at] | string only consider alerts created after this date |
returns useful statistics to measure the impact of automation and customer context
filter | object filters to apply when querying for data |
filter[end_at] | string only consider alerts created before this date |
filter[organization_id] | string an array of organization IDs to scope the response to |
filter[range] | string Enum: "7days" "30days" "90days" "180days" a string representing a specific date range |
filter[start_at] | string only consider alerts created after this date |
Alert analysis devices w/metrics for org
filter | object filters to apply when querying for data |
filter[range] | string filter returned metrics by date range |
filter[security_device_id] | string filter to a specific security_device_id (can be repeated to include more than one device) |
flag | object flags that alter the output or behavior of the api |
flag[graph] | string enables/disables the graph output on this request. Disabling the graph output will make the request return faster. Use true or 1 to include the graph (this is the default), or false or 0 to exclude the graph. |
Alert analysis idle devices w/metrics for org
filter | object filters to apply when querying for data |
filter[range] | string filter returned metrics by date range |
filter[security_device_id] | string filter to a specific security_device_id (can be repeated to include more than one device) |
flag | object flags that alter the output or behavior of the api |
flag[graph] | string enables/disables the graph output on this request. Disabling the graph output will make the request return faster. Use true or 1 to include the graph (this is the default), or false or 0 to exclude the graph. |
mean and median time from alert creation to first remediation action completed by customer
filter | object filters to apply when querying for data |
filter[end_at] | string only consider alerts created before this date |
filter[organization_id] | string an array of organization IDs to scope the response to |
filter[range] | string Enum: "7days" "30days" "90days" "180days" a string representing a specific date range |
filter[start_at] | string only consider alerts created after this date |
times from creation of expel alerts to completion of first remediation action by customer
filter | object filters to apply when querying for data |
filter[end_at] | string only consider alerts created before this date |
filter[organization_id] | string an array of organization IDs to scope the response to |
filter[range] | string Enum: "7days" "30days" "90days" "180days" a string representing a specific date range |
filter[start_at] | string only consider alerts created after this date |
filter[with_verify] | string Default: false if value is true only consider alerts with verify actions, if false only consider alerts without verify actions |
mean and median time from the creation of a remediation action to its completion
filter | object filters to apply when querying for data |
filter[end_at] | string only consider remediation actions created before this date |
filter[organization_id] | string an array of organization IDs to scope the response to |
filter[range] | string Enum: "7days" "30days" "90days" "180days" a string representing a specific date range |
filter[start_at] | string only consider remediation actions created after this date |
times from the creation of remediation actions to their completion
filter | object filters to apply when querying for data |
filter[organization_id] | string an array of organization IDs to scope the response to |
filter[range] | string Enum: "7days" "30days" "90days" "180days" a string representing a specific date range |
filter[source_reason] | string Default: "all" Enum: "phishing" "mdr" "all" only considers remediation actions where the parent incident has this source reason |
filter[start_at] | string only consider remediation actions created after this date |
page | object pagination parameters |
page[limit] | string Default: 50 number of records from the offset |
page[offset] | string Default: 0 starting offset for paginating results |
mean and median duration between first verification action assigned and first verification action acknowledged
filter | object filters to apply when querying for data |
filter[end_at] | string only consider verify actions created before this date |
filter[organization_id] | string an array of organization IDs to scope the response to |
filter[range] | string Enum: "7days" "30days" "90days" "180days" a string representing a specific date range |
filter[start_at] | string only consider verify actions created after this date |
list of acknowledged verify actions sorted by time to verify descending
filter | object filters to apply when querying for data |
filter[end_at] | string only consider verify actions created before this date |
filter[organization_id] | string an array of organization IDs to scope the response to |
filter[range] | string Enum: "7days" "30days" "90days" "180days" a string representing a specific date range |
filter[start_at] | string only consider verify actions created after this date |
Performs a search of inbound events we ran against our detection engine
which may or may not have led to Expel alerts warranting further investigation.
NOTE: at least one of name, ip, hostname, username, or fileHash must be provided.
NOTE: search parameters are combined using AND to build more restrictive
sets of results as each filter is added.
NOTE: for the purpose of using from and to filters we default to the generated
timestamp for the event if we can determine that from the data, otherwise
we use the timestamp Expel ingested the event meaning it may be best to
cast a wider net using the time range filters when looking for a specific event.
filter | object filters to apply when querying for data |
filter[fileHash] | string file hash to look for in the event (case-insensitive) |
filter[from] | string only consider events generated or arriving after this date |
filter[hostname] | string hostname to look for in the event (case-insensitive) |
filter[ip] | string IP address to look for in the event |
filter[organization][id] | string an array of organization IDs to scope the search results to |
filter[phrase] | string case-insensitive search phrase contained within a parsed text field of the event |
filter[to] | string only consider events generated or arriving before this date |
filter[username] | string username to look for in the event (case-insensitive) |
filter[vendor][name] | string an array of vendor names to scope the search results to |
Aggregates data for emerging threats and related data such as number of detections and lookback results
filter | object filters to apply when querying for data |
filter[organization][id] | string return data for global emerging threats and emerging threats scoped to this organization, otherwise return data for all global emerging threats and emerging threats from all in scope organizations |
page | object pagination parameters |
page[limit] | string Default: 50 number of records from the offset |
page[offset] | string Default: 0 starting offset for paginating results |
Returns an array of timeline entries sorted in chronological order where each entry object, derived from a history record of and its relations, represents one particular event on the timeline of the investigation
id required | string ID of investigation to fetch history timeline data for |
Returns an array of timeline entries sorted in chronological order where each entry object, derived from a history record of and its relations, represents one particular event on the timeline of the expel_alert
id required | string ID of expel alert to fetch history timeline data for |
Checking the health of the Workbench API with full authentication
filter | object filters to apply when querying for data |
filter[component] | string only run checks for the given components; if NONE then does simple heartbeat. If this filter is missing, then runs all checks. |
Checking the health of the Workbench API
filter | object filters to apply when querying for data |
filter[component] | string only run checks for the given components; if NONE then does simple heartbeat. If this filter is missing, then runs all checks. |
Provides lookback data including aggregate lookback results, scope, and the name of the parent emerging threat
filter | object filters to apply when querying for data |
filter[emerging_threat][id] | string an emerging threat ID to scope the search to |
filter[organization][id] | string an organization ID to scope the search to |
page | object pagination parameters |
page[limit] | string Default: 50 number of records from the offset to return |
page[offset] | string Default: 0 starting offset for paginating results |
Creates remediation_action along with its associated remediation_action_assets
required | object |
{- "data": {
- "attributes": {
- "action": "string",
- "action_type": null,
- "asset_state_counts": { },
- "can_automate": true,
- "can_automate_completely": true,
- "cannot_automate_reason": null,
- "close_reason": "string",
- "comment": "string",
- "created_at": "string",
- "deleted_at": "string",
- "status": null,
- "status_updated_at": "string",
- "template_name": "string",
- "updated_at": "string",
- "version": null
}, - "relationships": {
- "assigned_to_actor": {
- "data": {
- "id": "string",
- "meta": { },
- "type": "string"
}, - "links": {
- "related": "string",
- "self": "string"
}, - "meta": { }
}, - "investigation": {
- "data": {
- "id": "string",
- "meta": { },
- "type": "string"
}, - "links": {
- "related": "string",
- "self": "string"
}, - "meta": { }
}, - "security_device": {
- "data": {
- "id": "string",
- "meta": { },
- "type": "string"
}, - "links": {
- "related": "string",
- "self": "string"
}, - "meta": { }
}, - "remediation_action_assets": [
- {
- "data": {
- "attributes": {
- "asset_type": null,
- "automate_revert": true,
- "automate_status": null,
- "automate_status_updated_at": "string",
- "automate_task_error": { },
- "automate_task_id": "string",
- "automate_task_result_id": null,
- "automate_task_results": { },
- "cannot_automate_reason": null,
- "category": null,
- "created_at": "string",
- "status": null,
- "updated_at": "string",
- "value": null
}
}
}
]
}
}
}
Creates a context label associated with a suppress action based on the provided attributes.
conditions required | object |
description required | string |
ends_at required | string <date> |
organization_id required | string <uuid> |
title required | string |
conditions_operator | string Default: "AND" Enum: "OR" "AND" |
severity_threshold | string or null Enum: "CRITICAL" "HIGH" "MEDIUM" "LOW" "TESTING" "TUNING" |
starts_at | string <date> Default: "new Date()" |
{- "title": "string",
- "description": "string",
- "starts_at": "new Date()",
- "ends_at": "2019-08-24",
- "conditions": { },
- "conditions_operator": "OR",
- "severity_threshold": "CRITICAL",
- "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6"
}
Updates a context label associated with a suppress action based on the provided attributes. Expired suppressions can be deleted at anytime.
conditions | object |
conditions_operator | string Enum: "OR" "AND" |
description | string |
ends_at | string <date> |
severity_threshold | string or null Enum: "CRITICAL" "HIGH" "MEDIUM" "LOW" "TESTING" "TUNING" |
starts_at | string <date> |
title | string |
{- "title": "string",
- "description": "string",
- "starts_at": "2019-08-24",
- "ends_at": "2019-08-24",
- "conditions": { },
- "conditions_operator": "OR",
- "severity_threshold": "CRITICAL"
}
object | |
id | string <guid> |
object | |
meta | object |
object | |
type | string |
{- "activity": "string",
- "created_at": "2019-01-15T15:35:00-05:00",
- "data": { },
- "ended_at": "2019-01-15T15:35:00-05:00",
- "started_at": "2019-01-15T15:35:00-05:00",
- "updated_at": "2019-01-15T15:35:00-05:00",
}
object | |
id | string <guid> |
object | |
meta | object |
object | |
type | string |
{- "actor_type": "system",
- "created_at": "2019-01-15T15:35:00-05:00",
- "display_name": "string",
- "is_expel": true,
- "updated_at": "2019-01-15T15:35:00-05:00"
}
object | |
id | string <guid> |
object | |
meta | object |
object | |
type | string |
{- "action": "VIEW",
- "context": [ ],
- "created_at": "2019-01-15T15:35:00-05:00",
- "source": "string",
- "target": "string",
- "updated_at": "2019-01-15T15:35:00-05:00"
}
object | |
id | string <guid> |
object | |
meta | object |
object | |
type | string |
{- "access_token": "string",
- "active": true,
- "assignable": true,
- "created_at": "2019-01-15T15:35:00-05:00",
- "display_name": "string",
- "name": "string",
- "realm": "public",
- "restrictions": [ ],
- "role": "expel_admin",
- "updated_at": "2019-01-15T15:35:00-05:00"
}
object | |
id | string <guid> |
object | |
meta | object |
object | |
type | string |
{- "created_at": "2019-01-15T15:35:00-05:00",
- "hash_md5": "string",
- "hash_sha1": "string",
- "hash_sha256": "string",
- "platform": "VMWARE",
- "release_date": "2019-01-15T15:35:00-05:00",
- "size": 100,
- "updated_at": "2019-01-15T15:35:00-05:00",
- "version": "string"
}
object | |
id | string <guid> |
object | |
meta | object |
object | |
type | string |
{- "connection_status": "Never Connected",
- "connection_status_updated_at": "2019-01-15T15:35:00-05:00",
- "created_at": "2019-01-15T15:35:00-05:00",
- "deleted_at": "2019-01-15T15:35:00-05:00",
- "install_code": "string",
- "lifecycle_status": "New",
- "lifecycle_status_updated_at": "2019-01-15T15:35:00-05:00",
- "location": "string",
- "name": "string",
- "status": "string",
- "status_updated_at": "2019-01-15T15:35:00-05:00",
- "updated_at": "2019-01-15T15:35:00-05:00",
- "vpn_ip": "string"
}
object | |
id | string <guid> |
object | |
meta | object |
object | |
type | string |
{- "action": "CREATED",
- "created_at": "2019-01-15T15:35:00-05:00",
- "value": { }
}
object | |
id | string <guid> |
object | |
meta | object |
object | |
type | string |
{- "comment": "string",
- "created_at": "2019-01-15T15:35:00-05:00",
- "updated_at": "2019-01-15T15:35:00-05:00"
}
object | |
id | string <guid> |
object | |
meta | object |
object | |
type | string |
{- "created_at": "2019-01-15T15:35:00-05:00",
- "default_value": "object",
- "description": "string",
- "is_override": true,
- "key": "string",
- "metadata": { },
- "title": "string",
- "updated_at": "2019-01-15T15:35:00-05:00",
- "validation": { },
- "value": "object",
- "visibility": "EXPEL",
- "write_permission_level": "EXPEL"
}
object | |
id | string <guid> |
object | |
meta | object |
object | |
type | string |
{- "created_at": "2019-01-15T15:35:00-05:00",
- "description": "string",
- "image": "string",
- "name": "string",
- "updated_at": "2019-01-15T15:35:00-05:00"
}
object | |
id | string <guid> |
object | |
meta | object |
object | |
type | string |
{- "created_at": "2019-01-15T15:35:00-05:00",
- "description": "string",
- "image": "string",
- "name": "string",
- "updated_at": "2019-01-15T15:35:00-05:00"
}
object | |
id | string <guid> |
object | |
meta | object |
object | |
type | string |
{- "action": "CREATED",
- "action_type": "ALERT_ON",
- "created_at": "2019-01-15T15:35:00-05:00",
- "value": { }
}
object | |
id | string <guid> |
object | |
meta | object |
object | |
type | string |
{- "action_enabled": true,
- "action_type": "ALERT_ON",
- "created_at": "2019-01-15T15:35:00-05:00",
- "expel_severity_threshold": "CRITICAL",
- "expel_signature_id": "string",
- "hunt_lead_category": "UNKNOWN",
- "updated_at": "2019-01-15T15:35:00-05:00"
}
object | |
id | string <guid> |
object | |
meta | object |
object | |
type | string |
{- "action": "CREATED",
- "created_at": "2019-01-15T15:35:00-05:00",
- "value": { }
}
object | |
id | string <guid> |
object | |
meta | object |
object | |
type | string |
{- "created_at": "2019-01-15T15:35:00-05:00",
- "definition": { },
- "description": "string",
- "ends_at": "2019-01-15T15:35:00-05:00",
- "initial_edit_at": "2019-01-15T15:35:00-05:00",
- "instruction": "string",
- "metadata": { },
- "resolved_definition": { },
- "review_status": "APPROVED",
- "starts_at": "2019-01-15T15:35:00-05:00",
- "title": "string",
- "updated_at": "2019-01-15T15:35:00-05:00"
}
object | |
id | string <guid> |
object | |
meta | object |
object | |
type | string |
{- "action": "string",
- "created_at": "2019-01-15T15:35:00-05:00",
- "value": { }
}
object | |
id | string <guid> |
object | |
meta | object |
object | |
type | string |
{- "context_type": "string",
- "created_at": "2019-01-15T15:35:00-05:00",
- "description": "string",
- "is_array": true,
- "name": "string",
- "surface_context": true,
- "updated_at": "2019-01-15T15:35:00-05:00",
- "value": "object",
- "value_type": "cidr_block"
}
object | |
id | string <guid> |
object | |
meta | object |
object | |
type | string |
{- "author_type": "string",
- "configuration_slugs": [ ],
- "created_at": "2019-01-15T15:35:00-05:00",
- "customer_context_tags": [ ],
- "description": "string",
- "engine": "string",
- "logic_blob": "string",
- "name": "string",
- "priority": 100,
- "severity": "string",
- "status": "string",
- "supported_tech": [ ],
- "tags": [ ],
- "test_blob": "string",
- "triage_considerations": "string",
- "unique_on": [ ],
- "unique_within": "string",
- "updated_at": "2019-01-15T15:35:00-05:00"
}
object | |
id | string <guid> |
object | |
meta | object |
object | |
type | string |
{- "email": "name@company.com",
- "schedule": "string"
}
object | |
id | string <guid> |
object | |
meta | object |
object | |
type | string |
{- "created_at": "2019-01-15T15:35:00-05:00",
- "recommendation": "string",
- "updated_at": "2019-01-15T15:35:00-05:00"
}
object | |
id | string <guid> |
object | |
meta | object |
object | |
type | string |
{- "created_at": "2019-01-15T15:35:00-05:00",
- "details": "string",
- "details_last_updated_at": "2019-01-15T15:35:00-05:00",
- "name": "string",
- "name_last_updated_at": "2019-01-15T15:35:00-05:00",
- "reason": "string",
- "reason_last_updated_at": "2019-01-15T15:35:00-05:00",
- "reference_links": "string",
- "reference_links_last_updated_at": "2019-01-15T15:35:00-05:00",
- "short_link": "string",
- "status": "INVESTIGATING",
- "summary": "string",
- "summary_last_updated_at": "2019-01-15T15:35:00-05:00",
- "threat_intelligence": "string",
- "threat_intelligence_last_updated_at": "2019-01-15T15:35:00-05:00",
- "updated_at": "2019-01-15T15:35:00-05:00"
}
object | |
id | string <guid> |
object | |
meta | object |
object | |
type | string |
{- "created_at": "2019-01-15T15:35:00-05:00",
- "display_name": "string",
- "email": "name@company.com",
- "pagerduty_id": "string",
- "phone_number": "string",
- "updated_at": "2019-01-15T15:35:00-05:00"
}
object | |
id | string <guid> |
object | |
meta | object |
object | |
type | string |
{- "entitlement": {
- "enabled_plugin_slugs": [ ],
- "installed_plugin_slugs": [ ],
- "installed_plugin_slugs_count": 100,
- "integrations_remaining": 100,
- "investigative_tech_enabled_plugin_slugs": [ ],
- "is_unlimited_integrations": true,
- "max_allowed_integrations": 100,
- "organization_id": "string",
- "service_offerings": [ ],
- "service_offerings_for_hunting": [ ],
- "service_types": [ ],
- "support_tier": "string"
}, - "expired_skus": [ ],
- "skus": [ ]
}
object | |
id | string <guid> |
object | |
meta | object |
object | |
type | string |
{- "created_at": "2019-01-15T15:35:00-05:00",
- "file_hash": "string",
- "from_date": "2019-01-15T15:35:00-05:00",
- "hostname": "string",
- "ip": "string",
- "latency": 100,
- "number_of_security_devices": 100,
- "phrase": "string",
- "scoped_organization_ids": [ ],
- "search_service_error": { },
- "to_date": "2019-01-15T15:35:00-05:00",
- "total_events": 100,
- "updated_at": "2019-01-15T15:35:00-05:00",
- "username": "string",
- "vendor_names": [ ]
}
object | |
id | string <guid> |
object | |
meta | object |
object | |
type | string |
{- "created_at": "2019-01-15T15:35:00-05:00"
}
object | |
id | string <guid> |
object | |
meta | object |
object | |
type | string |
{- "action": "CREATED",
- "created_at": "2019-01-15T15:35:00-05:00",
- "value": { }
}
object | |
id | string <guid> |
object | |
meta | object |
object | |
type | string |
{- "action": "CREATED",
- "created_at": "2019-01-15T15:35:00-05:00",
- "value": { }
}
object | |
id | string <guid> |
object | |
meta | object |
object | |
type | string |
{- "created_at": "2019-01-15T15:35:00-05:00",
- "name": "string",
- "threshold": 100,
- "updated_at": "2019-01-15T15:35:00-05:00"
}
object | |
id | string <guid> |
object | |
meta | object |
object | |
type | string |
{- "activity_first_at": "2019-01-15T15:35:00-05:00",
- "activity_last_at": "2019-01-15T15:35:00-05:00",
- "alert_type": "ENDPOINT",
- "close_comment": "string",
- "close_reason": "FALSE_POSITIVE",
- "created_at": "2019-01-15T15:35:00-05:00",
- "cust_disp_alerts_in_critical_incidents_count": 100,
- "cust_disp_alerts_in_incidents_count": 100,
- "cust_disp_alerts_in_investigations_count": 100,
- "cust_disp_closed_alerts_count": 100,
- "cust_disp_disposed_alerts_count": 100,
- "disposition_alerts_in_critical_incidents_count": 100,
- "disposition_alerts_in_incidents_count": 100,
- "disposition_alerts_in_investigations_count": 100,
- "disposition_closed_alerts_count": 100,
- "disposition_disposed_alerts_count": 100,
- "expel_alert_time": "2019-01-15T15:35:00-05:00",
- "expel_alias_name": "string",
- "expel_message": "string",
- "expel_name": "string",
- "expel_severity": "CRITICAL",
- "expel_signature_id": "string",
- "expel_version": "string",
- "hunt_finding_data": { },
- "investigative_action_count": 100,
- "is_auto_add": true,
- "is_viewed_by_assignable_expel_user": true,
- "rapid_triage_priority": "string",
- "ref_event_id": "string",
- "status": "string",
- "status_updated_at": "2019-01-15T15:35:00-05:00",
- "triggered_by_signal_guids": [ ],
- "tuning_requested": true,
- "updated_at": "2019-01-15T15:35:00-05:00",
- "vendor_alert_count": 100,
- "vendor_disp_alerts_in_critical_incidents_count": 100,
- "vendor_disp_alerts_in_incidents_count": 100,
- "vendor_disp_alerts_in_investigations_count": 100,
- "vendor_disp_closed_alerts_count": 100,
- "vendor_disp_disposed_alerts_count": 100
}
object | |
id | string <guid> |
object | |
meta | object |
relationships | object |
type | string |
{- "category_type": "string",
- "customer_context_tags": [ ],
- "description": "string",
- "investigative_questions": [ ],
- "name": "string",
- "number_of_detections": 100
}
object | |
id | string <guid> |
object | |
meta | object |
object | |
type | string |
{- "created_at": "2019-01-15T15:35:00-05:00",
- "expel_file_type": "string",
- "file_meta": {
- "investigative_action": {
- "file_type": "string"
}, - "rich_result": { }
}, - "filename": "string",
- "updated_at": "2019-01-15T15:35:00-05:00"
}
object | |
id | string <guid> |
object | |
meta | object |
object | |
type | string |
{- "created_at": "2019-01-15T15:35:00-05:00",
- "rank": 100,
- "title": "string",
- "updated_at": "2019-01-15T15:35:00-05:00"
}
object | |
id | string <guid> |
object | |
meta | object |
object | |
type | string |
{- "cells": [ ],
- "classification": "UNKNOWN",
- "created_at": "2019-01-15T15:35:00-05:00",
- "reason": [ ],
- "row_type": "DATA",
- "updated_at": "2019-01-15T15:35:00-05:00"
}
object | |
id | string <guid> |
object | |
meta | object |
object | |
type | string |
{- "created_at": "2019-01-15T15:35:00-05:00",
- "description": "string",
- "hypothesis": "string",
- "key": "string",
- "metadata": { },
- "mitre_tactics": [ ],
- "name": "string",
- "status": "string",
- "surface": "string",
- "updated_at": "2019-01-15T15:35:00-05:00"
}
object | |
id | string <guid> |
object | |
meta | object |
object | |
type | string |
{- "created_at": "2019-01-15T15:35:00-05:00",
- "expires_at": "2019-01-15T15:35:00-05:00",
- "updated_at": "2019-01-15T15:35:00-05:00",
- "value": "string",
- "value_type": "string"
}
object | |
id | string <guid> |
object | |
meta | object |
object | |
type | string |
{- "account": "string",
- "created_at": "2019-01-15T15:35:00-05:00",
- "enabled": true,
- "integration_meta": { },
- "integration_type": "pagerduty",
- "last_tested_at": "2019-01-15T15:35:00-05:00",
- "service_name": "string",
- "status": "UNTESTED",
- "updated_at": "2019-01-15T15:35:00-05:00"
}
object | |
id | string <guid> |
object | |
meta | object |
object | |
type | string |
{- "action": "CREATED",
- "created_at": "2019-01-15T15:35:00-05:00",
- "updated_at": "2019-01-15T15:35:00-05:00",
- "value": { }
}
object | |
id | string <guid> |
object | |
meta | object |
object | |
type | string |
{- "created_at": "2019-01-15T15:35:00-05:00",
- "deleted_at": "2019-01-15T15:35:00-05:00",
- "finding": "string",
- "finding_data": "object",
- "finding_type": "HUNTING:OUTCOME",
- "rank": 100,
- "title": "string",
- "updated_at": "2019-01-15T15:35:00-05:00"
}
object | |
id | string <guid> |
object | |
meta | object |
object | |
type | string |
{- "action": "CREATED",
- "created_at": "2019-01-15T15:35:00-05:00",
- "is_incident": true,
- "value": { }
}
attributes | object |
id | string <guid> |
object | |
meta | object |
relationships | object |
type | string |
{ }
object | |
id | string <guid> |
object | |
meta | object |
object | |
type | string |
{- "created_at": "2019-01-15T15:35:00-05:00",
- "updated_at": "2019-01-15T15:35:00-05:00"
}
object | |
id | string <guid> |
object | |
meta | object |
object | |
type | string |
{- "analyst_severity": "CRITICAL",
- "attack_lifecycle": "INITIAL_RECON",
- "attack_timing": "HISTORICAL",
- "attack_vector": "DRIVE_BY",
- "close_comment": "string",
- "created_at": "2019-01-15T15:35:00-05:00",
- "critical_comment": "string",
- "decision": "FALSE_POSITIVE",
- "default_plugin_slug": "string",
- "deleted_at": "2019-01-15T15:35:00-05:00",
- "detection_type": "UNKNOWN",
- "has_hunting_status": true,
- "initial_attack_vector": "string",
- "is_downgrade": true,
- "is_incident": true,
- "is_incident_status_updated_at": "2019-01-15T15:35:00-05:00",
- "is_soc_support_required": true,
- "is_surge": true,
- "last_published_at": "2019-01-15T15:35:00-05:00",
- "last_published_value": "string",
- "lead_description": "string",
- "malware_family": "string",
- "next_steps": "string",
- "open_reason": "ACCESS_KEYS",
- "open_summary": "string",
- "review_requested_at": "2019-01-15T15:35:00-05:00",
- "short_link": "string",
- "source_reason": "HUNTING",
- "status_updated_at": "2019-01-15T15:35:00-05:00",
- "threat_type": "TARGETED",
- "title": "string",
- "updated_at": "2019-01-15T15:35:00-05:00"
}
object | |
id | string <guid> |
object | |
meta | object |
object | |
type | string |
{- "action": "CREATED",
- "created_at": "2019-01-15T15:35:00-05:00",
- "deleted_at": "2019-01-15T15:35:00-05:00",
- "value": { }
}