GraphQL API Reference
Welcome to the Horizon3.ai GraphQL API Reference. This guide covers every query, mutation, and type available in the API, along with everything you need to start making requests.
Getting Started
- GraphQL vs. REST — Key differences if you are coming from a REST background.
- Authentication — Obtain a token using your API key.
- Sending Requests — Make GraphQL requests to the API.
- Response Format — Understand the structure of API responses.
- Handling Errors — Interpret error responses.
- Versioning — Learn how the API evolves over time.
Client Examples
- h3-cli Examples — Use the Horizon3.ai CLI to run queries from the command line.
- Python Examples — Run queries with a ready-to-use Python script.
- cURL Examples — Run queries with a ready-to-use bash/cURL script.
GraphQL vs. REST
If you have worked with REST APIs before, GraphQL will feel familiar — you are still sending HTTP requests and receiving JSON responses. However, there are a few important differences to be aware of.
Single Endpoint
REST APIs expose many endpoints (e.g., /pentests, /pentests/:id, /assets). GraphQL uses a single endpoint (/graphql) for all operations. The request body determines what data is returned.
Requests Are Defined in the POST Body
Instead of encoding the operation in the URL path and HTTP method (GET, PUT, DELETE), GraphQL requests are always sent as an HTTP POST with a JSON body containing a query field. The query is a structured string that describes exactly which fields and relationships you want to retrieve. See Sending Requests for an example.
You Choose the Fields You Receive
With a REST API, each endpoint returns a fixed set of fields. GraphQL lets you specify exactly which fields to include in the response — no more, no less. This reduces payload sizes and eliminates unnecessary data transfer.
Fetch Related Data in a Single Request
REST often requires multiple round-trips to assemble related data (e.g., fetching a pentest, then its weaknesses, then each affected host). A GraphQL query can traverse deeply nested relationships in a single request, returning all the data you need at once.
Status Codes Work Differently
REST APIs use HTTP status codes (200, 404, 500, etc.) to indicate success or failure. GraphQL requests always return HTTP 200, even when errors occur. Errors are reported in the errors field of the response body. See Handling Errors for details.
Strongly Typed Schema
Every field, argument, and return type in the API is defined in a typed schema. This reference is generated directly from that schema, so it always reflects the current state of the API.
REST (Multiple Requests)
# Fetch a list of pentests
GET /v1/pentests
# Fetch details for one pentest
GET /v1/pentests/abc-123
# Fetch weaknesses for that pentest
GET /v1/pentests/abc-123/weaknesses
# Fetch affected host for a weakness
GET /v1/pentests/abc-123/weaknesses/weakness-1/affected_host
GraphQL (Single Request)
query {
pentest(op_id: "abc-123") {
name
state
weaknesses_page {
weaknesses {
vuln {
id
name
description
}
affected_host {
ip
host_names
os_names
}
score
severity
}
}
}
}
Authentication
All API requests require a JSON Web Token (JWT). To obtain one, send your API key to the /auth endpoint as shown in the example on the right. The response contains a token field that you will include in subsequent requests.
API Key Required
You can generate an API key from the Horizon3.ai Portal.
Auth Endpoints
Use the endpoint for your region:
- US:
H3_AUTH_URL=https://api.gateway.horizon3ai.com/v1/auth - EU:
H3_AUTH_URL=https://api.gateway.horizon3ai.eu/v1/auth
JWT Expiration
Tokens expire after 1 hour. When a token expires, the API returns the following message. Simply re-authenticate to the /auth endpoint to obtain a new token.
{"message":"The incoming token has expired"}
Authenticate
H3_AUTH_URL="https://api.gateway.horizon3ai.com/v1/auth"
H3_API_KEY="<your-api-key-here>"
curl -X POST $H3_AUTH_URL \
-H "Content-Type: application/json" \
-d @- <<HERE
{
"key": "$H3_API_KEY"
}
HERE
Response
{"token": "<your-jwt>"}
Sending Requests
Send an HTTP POST request to the /graphql endpoint with your JWT in the Authorization header. The example on the right retrieves all pentests for your account, ordered by most recent.
API Endpoints
Use the endpoint for your region:
- US:
H3_API_URL=https://api.gateway.horizon3ai.com/v1/graphql - EU:
H3_API_URL=https://api.gateway.horizon3ai.eu/v1/graphql
Request Body
The POST body is a JSON object with two fields:
query— The GraphQL query or mutation string.variables— An optional JSON object containing variables referenced in the query or mutation.
For additional examples, see the Getting Started guide.
GraphQL Request
H3_API_URL="https://api.gateway.horizon3ai.com/v1/graphql"
H3_API_JWT="<your-jwt>"
curl -X POST $H3_API_URL \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $H3_API_JWT" \
-d @- <<HERE
{
"query": "
query q(\$page_input: PageInput) {
pentests_count(page_input: \$page_input)
pentests_page(page_input: \$page_input) {
pentests {
...PentestFragment
}
}
}
fragment PentestFragment on Pentest {
op_id
op_type
name
state
scheduled_at
launched_at
completed_at
etl_completed_at
hosts_count
weaknesses_count
}
",
"variables": {
"page_input": {
"page_num": 1
}
}
}
HERE
Response Format
Every response is a JSON object with up to two top-level fields:
data— The results of your query or mutation, mirroring the shape of the request.errors— Present only if one or more errors occurred during execution. See Handling Errors for details.
GraphQL Response
{
"data": {
"pentests_count": 8,
"pentests_page": {
"pentests": [
{
"op_id": "12341234-1234-1234-1234-123412341234",
"op_type": "NodeZero",
"name": "Sample Pentest",
"state": "done",
"scheduled_at": "2025-03-06T20:37:31.973429",
"launched_at": "2025-03-06T20:44:22.567519",
"completed_at": "2025-03-06T21:22:33.893341",
"etl_completed_at": "2025-03-06T21:30:01.073779",
"hosts_count": 10,
"weaknesses_count": 5
},
...
]
}
}
}
Handling Errors
Errors are returned in the errors array of the response. See the example on the right.
Status Codes
GraphQL requests return HTTP 200 in most cases, even when there are application-level errors. An HTTP 5xx status code indicates a network or system failure that prevented the API from responding.
Each error object may include an HTTP-style status code embedded in its message field, enclosed in square brackets (e.g., [403] You are not authorized).
The table below summarizes the status codes you may encounter.
| Code | Title | Description |
|---|---|---|
| 200 | Success | The response contains the requested data. |
| 400 | Bad Request | The request is malformed. Check the errors field for details. |
| 401 | Unauthorized | Authentication failed due to an invalid or expired JWT. |
| 403 | Forbidden | You do not have permission to access the requested resource. |
| 5xx | Internal Server Error | An unexpected server-side error occurred. |
Example Error Response
{
"data": {
"pentests_count": null,
"pentests_page": null
},
"errors": [
{
"message": "[403] You are not authorized",
"locations": [ { "line": 2, "column": 13 } ],
"path": [ "pentests_count" ]
}
]
}
Versioning
The Horizon3.ai GraphQL API does not use version numbers. All changes are additive and backward-compatible, so existing integrations continue to work as the API evolves.
Deprecations: Queries, mutations, and fields may be deprecated over time. Deprecated items are flagged in this documentation and remain functional until they are no longer in active use.
h3-cli Examples
h3-cli is a command-line tool for interacting with the Horizon3.ai GraphQL API. You can use it to run any of the query and mutation examples in this reference.
Installation
Install h3-cli using the commands shown on the right.
Usage
Run h3 help to see all available subcommands.
The h3 gql subcommand executes any GraphQL query or mutation. Save your query in a .graphql file and pass it to h3 gql:
h3 gql <graphql_file> [params_json]
Parameters
graphql_file— Path to a.graphqlfile containing your query or mutation.params_json— Optional JSON string with variables for the query or mutation.
The h3-cli tabs throughout this reference show the exact command for each query and mutation.
Pretty-Printing with jq
h3-cli bundles jq for formatting JSON output. Pipe the result to jq . to pretty-print:
h3 gql ./my_pentests.graphql '{"page_input": {"page_num": 1}}' | jq .
Auto-Pagination
For queries that accept a $page_input: PageInput argument, use h3 gql-stream to automatically iterate through all pages:
h3 gql-stream ./my_pentests.graphql data.pentests_page.pentests
The second argument (data.pentests_page.pentests in this example) is the path to the paginated array in the response. h3-cli fetches each page and streams the individual objects until all results have been returned.
JSON Streaming
The output of gql-stream is a stream of JSON objects, not a JSON array. To collect the stream into an array, pipe the output to jq -s:
h3 gql-stream ./my_pentests.graphql data.pentests_page.pentests | jq -s .
Installation
H3_API_KEY="<your-api-key-here>"
H3_DOWNLOAD_URL="https://downloads.horizon3ai.com/utilities/cli/easy_install.sh"
curl $H3_DOWNLOAD_URL | bash -s "$H3_API_KEY"
export H3_CLI_HOME="`pwd`/h3-cli"
export PATH="$H3_CLI_HOME/bin:$PATH"
# Commands
h3 help
h3 whoami
h3 pentests
Python Examples
h3_gql.py is a ready-to-use Python script that handles authentication and query execution in a single call. The full source is shown on the right.
Required Environment Variables
H3_API_KEY— Your API key.H3_AUTH_URL— The authentication endpoint for your region. See Authentication.H3_API_URL— The GraphQL endpoint for your region. See Sending Requests.
Usage
python h3_gql.py <graphql_file> [params_json]
Parameters
graphql_file— Path to a.graphqlfile containing your query or mutation.params_json— Optional JSON string with variables for the query or mutation.
The Python tabs throughout this reference show the exact command for each query and mutation.
h3_gql.py
import json
import os
import sys
from pathlib import Path
import requests
def authenticate():
url = os.environ["H3_AUTH_URL"]
api_key = os.environ["H3_API_KEY"]
response = requests.post(url, json={"key": api_key})
response.raise_for_status()
return response.json()["token"]
def execute_query(jwt, graphql_file, variables):
url = os.environ["H3_API_URL"]
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {jwt}",
}
query = Path(graphql_file).read_text()
payload = {"query": query, "variables": variables}
response = requests.post(url, headers=headers, json=payload)
return response.json()
if __name__ == "__main__":
graphql_file = sys.argv[1]
params = json.loads(sys.argv[2]) if len(sys.argv) > 2 else {}
jwt = authenticate()
result = execute_query(jwt, graphql_file, params)
print(json.dumps(result, indent=2))
cURL Examples
h3_gql.sh is a ready-to-use bash script that handles authentication and query execution using only cURL and sed — no additional dependencies required. The full source is shown on the right.
Required Environment Variables
H3_API_KEY— Your API key.H3_AUTH_URL— The authentication endpoint for your region. See Authentication.H3_API_URL— The GraphQL endpoint for your region. See Sending Requests.
Usage
chmod +x h3_gql.sh
./h3_gql.sh <graphql_file> [params_json]
Parameters
graphql_file— Path to a.graphqlfile containing your query or mutation.params_json— Optional JSON string with variables for the query or mutation.
The cURL tabs throughout this reference show the exact command for each query and mutation.
h3_gql.sh
#!/usr/bin/env bash
set -euo pipefail
graphql_file="${1:?Usage: ./h3_gql.sh <graphql_file> [params_json]}"
variables="${2:-{}}"
# Authenticate and extract JWT using sed (no jq/python dependency)
jwt=$(curl -s -X POST "$H3_AUTH_URL" \
-H "Content-Type: application/json" \
-d "{\"key\": \"$H3_API_KEY\"}" \
| sed -n 's/.*"token"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p')
query=$(cat "$graphql_file" | sed 's/"/\\\\"/g' | tr '\n' ' ')
curl -s -X POST "$H3_API_URL" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $jwt" \
-d "{\"query\": \"$query\", \"variables\": $variables}"
Using the API
Core utilities for working with the Horizon3.ai GraphQL API. This section covers pagination controls for managing large datasets, filtering and sorting options, and metadata queries for API introspection and type definitions.
Using the API: Pagination
Control pagination, filtering, and sorting for query results that return large datasets. Use PageInput to navigate through paginated results, apply filters to narrow results, and specify sort order.
PageInput
Description
Controls pagination, sorting, and filtering for any paginated query.
Pass a PageInput to any *_page query to specify which page of results to return, how to order them, and which filters to apply. Pages are 1-indexed, with a default size of 20 and a maximum of 100 results per page.
Fields
page_num - Int
page_size to determine the offset into the result set. Defaults to 1 if not specified. page_size - Int
order_by - String
sort_inputs instead. sort_order - SortOrder
ASC or DESC). Used together with order_by. sort_inputs - [SortInput]
filter_by_inputs - [FilterByInput]
AND logic. Use filter_by_input_mode to switch to OR. See FilterByInput. filter_by_input_mode - FilterByInputMode
AND or OR) for combining multiple filter_by_inputs entries. Defaults to AND. See FilterByInputMode. text_search - String
# Example 1: Basic pagination
query BasicPagination($page_input: PageInput = {
page_num: 1,
page_size: 5
}) {
pentests_page(page_input: $page_input) {
pentests {
op_id
name
state
}
}
}
# Example 2: Pagination with sorting
query PaginationWithSorting($page_input: PageInput = {
page_size: 10,
sort_inputs: [
{ order_by: "scheduled_at", sort_order: DESC }
]
}) {
pentests_page(page_input: $page_input) {
pentests {
op_id
name
scheduled_at
}
}
}
# Example 3: Pagination with filtering
query PaginationWithFiltering($page_input: PageInput = {
filter_by_inputs: [
{ field_name: "state", values: ["done"] }
]
}) {
pentests_page(page_input: $page_input) {
pentests {
op_id
name
op_type
state
}
}
}
Examples may not include all available fields for a type.
FacetValue
Description
Represents a single filterable value within a faceted navigation set. Each FacetValue provides a value, its count in the current result set, and a prebuilt FilterBy object that can be passed directly to PageInput filter_by_inputs to narrow results to this value.
fragment FacetValueFragment on FacetValue {
label
value
value_count
filter_by {
field_name
values
}
}
Examples may not include all available fields for a type.
{
"label": "Critical",
"value": "CRITICAL",
"value_count": 12,
"filter_by": {
"field_name": "severity",
"values": ["CRITICAL"]
}
}
FilterBy
Description
Represents an active filter applied to query results. This is the output counterpart of FilterByInput, returned within PageInfo to confirm which filters were applied.
Fields
field_name - StringNoWhitespace!
values - [String]
not_values - [String]
less_than - String
less_than_or_equal - String
greater_than - String
greater_than_or_equal - String
fragment FilterByFragment on FilterBy {
field_name
values
not_values
less_than
less_than_or_equal
greater_than
greater_than_or_equal
}
Examples may not include all available fields for a type.
{
"field_name": "severity",
"values": ["CRITICAL", "HIGH"],
"not_values": null,
"less_than": null,
"less_than_or_equal": null,
"greater_than": null,
"greater_than_or_equal": null
}
FilterByInput
Description
Defines a single filter criterion for querying data. Specify a field_name and one or more conditions (values, not_values, range comparisons, or is_null) to restrict results. Multiple conditions within a single FilterByInput are combined with AND logic.
Fields
field_name - StringNoWhitespace!
values - [String]
not_values. Can be combined with range comparisons (greater_than*, less_than*) and is_null; combined conditions are AND'ed. not_values - [String]
values. Can be combined with range comparisons (greater_than*, less_than*) and is_null; combined conditions are AND'ed. greater_than - String
greater_than_or_equal. Can be combined with less_than*, values, not_values, and is_null; combined conditions are AND'ed. greater_than_or_equal - String
greater_than. Can be combined with less_than*, values, not_values, and is_null; combined conditions are AND'ed. less_than - String
less_than_or_equal. Can be combined with greater_than*, values, not_values, and is_null; combined conditions are AND'ed. less_than_or_equal - String
less_than. Can be combined with greater_than*, values, not_values, and is_null; combined conditions are AND'ed. filter_by_input_mode - FilterByInputMode
is_null - Boolean
true to include only rows where the field IS NULL. Set to false to include only rows where the field IS NOT NULL. Omit or set to null to skip null checking. Can be combined with other conditions; combined conditions are AND'ed. # Example 1: Filter by single value
query FilterBySingleValue($page_input: PageInput = {
filter_by_inputs: [
{ field_name: "op_type", values: ["NodeZero"] }
]
}) {
pentests_page(page_input: $page_input) {
pentests {
op_id
name
op_type
}
}
}
# Example 2: Filter by multiple values
query FilterByMultipleValues($page_input: PageInput = {
filter_by_inputs: [
{ field_name: "state", values: ["done", "running"] }
]
}) {
pentests_page(page_input: $page_input) {
pentests {
op_id
name
op_type
state
}
}
}
# Example 3: Exclude specific values
query FilterExcludeValues($page_input: PageInput = {
filter_by_inputs: [
{ field_name: "state", not_values: ["ended", "error"] }
]
}) {
pentests_page(page_input: $page_input) {
pentests {
op_id
name
state
}
}
}
Examples may not include all available fields for a type.
FilterByInputMode
Description
Logical operator used to combine multiple FilterByInput entries when filtering query results.
Values
AND
filter_by_input_mode is not specified. OR
Example
"AND"
PageInfo
Description
Echoes back the pagination parameters that were applied to produce the current page of results. Returned by all paginated queries alongside the result data.
Fields
page_num - Int
page_size - Int
text_search - String
filter_by_inputs - [FilterBy]
fragment PageInfoFragment on PageInfo {
page_num
page_size
text_search
}
Examples may not include all available fields for a type.
{
"page_num": 1,
"page_size": 10,
"text_search": null
}
SortInput
Description
Defines a single sort criterion. Use within PageInput sort_inputs to sort results by one or more fields.
Fields
order_by - StringNoWhitespace!
Name of the field to sort by. Must correspond to a field name on the returned type.
Not all fields are sortable. An error is returned if you specify a non-sortable field. The set of sortable fields depends on the type being queried.
sort_order - SortOrder
ASC if not specified. nulls_first - Boolean
false (default), nulls are placed last even in DESC order. Set to true to place nulls first in DESC queries. # Example 1: Sort by a single field
query SortBySingleField($page_input: PageInput = {
sort_inputs: [
{ order_by: "severity", sort_order: DESC }
]
}) {
weaknesses_page(
op_id: "1234abcd-1234-abcd-1234-abcd1234abcd"
page_input: $page_input
) {
weaknesses {
uuid
vuln_name
severity
}
}
}
# Example 2: Sort by multiple fields
query SortByMultipleFields($page_input: PageInput = {
sort_inputs: [
{ order_by: "severity", sort_order: DESC },
{ order_by: "vuln_name", sort_order: ASC }
]
}) {
weaknesses_page(
op_id: "1234abcd-1234-abcd-1234-abcd1234abcd"
page_input: $page_input
) {
weaknesses {
uuid
vuln_name
severity
}
}
}
Examples may not include all available fields for a type.
SortOrder
Description
Specifies the direction in which to order query results.
Values
ASC
DESC
Example
"ASC"
Using the API: Metadata
Query GraphQL schema metadata and type definitions. Introspect the API to discover available types, fields, queries, and mutations programmatically, such as with an LLM and MCP server.
graphql_def
Description
Returns the GraphQLDef schema definition for a single element in the API. No authentication is required. The id parameter identifies the schema element and can be one of:
- a type name, eg.
Query,Mutation,Weakness, etc. - a field name, eg.
Query.pentests_page,Mutation.create_op, etc. - an enum name, eg.
AuthzRole,PortalOpState, etc. - an enum value, eg.
AuthzRole.ORG_ADMIN,PortalOpState.running, etc.
Response
Returns an GraphQLDef!
Arguments
id - String!
Query, Weakness, Mutation.create_op, etc. query GetGraphQLDefinition($id: String!) {
graphql_def(id: $id) {
...GraphQLDefFragment
}
}
fragment GraphQLDefFragment on GraphQLDef {
id
name
type
type_name
declaration
description
parent_id
default_value
related_type_ids
args
fields {
id
name
type
type_name
description
}
}
Examples may not include all available fields for a type.
{
"data": {
"graphql_def": {
"id": "Query.weaknesses_page",
"name": "weaknesses_page",
"type": "WeaknessesPage!",
"type_name": "WeaknessesPage",
"declaration": "weaknesses_page(input: OpInput!, page_input: PageInput): WeaknessesPage!",
"description": "The set of Weaknesses observed during the given op",
"parent_id": "Query",
"default_value": null,
"related_type_ids": ["WeaknessesPage", "OpInput", "PageInput"],
"args": [
{
"declaration": "input: OpInput!",
"defaultValue": null,
"description": null,
"name": "input",
"type": "OpInput!",
"type_name": "OpInput"
},
{
"declaration": "page_input: PageInput",
"defaultValue": null,
"description": null,
"name": "page_input",
"type": "PageInput",
"type_name": "PageInput"
}
],
"fields": null
}
}
}
python h3_gql.py ./graphql_def.graphql '{
"id": "Query.weaknesses_page"
}'
Save the example request as ./graphql_def.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./graphql_def.graphql '{
"id": "Query.weaknesses_page"
}'
Save the example request as ./graphql_def.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./graphql_def.graphql '{
"id": "Query.weaknesses_page"
}'
Save the example request as ./graphql_def.graphql.
See h3-cli Examples for installation and usage.
hello
Description
A simple connectivity test that returns the string world!. Use this query to verify that your API client can successfully reach the GraphQL endpoint. No authentication is required.
query {
hello
}
Response
Returns a String!
query HelloWorld {
hello
}
Examples may not include all available fields for a type.
{
"data": {
"hello": "world"
}
}
python h3_gql.py ./hello.graphql
Save the example request as ./hello.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./hello.graphql
Save the example request as ./hello.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./hello.graphql
Save the example request as ./hello.graphql.
See h3-cli Examples for installation and usage.
GraphQLDef
Description
Represents the schema definition of a single element in the GraphQL API. Use the graphql_def query to retrieve definitions programmatically. A GraphQLDef can represent one of:
- a Type (e.g.
Query,Mutation,WeaknessesPage,Weakness) - a Field within a type (e.g.
Query.weaknesses_page,Weakness.op_id) - an Enum (e.g.
AuthzRole,PortalOpState) - an Enum Value (e.g.
AuthzRole.ORG_ADMIN,PortalOpState.running)
Fields
id - String!
Unique identifier for this schema element.
- For a Type: the type name (e.g.
Query,WeaknessesPage) - For a Field: the parent type + field name (e.g.
Query.weaknesses_page) - For an Enum: the enum name (e.g.
AuthzRole) - For an Enum Value: the enum name + value (e.g.
AuthzRole.ORG_ADMIN)
description - String
declaration - String
The full GraphQL declaration syntax for this schema element. For example:
weaknesses_page(input: OpInput!, page_input: PageInput): WeaknessesPage!
: WeaknessesPage!)
name - String!
The name of this schema element.
- For a Type: the type name (e.g.
Query,WeaknessesPage) - For a Field: the field name (e.g.
weaknesses_page) - For an Enum: the enum name (e.g.
AuthzRole) - For an Enum Value: the enum value (e.g.
ORG_ADMIN)
type - String!
! (non-null) and [] (list). type_name - String!
!, []). parent_id - String
weaknesses_page on Query has a parent_id of Query. default_value - String
related_type_ids - [String!]
related_types - [GraphQLDef!]
args - [JSONObject!]
The list of arguments accepted by this field, if any. Each argument is a JSON object with keys:
[
{
"declaration": "page_input: PageInput",
"defaultValue": null,
"description": null,
"name": "page_input",
"type": "PageInput",
"type_name": "PageInput"
}
]
fields - [GraphQLDef!]
fragment GraphQLDefFragment on GraphQLDef {
id
name
description
declaration
type
type_name
parent_id
default_value
related_type_ids
args
fields {
id
name
type
type_name
description
}
}
Examples may not include all available fields for a type.
{
"id": "Weakness",
"name": "Weakness",
"description": "A Weakness represents a security vulnerability found during an operation.",
"declaration": null,
"type": "Weakness",
"type_name": "Weakness",
"parent_id": null,
"default_value": null,
"related_type_ids": null,
"args": null,
"fields": [
{
"id": "Weakness.uuid",
"name": "uuid",
"type": "ID!",
"type_name": "ID",
"description": "UUID of the Weakness"
},
{
"id": "Weakness.name",
"name": "name",
"type": "String!",
"type_name": "String",
"description": "Name of the Weakness"
}
]
}
Setup
Configure your pentesting environment and define your attack surface. Create and manage pentest templates, deploy NodeZero runners, schedule recurring pentests, organize assets into groups, and authorize domains and IPs for external testing. This section provides all the tools needed to prepare your pentesting infrastructure.
Setup: Op Config
Configure pentest parameters and settings including scope, attack types, feature flags, credentials, and runtime limits. This section defines the comprehensive configuration object used when creating or scheduling pentests and other operations.
ScheduleOpForm
Description
The configuration used to create an Op or an OpTemplate.
This type represents the read view of an op's configuration. To create or update a configuration, use ScheduleOpFormInput.
Key configuration fields include:
op_type: The type of operation (e.g. internal pentest, external pentest, AD password audit). See OpType for the full list and configuration requirements.op_param_max_scope/op_param_min_scope: Define the network scope for the op.feature_flags: Advanced configuration settings that control specific attack behaviors. See FeatureFlag.asset_group_uuid: The AssetGroup to target for external pentests.runner_uuid: The NodeZero Runner that launches the op.k8s_deploymentand relatedk8s_*fields: Configuration for Kubernetes-based pentests.auto_injected_credential_uuids: Credentials to be auto-injected by a NodeZero Runner.minimum_run_time/maximum_run_time: Control how long the op runs.
Note: Despite its name, ScheduleOpForm is not used for creating a recurring schedule. Use Schedule and ScheduledAction for that purpose.
Fields
op_name - String
The name of the operation.
The name can be anything. It is used in reports and the UI to label the operation.
op_type - OpType
The type of operation.
Defaults to NodeZero (an internal pentest).
See OpType for the full list of supported op types and their configuration requirements.
op_param_blacklist - String
Hosts and subnets that are EXCLUDED from the op.
Any hosts or subnets that fall within this scope will not be scanned during the op.
Specified as comma-separated CIDR ranges and/or individual IP addresses.
op_param_min_scope - String
op_param_min_scope and op_param_max_scope are mutually exclusive ways to define the scope of an op. You can define one or the other, but not both at the same time.
If op_param_min_scope is defined, then the Auto-Expand Scope feature is enabled. This means NodeZero will scan not only the hosts defined in op_param_min_scope, but it will dynamically expand the scope during the operation to include any additional hosts it discovers organically.
Use op_param_min_scope if you're not sure of your full scope, and you want NodeZero to dynamically discover and scan additional hosts and scope, beyond the scope you defined in op_param_min_scope.
op_param_min_scope is typically configured as a set of individual host IPs, not large CIDR ranges or subnets. NodeZero will specifically search for and scan the defined IPs, in addition to any other hosts and subnets it discovers during the op.
Use op_param_max_scope if you know exactly the scope of hosts and subnets you want to scan, and you do NOT want NodeZero to scan any hosts or subnets beyond that scope. This is the more commonly used option, as it gives you the most control over which hosts and subnets are included in the scan.
If neither op_param_min_scope nor op_param_max_scope are defined, then NodeZero defaults to using Intelligent Scope. Intelligent Scope starts with the IP of the host that NodeZero is deployed on. From there, NodeZero enumerates and scans the /16 subnet that the host belongs to. NodeZero then expands into adjacent /23 subnets, continuously identifying and testing nearby assets. The cycle repeats until no additional devices are detected. The ultimate scope of the test depends on the level of privilege and access NodeZero has, either through captured or granted permissions.
The scope is specified as a list of comma-separated IPs and/or CIDR ranges.
op_param_max_scope - String
op_param_min_scope and op_param_max_scope are mutually exclusive ways to define the scope of an op. You can define one or the other, but not both at the same time.
If op_param_max_scope is defined, then the Auto-Expand Scope feature is disabled. This means NodeZero will only scanthe hosts and subnets defined in op_param_max_scope. NodeZero will NOT try to dynamically expand the scope during the operation to include any additional hosts it discovers organically. Only the hosts and subnets that fall within the scope defined in op_param_max_scope will be scanned.
Use op_param_max_scope if you know exactly the scope of hosts and subnets you want to scan, and you do NOT want NodeZero to scan any hosts or subnets beyond that scope. This is the more commonly used option, as it gives you the most control over which hosts and subnets are included in the scan.
Use op_param_min_scope if you're not sure of your full scope, and you want NodeZero to dynamically discover and scan additional hosts and scope.
If neither op_param_min_scope nor op_param_max_scope are defined, then NodeZero defaults to using Intelligent Scope. Intelligent Scope starts with the IP of the host that NodeZero is deployed on. From there, NodeZero enumerates and scans the /16 subnet that the host belongs to. NodeZero then expands into adjacent /23 subnets, continuously identifying and testing nearby assets. The cycle repeats until no additional devices are detected. The ultimate scope of the test depends on the level of privilege and access NodeZero has, either through captured or granted permissions.
The scope is specified as a list of comma-separated IPs and/or CIDR ranges.
op_param_application_url - String
op_param_application_alt_urls - [String]
web_application_uuid - String
feature_flags - [FeatureFlag]
osint_domains - [String]
osint_company_names - [String]
passwords_to_spray - [String]
git_accounts - [GitAccount]
aws_account_ids - [AWSAccountId]
asset_group_uuid - String
op_type=ExternalAttack). start_paused - Boolean
true, the op starts in a paused state. This is useful for external pentests when NodeZero's IP address must first be known in order to configure firewall rules. minimum_run_time - Int
maximum_run_time - Int
runner_uuid - String
auto_injected_credential_uuids - [String!]
targeted_test_id - String
k8s_deployment - Boolean
true when deploying NodeZero in a Kubernetes cluster. Required for the K8sPentest op type. k8s_node - String
K8sPentest op type. k8s_namespace - String
K8sPentest op type. k8s_service_account_name - String
K8sPentest op type. aws_connection_uuids - [String!]
AWSPentest op type. aws_connection_identifier_uuid - String
inventory_op_scope_uuids - [ID!]
ExternalAssetDiscovery and ExternalAttack op types. all_authorized_assets - Boolean
true, the op includes all authorized assets with no additional scope filtering. Currently only supported for the ExternalAttack op type. Mutually exclusive with asset_group_uuid, op_series_uuid, and inventory_op_scope_uuids. fragment ScheduleOpFormFragment on ScheduleOpForm {
op_name
op_type
op_param_blacklist
op_param_max_scope
feature_flags {
name
value
}
osint_domains
osint_company_names
passwords_to_spray
asset_group_uuid
start_paused
minimum_run_time
maximum_run_time
runner_uuid
auto_injected_credential_uuids
targeted_test_id
k8s_deployment
k8s_node
k8s_namespace
k8s_service_account_name
aws_connection_uuids
aws_connection_identifier_uuid
}
Examples may not include all available fields for a type.
{
"op_name": "Weekly Internal Pentest",
"op_type": "NodeZero",
"op_param_blacklist": "10.0.0.1,10.0.0.2",
"op_param_max_scope": "10.0.0.0/8",
"feature_flags": [
{"name": "brute_force.dns", "value": true},
{"name": "default_cred.ssh", "value": true}
],
"osint_domains": ["example.com"],
"osint_company_names": ["Example Corp"],
"passwords_to_spray": ["Summer2024!", "Welcome1"],
"asset_group_uuid": null,
"start_paused": false,
"minimum_run_time": 60,
"maximum_run_time": 480,
"runner_uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"auto_injected_credential_uuids": [],
"targeted_test_id": null,
"k8s_deployment": false,
"k8s_node": null,
"k8s_namespace": null,
"k8s_service_account_name": null,
"aws_connection_uuids": [],
"aws_connection_identifier_uuid": null
}
ScheduleOpFormInput
Description
Input configuration for creating an Op or an OpTemplate.
This is the input version of ScheduleOpForm, used when creating or updating op configurations.
See OpType for the list of op types and their configuration requirements.
Key configuration fields include:
op_type: The type of operation (e.g. internal pentest, external pentest, AD password audit).op_param_max_scope/op_param_min_scope: Define the network scope for the op.feature_flags: Advanced configuration settings that control specific attack behaviors.asset_group_uuid: The AssetGroup to target for external pentests.runner_uuid: The NodeZero Runner that launches the op.k8s_deploymentand relatedk8s_*fields: Configuration for Kubernetes-based pentests.auto_injected_credential_uuids: Credentials to be auto-injected by a NodeZero Runner.minimum_run_time/maximum_run_time: Control how long the op runs.
Partial/patch updates of an op template's configuration are supported via Mutation.update_op_template.
Fields
op_name - String
The name of the operation.
The name can be anything. It is used in reports and the UI to label the operation.
This also sets AssetGroup.name when used with create_asset_group and update_asset_group_template.
op_type - OpType
The type of operation.
Defaults to NodeZero (an internal pentest).
See OpType for the full list of supported op types and their configuration requirements.
op_param_blacklist - String
Hosts and subnets that are EXCLUDED from the op.
Any hosts or subnets that fall within this scope will not be scanned during the op.
Specified as comma-separated CIDR ranges and/or individual IP addresses.
op_param_min_scope - String
op_param_min_scope and op_param_max_scope are mutually exclusive ways to define the scope of an op. You can define one or the other, but not both at the same time.
If op_param_min_scope is defined, then the Auto-Expand Scope feature is enabled. This means NodeZero will scan not only the hosts defined in op_param_min_scope, but it will dynamically expand the scope during the operation to include any additional hosts it discovers organically.
Use op_param_min_scope if you're not sure of your full scope, and you want NodeZero to dynamically discover and scan additional hosts and scope, beyond the scope you defined in op_param_min_scope.
op_param_min_scope is typically configured as a set of individual host IPs, not large CIDR ranges or subnets. NodeZero will specifically search for and scan the defined IPs, in addition to any other hosts and subnets it discovers during the op.
Use op_param_max_scope if you know exactly the scope of hosts and subnets you want to scan, and you do NOT want NodeZero to scan any hosts or subnets beyond that scope. This is the more commonly used option, as it gives you the most control over which hosts and subnets are included in the scan.
If neither op_param_min_scope nor op_param_max_scope are defined, then NodeZero defaults to using Intelligent Scope. Intelligent Scope starts with the IP of the host that NodeZero is deployed on. From there, NodeZero enumerates and scans the /16 subnet that the host belongs to. NodeZero then expands into adjacent /23 subnets, continuously identifying and testing nearby assets. The cycle repeats until no additional devices are detected. The ultimate scope of the test depends on the level of privilege and access NodeZero has, either through captured or granted permissions.
The scope is specified as a list of comma-separated IPs and/or CIDR ranges.
op_param_max_scope - String
op_param_min_scope and op_param_max_scope are mutually exclusive ways to define the scope of an op. You can define one or the other, but not both at the same time.
If op_param_max_scope is defined, then the Auto-Expand Scope feature is disabled. This means NodeZero will only scanthe hosts and subnets defined in op_param_max_scope. NodeZero will NOT try to dynamically expand the scope during the operation to include any additional hosts it discovers organically. Only the hosts and subnets that fall within the scope defined in op_param_max_scope will be scanned.
Use op_param_max_scope if you know exactly the scope of hosts and subnets you want to scan, and you do NOT want NodeZero to scan any hosts or subnets beyond that scope. This is the more commonly used option, as it gives you the most control over which hosts and subnets are included in the scan.
Use op_param_min_scope if you're not sure of your full scope, and you want NodeZero to dynamically discover and scan additional hosts and scope.
If neither op_param_min_scope nor op_param_max_scope are defined, then NodeZero defaults to using Intelligent Scope. Intelligent Scope starts with the IP of the host that NodeZero is deployed on. From there, NodeZero enumerates and scans the /16 subnet that the host belongs to. NodeZero then expands into adjacent /23 subnets, continuously identifying and testing nearby assets. The cycle repeats until no additional devices are detected. The ultimate scope of the test depends on the level of privilege and access NodeZero has, either through captured or granted permissions.
The scope is specified as a list of comma-separated IPs and/or CIDR ranges.
op_param_application_url - String
web_application_uuid instead. web_application_uuid - String
For web app pentesting, the UUID of the web application entity being tested.
The web application object identified by this UUID provides the op_param_application_url and other web app-specific configuration automatically.
feature_flags - [FeatureFlagInput]
Mutation.update_op_template. Only flags included in the input will be updated; unspecified flags retain their current values. osint_domains - [String]
osint_company_names - [String]
passwords_to_spray - [String]
git_accounts - [GitAccountInput]
aws_account_ids - [AWSAccountId]
asset_group_uuid - String
op_type=ExternalAttack). start_paused - Boolean
true, the op starts in a paused state. This is useful for external pentests when NodeZero's IP address must first be known in order to configure firewall rules. minimum_run_time - Int
maximum_run_time - Int
runner_uuid - String
auto_injected_credential_uuids - [String!]
targeted_test_id - String
k8s_deployment - Boolean
true when deploying NodeZero in a Kubernetes cluster. Required for the K8sPentest op type. k8s_node - String
K8sPentest op type. k8s_namespace - String
K8sPentest op type. k8s_service_account_name - String
K8sPentest op type. aws_connection_uuids - [String!]
AWSPentest op type. aws_connection_identifier_uuid - String
enable_tripwires - Boolean
feature_flags field. inventory_op_scope_uuids - [ID!]
ExternalAssetDiscovery and ExternalAttack op types. Mutually exclusive with asset_group_uuid. all_authorized_assets - Boolean
true, the op includes all authorized assets with no additional scope filtering. Currently only supported for the ExternalAttack op type. Mutually exclusive with asset_group_uuid, op_series_uuid, and inventory_op_scope_uuids. # Example 1: Create an internal pentest with basic configuration
mutation CreateInternalPentest($schedule_op_form: ScheduleOpFormInput = {
op_name: "Weekly Internal Pentest",
op_type: NodeZero,
op_param_max_scope: "10.0.0.0/8",
maximum_run_time: 480
}) {
create_op(schedule_op_form: $schedule_op_form) {
op {
op_id
op_type
op_name
op_state
op_param_max_scope
nodezero_script_url
}
}
}
# Example 2: Create an external pentest
mutation CreateExternalPentest($schedule_op_form: ScheduleOpFormInput = {
op_name: "External Attack Assessment",
op_type: ExternalAttack,
asset_group_uuid: "1234abcd-1234-abcd-1234-abcd1234abcd"
}) {
create_op(schedule_op_form: $schedule_op_form) {
op {
op_id
op_type
op_name
op_state
asset_group_uuid
}
}
}
Examples may not include all available fields for a type.
AWSAccountId
Description
String scalar type representing an AWS Account ID (a 12-digit number).
Example
123456789012
AttackConfigValue
Description
The user-provided value for a FeatureFlag. Exactly one field will be set, corresponding to the option's data_type.
fragment AttackConfigValueFragment on AttackConfigValue {
bool_value
int_value
float_value
string_value
}
Examples may not include all available fields for a type.
{
"bool_value": true,
"int_value": null,
"float_value": null,
"string_value": null
}
AttackConfigValueInput
Description
Input type for specifying the value of a FeatureFlag. Provide exactly one of the value fields, matching the option's data_type.
# Example: Set a boolean config value via op template update
mutation SetAttackConfig($input: UpdateOpTemplateInput! = {
uuid: "1234abcd-1234-abcd-1234-abcd1234abcd",
schedule_op_form: {
feature_flags: [
{
name: "get_proof.bluekeep",
config_value: { bool_value: true }
}
]
}
}) {
update_op_template(input: $input) {
op_template {
uuid
schedule_op_form {
feature_flags {
name
config_value {
bool_value
int_value
string_value
}
}
}
}
}
}
Examples may not include all available fields for a type.
FeatureFlag
Description
An advanced configuration option (also known as a feature flag) that controls specific attack behaviors during an op.
Feature flags are configured via ScheduleOpFormInput.feature_flags and can be read from Op.feature_flags or ScheduleOpForm.feature_flags.
For more information about advanced configuration options, see the Attack Configurations section of the Horizon3.ai documentation.
Fields
name - String!
value - Boolean
config_value - AttackConfigValue
property_name - String
property_description - String
category_name - String
category_description - String
risk - FeatureFlagRiskType
enables_min_runtime - Boolean
true, indicates this option works best when ScheduleOpFormInput.minimum_run_time is also configured, to give the attack enough time to execute. enables_password_spray - Boolean
true, indicates this option works best when ScheduleOpFormInput.passwords_to_spray is also configured with a list of passwords. is_new - Boolean!
true, indicates this option was introduced after the containing OpTemplate was last saved. This helps alert users to new configuration options available in their template. The flag resets once the template is re-saved. fragment FeatureFlagFragment on FeatureFlag {
name
value
config_value {
bool_value
int_value
float_value
string_value
}
property_name
property_description
category_name
category_description
risk
enables_min_runtime
enables_password_spray
is_new
}
Examples may not include all available fields for a type.
{
"name": "get_proof.bluekeep",
"value": true,
"config_value": {
"bool_value": true,
"int_value": null,
"float_value": null,
"string_value": null
},
"property_name": "Bluekeep (CVE-2019-0708)",
"property_description": "Attempt to exploit BlueKeep vulnerability on discovered hosts.",
"category_name": "Exploitation",
"category_description": "Options related to exploitation techniques.",
"risk": "moderate",
"enables_min_runtime": false,
"enables_password_spray": false,
"is_new": false
}
FeatureFlagInput
Description
Input for configuring an advanced attack configuration option.
Advanced configuration options (also known as feature flags) control specific attack behaviors during an op. Specify these via ScheduleOpFormInput.feature_flags.
For more information about advanced configuration options, see the Attack Configurations section of the Horizon3.ai documentation.
Fields
name - String!
value - Boolean
config_value - AttackConfigValueInput
data_type. See AttackConfigValueInput for details. # Example 1: Enable a boolean feature flag
mutation EnableFeatureFlag($input: UpdateOpTemplateInput! = {
uuid: "1234abcd-1234-abcd-1234-abcd1234abcd",
schedule_op_form: {
feature_flags: [
{
name: "get_proof.bluekeep",
value: true
}
]
}
}) {
update_op_template(input: $input) {
op_template {
uuid
schedule_op_form {
feature_flags {
name
value
}
}
}
}
}
# Example 2: Set a feature flag with a config value
mutation SetFeatureFlagConfig($input: UpdateOpTemplateInput! = {
uuid: "1234abcd-1234-abcd-1234-abcd1234abcd",
schedule_op_form: {
feature_flags: [
{
name: "get_proof.bluekeep",
config_value: { bool_value: true }
}
]
}
}) {
update_op_template(input: $input) {
op_template {
uuid
schedule_op_form {
feature_flags {
name
config_value {
bool_value
}
}
}
}
}
}
Examples may not include all available fields for a type.
FeatureFlagRiskType
Description
The disruption risk level associated with an advanced configuration option (FeatureFlag).
Higher-risk options may cause service interruptions or other observable effects in your environment during the op.
Values
none
low
moderate
high
Example
"none"
GitAccount
Description
A Git account discovered or configured during an op.
Git accounts can be specified in the op configuration (via ScheduleOpFormInput.git_accounts) or discovered automatically by NodeZero during the op.
Fields
name - String!
source - GitAccountSource!
fragment GitAccountFragment on GitAccount {
name
source
}
Examples may not include all available fields for a type.
{
"name": "my-org",
"source": "GitHub"
}
GitAccountInput
Description
Input type for specifying a Git account to scan during an op.
Configure Git accounts via ScheduleOpFormInput.git_accounts to have NodeZero scan the specified repositories for exposed secrets and sensitive data.
Fields
name - StringNoWhitespace!
source - GitAccountSource!
# Example: Add git accounts to an op template
mutation SetGitAccounts($input: UpdateOpTemplateInput! = {
uuid: "1234abcd-1234-abcd-1234-abcd1234abcd",
schedule_op_form: {
git_accounts: [
{ name: "my-org", source: GitHub },
{ name: "my-team", source: GitLab }
]
}
}) {
update_op_template(input: $input) {
op_template {
uuid
schedule_op_form {
git_accounts {
name
source
}
}
}
}
}
Examples may not include all available fields for a type.
GitAccountSource
Description
The git hosting service for a GitAccount.
Values
GitLab
GitHub
Bitbucket
Example
"GitLab"
OpInput
Description
An input type for identifying an Op by its unique identifier.
Fields
op_id - String!
# Example: Fetch EDR hosts CSV
query EDRHostsCSV($input: OpInput!) {
edr_overview_hosts_csv_presigned_url(input: $input)
}
Examples may not include all available fields for a type.
Setup: Op Templates
Create and manage reusable pentest templates that define standard configurations for different testing scenarios. Templates can be linked to schedules for automated recurring pentests and shared across your organization.
op_templates_page
Description
Retrieve a paginated list of op templates for the current client account. Does not include default templates provided by Horizon3.ai.
Use the OpTemplate.uuid or OpTemplate.op_template_name fields from the results to fetch complete details about a specific OpTemplate via Query.op_template.
Response
Returns an OpTemplatesPage!
Arguments
page_input - PageInput
query GetOpTemplatesPage($page_input: PageInput) {
op_templates_page(page_input: $page_input) {
op_templates {
uuid
op_template_name
op_type
row_created_at
schedule_op_form {
op_name
op_param_max_scope
}
}
}
}
Examples may not include all available fields for a type.
{
"data": {
"op_templates_page": {
"op_templates": [
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_template_name": "Weekly Internal Pentest",
"op_type": "NodeZero",
"row_created_at": "2024-01-15T10:30:00.000000",
"schedule_op_form": {
"op_name": "Weekly Internal Pentest",
"op_param_max_scope": "10.0.0.0/8"
}
},
{
"uuid": "2345bcde-2345-bcde-2345-bcde2345bcde",
"op_template_name": "External Attack Assessment",
"op_type": "ExternalAttack",
"row_created_at": "2024-01-10T08:15:00.000000",
"schedule_op_form": {
"op_name": "External Attack Assessment",
"op_param_max_scope": null
}
}
]
}
}
}
python h3_gql.py ./op_templates_page.graphql '{
"page_input": {
"page_size": 10
}
}'
Save the example request as ./op_templates_page.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./op_templates_page.graphql '{
"page_input": {
"page_size": 10
}
}'
Save the example request as ./op_templates_page.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./op_templates_page.graphql '{
"page_input": {
"page_size": 10
}
}'
Save the example request as ./op_templates_page.graphql.
See h3-cli Examples for installation and usage.
op_templates_count
Description
Get the total count of OpTemplate records for the current client account. Does not include default templates provided by Horizon3.ai.
Response
Returns an Int!
Arguments
page_input - PageInput
query GetOpTemplatesCount($page_input: PageInput) {
op_templates_count(page_input: $page_input)
}
Examples may not include all available fields for a type.
{
"data": {
"op_templates_count": 5
}
}
python h3_gql.py ./op_templates_count.graphql
Save the example request as ./op_templates_count.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./op_templates_count.graphql
Save the example request as ./op_templates_count.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./op_templates_count.graphql
Save the example request as ./op_templates_count.graphql.
See h3-cli Examples for installation and usage.
op_template
Description
Retrieve a single op template by its unique identifier or name. Exactly one parameter must be provided. Returns the matching OpTemplate or null if not found.
Response
Returns an OpTemplate
query GetOpTemplate($op_template_uuid: String) {
op_template(op_template_uuid: $op_template_uuid) {
...OpTemplateFragment
}
}
fragment OpTemplateFragment on OpTemplate {
uuid
op_template_name
name
op_type
user_account_uuid
client_account_uuid
row_created_at
row_updated_at
schedule_op_form {
op_name
op_type
op_param_max_scope
maximum_run_time
}
}
Examples may not include all available fields for a type.
{
"data": {
"op_template": {
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_template_name": "Weekly Internal Pentest",
"name": "Weekly Internal Pentest",
"op_type": "NodeZero",
"user_account_uuid": "a1b2c3d4-a1b2-c3d4-a1b2-c3d4a1b2c3d4",
"client_account_uuid": "b2c3d4e5-b2c3-d4e5-b2c3-d4e5b2c3d4e5",
"row_created_at": "2024-01-15T10:30:00.000000",
"row_updated_at": "2024-01-20T14:45:00.000000",
"schedule_op_form": {
"op_name": "Weekly Internal Pentest",
"op_type": "NodeZero",
"op_param_max_scope": "10.0.0.0/8",
"maximum_run_time": 480
}
}
}
}
python h3_gql.py ./op_template.graphql '{
"op_template_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./op_template.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./op_template.graphql '{
"op_template_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./op_template.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./op_template.graphql '{
"op_template_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./op_template.graphql.
See h3-cli Examples for installation and usage.
create_op_template
Description
Create an OpTemplate. An OpTemplate is a reusable template for running pentests and other op types.
Response
Returns a SaveOpTemplateOutput!
Arguments
op_template_name - String!
schedule_op_form - ScheduleOpFormInput!
campaign_uuid - String
mutation CreateOpTemplate(
$op_template_name: String!
$schedule_op_form: ScheduleOpFormInput!
) {
create_op_template(
op_template_name: $op_template_name
schedule_op_form: $schedule_op_form
) {
op_template {
uuid
op_template_name
op_type
row_created_at
schedule_op_form {
op_name
op_type
op_param_max_scope
maximum_run_time
}
}
}
}
Examples may not include all available fields for a type.
{
"data": {
"create_op_template": {
"op_template": {
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_template_name": "Weekly Internal Pentest",
"op_type": "NodeZero",
"row_created_at": "2024-01-15T10:30:00.000000",
"schedule_op_form": {
"op_name": "Weekly Internal Pentest",
"op_type": "NodeZero",
"op_param_max_scope": "10.0.0.0/8",
"maximum_run_time": 480
}
}
}
}
}
python h3_gql.py ./create_op_template.graphql '{
"op_template_name": "Weekly Internal Pentest",
"schedule_op_form": {
"op_name": "Weekly Internal Pentest",
"op_type": "NodeZero",
"op_param_max_scope": "10.0.0.0/8",
"maximum_run_time": 480
}
}'
Save the example request as ./create_op_template.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./create_op_template.graphql '{
"op_template_name": "Weekly Internal Pentest",
"schedule_op_form": {
"op_name": "Weekly Internal Pentest",
"op_type": "NodeZero",
"op_param_max_scope": "10.0.0.0/8",
"maximum_run_time": 480
}
}'
Save the example request as ./create_op_template.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./create_op_template.graphql '{
"op_template_name": "Weekly Internal Pentest",
"schedule_op_form": {
"op_name": "Weekly Internal Pentest",
"op_type": "NodeZero",
"op_param_max_scope": "10.0.0.0/8",
"maximum_run_time": 480
}
}'
Save the example request as ./create_op_template.graphql.
See h3-cli Examples for installation and usage.
update_op_template
Description
Update an OpTemplate.
- Allows for template renaming.
- Allows for partial/patch updates of
OpTemplate.schedule_op_form.
Response
Returns an UpdateOpTemplateOutput!
Arguments
input - UpdateOpTemplateInput!
mutation UpdateOpTemplate($input: UpdateOpTemplateInput!) {
update_op_template(input: $input) {
op_template {
uuid
op_template_name
op_type
row_updated_at
schedule_op_form {
op_name
op_type
op_param_max_scope
maximum_run_time
}
}
}
}
Examples may not include all available fields for a type.
{
"data": {
"update_op_template": {
"op_template": {
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_template_name": "Weekly Internal Pentest - Updated",
"op_type": "NodeZero",
"row_updated_at": "2024-01-20T14:45:00.000000",
"schedule_op_form": {
"op_name": "Weekly Internal Pentest - Updated",
"op_type": "NodeZero",
"op_param_max_scope": "192.168.0.0/16",
"maximum_run_time": 600
}
}
}
}
}
python h3_gql.py ./update_op_template.graphql '{
"input": {
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_template_name": "Weekly Internal Pentest - Updated",
"schedule_op_form": {
"op_param_max_scope": "192.168.0.0/16",
"maximum_run_time": 600
}
}
}'
Save the example request as ./update_op_template.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./update_op_template.graphql '{
"input": {
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_template_name": "Weekly Internal Pentest - Updated",
"schedule_op_form": {
"op_param_max_scope": "192.168.0.0/16",
"maximum_run_time": 600
}
}
}'
Save the example request as ./update_op_template.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./update_op_template.graphql '{
"input": {
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_template_name": "Weekly Internal Pentest - Updated",
"schedule_op_form": {
"op_param_max_scope": "192.168.0.0/16",
"maximum_run_time": 600
}
}
}'
Save the example request as ./update_op_template.graphql.
See h3-cli Examples for installation and usage.
update_op_templates
Description
Update a batch of OpTemplates.
- Allows for template renaming.
- Allows for partial/patch updates of
OpTemplate.schedule_op_form.
Response
Returns [UpdateOpTemplateOutput!]!
Arguments
input - [UpdateOpTemplateInput!]!
mutation UpdateOpTemplates($input: [UpdateOpTemplateInput!]!) {
update_op_templates(input: $input) {
op_template {
uuid
name
op_type
schedule_op_form {
op_name
op_type
op_param_max_scope
}
row_updated_at
}
}
}
Examples may not include all available fields for a type.
{
"data": {
"update_op_templates": [
{
"op_template": {
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"name": "Updated Internal Assessment",
"op_type": "NodeZero",
"schedule_op_form": {
"op_name": "Weekly Internal Scan - Updated",
"op_type": "NodeZero",
"op_param_max_scope": "10.0.0.0/8,172.16.0.0/12"
},
"row_updated_at": "2024-03-20T15:45:00Z"
}
},
{
"op_template": {
"uuid": "5678efgh-5678-efgh-5678-efgh5678efgh",
"name": "Updated External Test",
"op_type": "ExternalAttack",
"schedule_op_form": {
"op_name": "Monthly External Test - Revised",
"op_type": "ExternalAttack",
"op_param_max_scope": null
},
"row_updated_at": "2024-03-20T15:45:00Z"
}
}
]
}
}
python h3_gql.py ./update_op_templates.graphql '{
"input": [
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_template_name": "Updated Internal Assessment",
"schedule_op_form": {
"op_name": "Weekly Internal Scan - Updated",
"op_param_max_scope": "10.0.0.0/8,172.16.0.0/12"
}
},
{
"uuid": "5678abcd-5678-abcd-5678-abcd5678abcd",
"op_template_name": "Updated External Test",
"schedule_op_form": {
"op_name": "Monthly External Test - Revised"
}
}
]
}'
Save the example request as ./update_op_templates.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./update_op_templates.graphql '{
"input": [
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_template_name": "Updated Internal Assessment",
"schedule_op_form": {
"op_name": "Weekly Internal Scan - Updated",
"op_param_max_scope": "10.0.0.0/8,172.16.0.0/12"
}
},
{
"uuid": "5678abcd-5678-abcd-5678-abcd5678abcd",
"op_template_name": "Updated External Test",
"schedule_op_form": {
"op_name": "Monthly External Test - Revised"
}
}
]
}'
Save the example request as ./update_op_templates.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./update_op_templates.graphql '{
"input": [
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_template_name": "Updated Internal Assessment",
"schedule_op_form": {
"op_name": "Weekly Internal Scan - Updated",
"op_param_max_scope": "10.0.0.0/8,172.16.0.0/12"
}
},
{
"uuid": "5678abcd-5678-abcd-5678-abcd5678abcd",
"op_template_name": "Updated External Test",
"schedule_op_form": {
"op_name": "Monthly External Test - Revised"
}
}
]
}'
Save the example request as ./update_op_templates.graphql.
See h3-cli Examples for installation and usage.
delete_op_template
Description
Delete an op template by its display name.
Response
Returns a DeleteOpTemplateOutput!
mutation DeleteOpTemplate($op_template_name: String!) {
delete_op_template(op_template_name: $op_template_name) {
op_template {
uuid
op_template_name
op_type
}
}
}
Examples may not include all available fields for a type.
{
"data": {
"delete_op_template": {
"op_template": {
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_template_name": "Weekly Internal Pentest",
"op_type": "NodeZero"
}
}
}
}
python h3_gql.py ./delete_op_template.graphql '{
"op_template_name": "Weekly Internal Pentest"
}'
Save the example request as ./delete_op_template.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./delete_op_template.graphql '{
"op_template_name": "Weekly Internal Pentest"
}'
Save the example request as ./delete_op_template.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./delete_op_template.graphql '{
"op_template_name": "Weekly Internal Pentest"
}'
Save the example request as ./delete_op_template.graphql.
See h3-cli Examples for installation and usage.
delete_op_template_by_uuid
Description
Delete an op template by its unique identifier.
Response
Returns a DeleteOpTemplateOutput!
mutation DeleteOpTemplateByUuid($uuid: String!, $also_delete_schedules: Boolean) {
delete_op_template_by_uuid(uuid: $uuid, also_delete_schedules: $also_delete_schedules) {
op_template {
uuid
name
op_type
}
}
}
Examples may not include all available fields for a type.
{
"data": {
"delete_op_template_by_uuid": {
"op_template": {
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"name": "Internal Network Assessment",
"op_type": "NodeZero"
}
}
}
}
python h3_gql.py ./delete_op_template_by_uuid.graphql '{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"also_delete_schedules": false
}'
Save the example request as ./delete_op_template_by_uuid.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./delete_op_template_by_uuid.graphql '{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"also_delete_schedules": false
}'
Save the example request as ./delete_op_template_by_uuid.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./delete_op_template_by_uuid.graphql '{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"also_delete_schedules": false
}'
Save the example request as ./delete_op_template_by_uuid.graphql.
See h3-cli Examples for installation and usage.
delete_op_templates_by_uuids
Description
Delete multiple op templates by their unique identifiers.
Response
Returns [DeleteOpTemplateOutput!]!
Arguments
uuids - [String!]!
also_delete_schedules - Boolean
mutation DeleteOpTemplatesByUuids($uuids: [String!]!, $also_delete_schedules: Boolean) {
delete_op_templates_by_uuids(uuids: $uuids, also_delete_schedules: $also_delete_schedules) {
op_template {
uuid
name
op_type
}
}
}
Examples may not include all available fields for a type.
{
"data": {
"delete_op_templates_by_uuids": [
{
"op_template": {
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"name": "Internal Network Assessment",
"op_type": "NodeZero"
}
},
{
"op_template": {
"uuid": "5678efgh-5678-efgh-5678-efgh5678efgh",
"name": "External Attack Simulation",
"op_type": "ExternalAttack"
}
}
]
}
}
python h3_gql.py ./delete_op_templates_by_uuids.graphql '{
"uuids": [
"1234abcd-1234-abcd-1234-abcd1234abcd",
"5678abcd-5678-abcd-5678-abcd5678abcd"
],
"also_delete_schedules": false
}'
Save the example request as ./delete_op_templates_by_uuids.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./delete_op_templates_by_uuids.graphql '{
"uuids": [
"1234abcd-1234-abcd-1234-abcd1234abcd",
"5678abcd-5678-abcd-5678-abcd5678abcd"
],
"also_delete_schedules": false
}'
Save the example request as ./delete_op_templates_by_uuids.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./delete_op_templates_by_uuids.graphql '{
"uuids": [
"1234abcd-1234-abcd-1234-abcd1234abcd",
"5678abcd-5678-abcd-5678-abcd5678abcd"
],
"also_delete_schedules": false
}'
Save the example request as ./delete_op_templates_by_uuids.graphql.
See h3-cli Examples for installation and usage.
op_templates
Description
List of op templates for the current client account. Includes default templates provided by Horizon3.ai.
Response
Returns [OpTemplate]
query OpTemplates($op_type: String) {
op_templates(op_type: $op_type) {
uuid
name
op_type
schedule_op_form {
op_name
op_type
op_param_blacklist
op_param_min_scope
op_param_max_scope
runner_uuid
}
row_created_at
row_updated_at
}
}
Examples may not include all available fields for a type.
{
"data": {
"op_templates": [
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"name": "Internal Network Assessment",
"op_type": "NodeZero",
"schedule_op_form": {
"op_name": "Weekly Internal Scan",
"op_type": "NodeZero",
"op_param_blacklist": null,
"op_param_min_scope": null,
"op_param_max_scope": "10.0.0.0/8,172.16.0.0/12,192.168.0.0/16",
"runner_uuid": "abcd1234-abcd-1234-abcd-1234abcd1234"
},
"row_created_at": "2024-03-15T10:30:00Z",
"row_updated_at": "2024-03-15T10:30:00Z"
},
{
"uuid": "5678efgh-5678-efgh-5678-efgh5678efgh",
"name": "External Attack Simulation",
"op_type": "ExternalAttack",
"schedule_op_form": {
"op_name": "Monthly External Test",
"op_type": "ExternalAttack",
"op_param_blacklist": "203.0.113.0/24",
"op_param_min_scope": null,
"op_param_max_scope": null,
"runner_uuid": "efgh5678-efgh-5678-efgh-5678efgh5678"
},
"row_created_at": "2024-03-10T14:20:00Z",
"row_updated_at": "2024-03-12T09:15:00Z"
}
]
}
}
python h3_gql.py ./op_templates.graphql '{
"op_type": "NodeZero"
}'
Save the example request as ./op_templates.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./op_templates.graphql '{
"op_type": "NodeZero"
}'
Save the example request as ./op_templates.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./op_templates.graphql '{
"op_type": "NodeZero"
}'
Save the example request as ./op_templates.graphql.
See h3-cli Examples for installation and usage.
op_templates_facets
Description
Retrieve available filter values and counts for op templates. Returns distinct values that can be used to filter the op templates list, such as runner names.
Response
Returns an OpTemplatesFacets!
Arguments
page_input - PageInput
query OpTemplatesFacets($page_input: PageInput) {
op_templates_facets(page_input: $page_input) {
page_info {
page_size
}
runner_name {
label
value
value_count
}
}
}
Examples may not include all available fields for a type.
{
"data": {
"op_templates_facets": {
"page_info": {
"page_size": 10
},
"runner_name": [
{
"label": "Attack Path Validation",
"value": "attack_path_validation",
"value_count": 3
},
{
"label": "External Assessment",
"value": "external_assessment",
"value_count": 2
},
{
"label": "Internal Assessment",
"value": "internal_assessment",
"value_count": 5
}
]
}
}
}
python h3_gql.py ./op_templates_facets.graphql
Save the example request as ./op_templates_facets.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./op_templates_facets.graphql
Save the example request as ./op_templates_facets.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./op_templates_facets.graphql
Save the example request as ./op_templates_facets.graphql.
See h3-cli Examples for installation and usage.
OpTemplate
Description
An OpTemplate is a reusable template for running pentests and other op types.
An OpTemplate can be linked to a Schedule to run ops on a regular schedule.
See ScheduleOpForm for the configuration options available when creating an OpTemplate.
Fields
uuid - String!
user_account_uuid - String!
client_account_uuid - String!
client_account - ClientAccount!
op_template_name - String!
name - String!
schedule_op_form - ScheduleOpForm!
schedules - [Schedule!]!
row_created_at - Datetime!
row_updated_at - Datetime
fragment OpTemplateFragment on OpTemplate {
uuid
op_template_name
name
op_type
user_account_uuid
client_account_uuid
row_created_at
row_updated_at
schedule_op_form {
op_name
op_type
op_param_max_scope
op_param_blacklist
maximum_run_time
minimum_run_time
}
schedules {
uuid
name
}
}
Examples may not include all available fields for a type.
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_template_name": "Weekly Internal Pentest",
"name": "Weekly Internal Pentest",
"op_type": "NodeZero",
"user_account_uuid": "a1b2c3d4-a1b2-c3d4-a1b2-c3d4a1b2c3d4",
"client_account_uuid": "b2c3d4e5-b2c3-d4e5-b2c3-d4e5b2c3d4e5",
"row_created_at": "2024-01-15T10:30:00.000000",
"row_updated_at": "2024-01-20T14:45:00.000000",
"schedule_op_form": {
"op_name": "Weekly Internal Pentest",
"op_type": "NodeZero",
"op_param_max_scope": "10.0.0.0/8",
"op_param_blacklist": "10.0.0.1",
"maximum_run_time": 480,
"minimum_run_time": 60
},
"schedules": [
{
"uuid": "5678efgh-5678-efgh-5678-efgh5678efgh",
"name": "Weekly Monday 9am"
}
]
}
DeleteOpTemplateOutput
Description
Output returned when deleting an OpTemplate.
Fields
op_template - OpTemplate
fragment DeleteOpTemplateOutputFragment on DeleteOpTemplateOutput {
op_template {
uuid
op_template_name
op_type
}
}
Examples may not include all available fields for a type.
{
"op_template": {
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_template_name": "Weekly Internal Pentest",
"op_type": "NodeZero"
}
}
OpTemplatesFacets
Description
Facets for op templates filtering. Provides available filter values with counts for the current dataset.
Fields
page_info - PageInfo
runner_name - [FacetValue!]!
OpTemplate.schedule_op_form.runner_name values present in the data after applying any filters. fragment OpTemplatesFacetsFragment on OpTemplatesFacets {
page_info {
page_size
}
runner_name {
label
value
value_count
}
}
Examples may not include all available fields for a type.
{
"page_info": {
"page_size": 25
},
"runner_name": [
{
"label": "Runner 1",
"value": "runner_1",
"value_count": 8
},
{
"label": "Runner 2",
"value": "runner_2",
"value_count": 5
},
{
"label": "Default Runner",
"value": "default_runner",
"value_count": 12
}
]
}
OpTemplatesPage
Description
Contains a paginated list of OpTemplate records.
Fields
page_info - PageInfo
op_templates - [OpTemplate!]!
fragment OpTemplatesPageFragment on OpTemplatesPage {
page_info {
page_size
page_num
}
op_templates {
uuid
op_template_name
op_type
row_created_at
}
}
Examples may not include all available fields for a type.
{
"page_info": {
"page_size": 10,
"page_num": 1
},
"op_templates": [
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_template_name": "Weekly Internal Pentest",
"op_type": "NodeZero",
"row_created_at": "2024-01-15T10:30:00.000000"
},
{
"uuid": "2345bcde-2345-bcde-2345-bcde2345bcde",
"op_template_name": "External Attack Assessment",
"op_type": "ExternalAttack",
"row_created_at": "2024-01-10T08:15:00.000000"
}
]
}
SaveOpTemplateOutput
Description
Output returned when creating or saving an OpTemplate.
Fields
op_template - OpTemplate!
asset_group - AssetGroup
fragment SaveOpTemplateOutputFragment on SaveOpTemplateOutput {
op_template {
uuid
op_template_name
op_type
row_created_at
schedule_op_form {
op_name
op_param_max_scope
}
}
asset_group {
uuid
name
}
}
Examples may not include all available fields for a type.
{
"op_template": {
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_template_name": "Weekly Internal Pentest",
"op_type": "NodeZero",
"row_created_at": "2024-01-15T10:30:00.000000",
"schedule_op_form": {
"op_name": "Weekly Internal Pentest",
"op_param_max_scope": "10.0.0.0/8"
}
},
"asset_group": null
}
UpdateOpTemplateInput
Description
Input type for Mutation.update_op_template.
Fields
uuid - String!
op_template_name - String
schedule_op_form - ScheduleOpFormInput
# Example 1: Rename an op template
mutation RenameOpTemplate($input: UpdateOpTemplateInput! = {
uuid: "1234abcd-1234-abcd-1234-abcd1234abcd",
op_template_name: "New Template Name"
}) {
update_op_template(input: $input) {
op_template {
uuid
op_template_name
}
}
}
# Example 2: Update op template scope (partial update)
mutation UpdateOpTemplateScope($input: UpdateOpTemplateInput! = {
uuid: "1234abcd-1234-abcd-1234-abcd1234abcd",
schedule_op_form: {
op_param_max_scope: "192.168.0.0/16"
}
}) {
update_op_template(input: $input) {
op_template {
uuid
op_template_name
schedule_op_form {
op_param_max_scope
}
}
}
}
# Example 3: Update multiple fields
mutation UpdateOpTemplateMultiple($input: UpdateOpTemplateInput! = {
uuid: "1234abcd-1234-abcd-1234-abcd1234abcd",
op_template_name: "Updated Weekly Pentest",
schedule_op_form: {
op_param_max_scope: "10.0.0.0/8",
maximum_run_time: 600
}
}) {
update_op_template(input: $input) {
op_template {
uuid
op_template_name
schedule_op_form {
op_param_max_scope
maximum_run_time
}
}
}
}
Examples may not include all available fields for a type.
UpdateOpTemplateOutput
Description
Output returned when updating an OpTemplate.
Fields
op_template - OpTemplate!
fragment UpdateOpTemplateOutputFragment on UpdateOpTemplateOutput {
op_template {
uuid
op_template_name
op_type
row_updated_at
schedule_op_form {
op_name
op_param_max_scope
maximum_run_time
}
}
}
Examples may not include all available fields for a type.
{
"op_template": {
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_template_name": "Weekly Internal Pentest - Updated",
"op_type": "NodeZero",
"row_updated_at": "2024-01-20T14:45:00.000000",
"schedule_op_form": {
"op_name": "Weekly Internal Pentest - Updated",
"op_param_max_scope": "192.168.0.0/16",
"maximum_run_time": 600
}
}
}
Setup: Runners
Deploy and manage NodeZero runners (agents and Kubernetes operators) that execute pentests from within your network perimeter. Runners simplify the process of launching internal pentests on a Docker host within your network. Runners are required for running internal pentests on an automated recurring basis using a Schedule.
agents_page
Description
Returns a paginated list of NodeZero Runners (Agents) belonging to the current user's ClientAccount.
Use PageInput to control pagination, sorting, and filtering. Set include_sub_client_agents to true to also include Runners from sub-client accounts (requires multi-tenancy to be enabled).
Response
Returns an AgentsPage!
query AgentsPage($page_input: PageInput) {
agents_page(page_input: $page_input) {
agents {
uuid
name
user_account_name
api_key_uuid
created_at
is_kubernetes
kubernetes_namespace
h3_cli_version
last_heartbeat_at
last_heartbeat_time_ago
active_op_id
}
page_info {
page_num
page_size
}
}
}
Examples may not include all available fields for a type.
{
"data": {
"agents_page": {
"agents": [
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"name": "runner-production",
"user_account_name": "admin@example.com",
"api_key_uuid": "5678efgh-5678-efgh-5678-efgh5678efgh",
"created_at": "2024-01-15T10:30:00Z",
"is_kubernetes": false,
"kubernetes_namespace": null,
"h3_cli_version": "4.2.1",
"last_heartbeat_at": "2024-01-15T14:25:00Z",
"last_heartbeat_time_ago": "5 minutes ago",
"active_op_id": "op-9012ijkl-9012-ijkl-9012-ijkl9012ijkl"
},
{
"uuid": "2345bcde-2345-bcde-2345-bcde2345bcde",
"name": "runner-staging",
"user_account_name": "devops@example.com",
"api_key_uuid": "6789fghi-6789-fghi-6789-fghi6789fghi",
"created_at": "2024-01-14T09:15:00Z",
"is_kubernetes": true,
"kubernetes_namespace": "nodezero",
"h3_cli_version": "4.2.1",
"last_heartbeat_at": "2024-01-15T14:20:00Z",
"last_heartbeat_time_ago": "10 minutes ago",
"active_op_id": null
}
],
"page_info": {
"page_num": 1,
"page_size": 10
}
}
}
}
python h3_gql.py ./agents_page.graphql '{
"page_input": {
"page_num": 1,
"page_size": 10
}
}'
Save the example request as ./agents_page.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./agents_page.graphql '{
"page_input": {
"page_num": 1,
"page_size": 10
}
}'
Save the example request as ./agents_page.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./agents_page.graphql '{
"page_input": {
"page_num": 1,
"page_size": 10
}
}'
Save the example request as ./agents_page.graphql.
See h3-cli Examples for installation and usage.
agents_count
Description
Returns the total count of NodeZero Runners (Agents) belonging to the current user's ClientAccount.
Supports the same filtering criteria as agents_page via PageInput. Set include_sub_client_agents to true to include Runners from sub-client accounts.
Response
Returns an Int!
query AgentsCount($page_input: PageInput, $include_sub_clients: Boolean) {
agents_count(
page_input: $page_input
include_sub_client_agents: $include_sub_clients
)
}
Examples may not include all available fields for a type.
{
"data": {
"agents_count": 12
}
}
python h3_gql.py ./agents_count.graphql '{
"include_sub_clients": false
}'
Save the example request as ./agents_count.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./agents_count.graphql '{
"include_sub_clients": false
}'
Save the example request as ./agents_count.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./agents_count.graphql '{
"include_sub_clients": false
}'
Save the example request as ./agents_count.graphql.
See h3-cli Examples for installation and usage.
agent
Description
Retrieves a single NodeZero Runner (Agent) by its uuid or name within the current user's ClientAccount.
You must provide either uuid or name. Returns null if no matching Runner is found.
Response
Returns an Agent
query Agent($uuid: String, $name: String) {
agent(uuid: $uuid, name: $name) {
uuid
name
user_account_name
api_key_uuid
api_key {
uuid
starts_with
}
uname
log_file
last_heartbeat_at
last_heartbeat_time_ago
last_heartbeat_source_ip
last_command {
command
received_at
completed_at
exit_status
}
commands {
command
received_at
completed_at
exit_status
}
created_at
h3_cli_version
is_kubernetes
kubernetes_namespace
active_op_id
op_next_scheduled_at
}
}
Examples may not include all available fields for a type.
{
"data": {
"agent": {
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"name": "runner-production",
"user_account_name": "admin@example.com",
"api_key_uuid": "5678efgh-5678-efgh-5678-efgh5678efgh",
"api_key": {
"uuid": "5678abcd-5678-abcd-5678-abcd5678abcd",
"starts_with": "h3_api_sk_abc..."
},
"uname": "Linux hostname 5.15.0-56-generic #62-Ubuntu SMP",
"log_file": "/var/log/nodezero/runner.log",
"last_heartbeat_at": "2024-01-15T14:25:00Z",
"last_heartbeat_time_ago": "5 minutes ago",
"last_heartbeat_source_ip": "192.168.1.100",
"last_command": {
"command": "run-pentest",
"received_at": "2024-01-15T14:20:00Z",
"completed_at": "2024-01-15T14:25:00Z",
"exit_status": "0"
},
"commands": [
{
"command": "run-pentest",
"received_at": "2024-01-15T14:20:00Z",
"completed_at": "2024-01-15T14:25:00Z",
"exit_status": "0"
},
{
"command": "heartbeat",
"received_at": "2024-01-15T14:15:00Z",
"completed_at": "2024-01-15T14:15:01Z",
"exit_status": "0"
}
],
"created_at": "2024-01-15T10:30:00Z",
"h3_cli_version": "4.2.1",
"is_kubernetes": false,
"kubernetes_namespace": null,
"active_op_id": "op-9012ijkl-9012-ijkl-9012-ijkl9012ijkl",
"op_next_scheduled_at": "2024-01-16T02:00:00Z"
}
}
}
python h3_gql.py ./agent.graphql '{
"name": "runner-production"
}'
Save the example request as ./agent.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./agent.graphql '{
"name": "runner-production"
}'
Save the example request as ./agent.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./agent.graphql '{
"name": "runner-production"
}'
Save the example request as ./agent.graphql.
See h3-cli Examples for installation and usage.
install_agent
Description
Creates a new NodeZero Runner and returns the installation command needed to deploy it.
NodeZero Runners are lightweight agents that run on your infrastructure and automatically launch NodeZero pentests whenever an Op is created and configured to use the Runner. You can also configure an OpTemplate to use a Runner for all ops created from that template.
This mutation creates a new API key with NODEZERO_RUNNER permissions (or reuses the existing NODEZERO_OPERATOR key for Kubernetes deployments). The API key is embedded in the installation command and stored on the Runner's host.
The InstallAgentOutput includes:
- The shell command to install and start the Runner (either
commandfor Docker hosts orkubernetes_install_commandfor K8s). - The Agent record representing the Runner, whose
uuidcan be used to assign it to an Op or OpTemplate even before installation completes.
Note: NodeZero Runners are referred to as Agents throughout the API.
Response
Returns an InstallAgentOutput!
Arguments
agent_name - String
name instead. name - String
is_kubernetes - Boolean
false. kubernetes_namespace - String
nodezero if omitted. Only applicable when is_kubernetes is true. mutation InstallAgent($name: String!, $is_kubernetes: Boolean, $kubernetes_namespace: String) {
install_agent(
name: $name
is_kubernetes: $is_kubernetes
kubernetes_namespace: $kubernetes_namespace
) {
command
kubernetes_install_command
agent {
uuid
name
created_at
is_kubernetes
kubernetes_namespace
}
}
}
Examples may not include all available fields for a type.
{
"data": {
"install_agent": {
"command": "docker run -d --name runner-production --restart unless-stopped -v /var/run/docker.sock:/var/run/docker.sock -e H3_API_KEY=h3_api_sk_abcdef123456789 -e H3_AGENT_NAME=runner-production horizon3ai/h3-cli:latest agent start",
"kubernetes_install_command": null,
"agent": {
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"name": "runner-production",
"created_at": "2024-01-15T10:30:00Z",
"is_kubernetes": false,
"kubernetes_namespace": null
}
}
}
}
python h3_gql.py ./install_agent.graphql '{
"name": "runner-production",
"is_kubernetes": false
}'
Save the example request as ./install_agent.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./install_agent.graphql '{
"name": "runner-production",
"is_kubernetes": false
}'
Save the example request as ./install_agent.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./install_agent.graphql '{
"name": "runner-production",
"is_kubernetes": false
}'
Save the example request as ./install_agent.graphql.
See h3-cli Examples for installation and usage.
hello_agent
Description
Sends a hello-world command to the Runner identified by the given AgentInput.name.
Use this mutation to test connectivity with a Runner and verify that it is active and able to receive and execute commands. The command is queued and delivered to the Runner during its next heartbeat. The resulting AgentCommand can be monitored to confirm the Runner successfully received and executed the ping.
Response
Returns an AgentCommand
Arguments
input - AgentInput!
mutation HelloAgent($input: AgentInput!) {
hello_agent(input: $input) {
uuid
agent_uuid
command
received_at
completed_at
exit_status
log
created_at
}
}
Examples may not include all available fields for a type.
{
"data": {
"hello_agent": {
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"agent_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"command": "hello",
"received_at": null,
"completed_at": null,
"exit_status": null,
"log": null,
"created_at": "2024-01-15T10:30:00Z"
}
}
}
python h3_gql.py ./hello_agent.graphql '{
"input": {
"name": "runner-production"
}
}'
Save the example request as ./hello_agent.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./hello_agent.graphql '{
"input": {
"name": "runner-production"
}
}'
Save the example request as ./hello_agent.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./hello_agent.graphql '{
"input": {
"name": "runner-production"
}
}'
Save the example request as ./hello_agent.graphql.
See h3-cli Examples for installation and usage.
upgrade_agent
Description
Queues an upgrade command to the Runner identified by the given agent_name or agent_uuid. The Runner will upgrade to the latest version of h3-cli and restart itself.
The Runner must be active and running h3-cli version 2023-06-05 or later to receive the upgrade command. The command is delivered during the Runner's next heartbeat.
You may provide either agent_name or agent_uuid to identify the target Runner.
Response
Returns an AgentCommandOutput!
mutation UpgradeAgent($agent_name: String) {
upgrade_agent(agent_name: $agent_name) {
agent_command {
uuid
agent_uuid
command
received_at
completed_at
exit_status
log
created_at
}
message
}
}
Examples may not include all available fields for a type.
{
"data": {
"upgrade_agent": {
"agent_command": {
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"agent_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"command": "upgrade",
"received_at": null,
"completed_at": null,
"exit_status": null,
"log": null,
"created_at": "2024-01-15T10:30:00Z"
},
"message": "Upgrade command queued for runner-production"
}
}
}
python h3_gql.py ./upgrade_agent.graphql '{
"agent_name": "runner-production"
}'
Save the example request as ./upgrade_agent.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./upgrade_agent.graphql '{
"agent_name": "runner-production"
}'
Save the example request as ./upgrade_agent.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./upgrade_agent.graphql '{
"agent_name": "runner-production"
}'
Save the example request as ./upgrade_agent.graphql.
See h3-cli Examples for installation and usage.
delete_agent
Description
Deletes the NodeZero Runner (Agent) identified by the given agent_name or agent_uuid.
When a Runner is deleted:
- For Docker-based Runners, the associated API key is revoked.
- For Kubernetes Runners, the API key is not revoked because it belongs to the Operator.
- The Runner is removed from any OpTemplates it was assigned to.
You may provide either agent_name or agent_uuid to identify the target Runner.
Response
Returns an AgentOutput!
mutation DeleteAgent($agent_uuid: String) {
delete_agent(agent_uuid: $agent_uuid) {
agent {
uuid
name
created_at
is_kubernetes
}
}
}
Examples may not include all available fields for a type.
{
"data": {
"delete_agent": {
"agent": {
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"name": "runner-production",
"created_at": "2024-01-15T10:30:00Z",
"is_kubernetes": false
}
}
}
}
python h3_gql.py ./delete_agent.graphql '{
"agent_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./delete_agent.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./delete_agent.graphql '{
"agent_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./delete_agent.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./delete_agent.graphql '{
"agent_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./delete_agent.graphql.
See h3-cli Examples for installation and usage.
operators_page
Description
Returns a paginated list of NodeZero Kubernetes Operators belonging to the current user's ClientAccount.
Use PageInput to control pagination, sorting, and filtering. Set include_sub_client_operators to true to also include Operators from sub-client accounts (requires multi-tenancy to be enabled).
Response
Returns an OperatorsPage!
query OperatorsPage($page_input: PageInput, $include_sub_clients: Boolean) {
operators_page(
page_input: $page_input
include_sub_client_operators: $include_sub_clients
) {
operators {
uuid
name
version
chart_version
is_registered
}
page_info {
page_num
page_size
}
}
}
Examples may not include all available fields for a type.
{
"data": {
"operators_page": {
"operators": [
{
"uuid": "3456cdef-3456-cdef-3456-cdef3456cdef",
"name": "nodezero-operator-prod",
"version": "2.1.0",
"chart_version": "1.5.2",
"is_registered": true
},
{
"uuid": "4567defg-4567-defg-4567-defg4567defg",
"name": "nodezero-operator-dev",
"version": "2.0.9",
"chart_version": "1.5.1",
"is_registered": true
}
],
"page_info": {
"page_num": 1,
"page_size": 10
}
}
}
}
python h3_gql.py ./operators_page.graphql '{
"page_input": {
"page_num": 1,
"page_size": 10
},
"include_sub_clients": false
}'
Save the example request as ./operators_page.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./operators_page.graphql '{
"page_input": {
"page_num": 1,
"page_size": 10
},
"include_sub_clients": false
}'
Save the example request as ./operators_page.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./operators_page.graphql '{
"page_input": {
"page_num": 1,
"page_size": 10
},
"include_sub_clients": false
}'
Save the example request as ./operators_page.graphql.
See h3-cli Examples for installation and usage.
operators_count
Description
Returns the total count of NodeZero Kubernetes Operators belonging to the current user's ClientAccount.
Supports the same filtering criteria as operators_page via PageInput. Set include_sub_client_operators to true to include Operators from sub-client accounts.
Response
Returns an Int!
query OperatorsCount($page_input: PageInput, $include_sub_clients: Boolean) {
operators_count(
page_input: $page_input
include_sub_client_operators: $include_sub_clients
)
}
Examples may not include all available fields for a type.
{
"data": {
"operators_count": 5
}
}
python h3_gql.py ./operators_count.graphql '{
"include_sub_clients": false
}'
Save the example request as ./operators_count.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./operators_count.graphql '{
"include_sub_clients": false
}'
Save the example request as ./operators_count.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./operators_count.graphql '{
"include_sub_clients": false
}'
Save the example request as ./operators_count.graphql.
See h3-cli Examples for installation and usage.
create_operator
Description
Creates a new NodeZero Kubernetes Operator and returns the Helm install command needed to deploy it to your cluster.
The Operator manages the lifecycle of NodeZero Runners within Kubernetes. Once installed, you can create Runners as Kubernetes custom resources via install_agent with is_kubernetes: true.
This mutation also creates a new API key with NODEZERO_OPERATOR permissions. The key is embedded in the Helm install command.
operator_name(required): The name for the Operator.use_cilium: Set totrueif the cluster uses Cilium, to include aCiliumNetworkPolicyin the deployment. Defaults tofalse.use_kyverno: Set totrueif the cluster uses Kyverno, to include a KyvernoPolicyExceptionin the deployment. Defaults tofalse.
Response
Returns a CreateOperatorOutput!
mutation CreateOperator($operator_name: String!, $use_cilium: Boolean, $use_kyverno: Boolean) {
create_operator(
operator_name: $operator_name
use_cilium: $use_cilium
use_kyverno: $use_kyverno
) {
command
operator {
uuid
name
version
chart_version
is_registered
}
}
}
Examples may not include all available fields for a type.
{
"data": {
"create_operator": {
"command": "helm install nodezero-operator-prod horizon3/nodezero-operator --namespace nodezero --create-namespace --set apiKey=h3_api_sk_xyz789 --set operatorName=nodezero-operator-prod",
"operator": {
"uuid": "3456cdef-3456-cdef-3456-cdef3456cdef",
"name": "nodezero-operator-prod",
"version": "2.1.0",
"chart_version": "1.5.2",
"is_registered": true
}
}
}
}
python h3_gql.py ./create_operator.graphql '{
"operator_name": "nodezero-operator-prod",
"use_cilium": false,
"use_kyverno": false
}'
Save the example request as ./create_operator.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./create_operator.graphql '{
"operator_name": "nodezero-operator-prod",
"use_cilium": false,
"use_kyverno": false
}'
Save the example request as ./create_operator.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./create_operator.graphql '{
"operator_name": "nodezero-operator-prod",
"use_cilium": false,
"use_kyverno": false
}'
Save the example request as ./create_operator.graphql.
See h3-cli Examples for installation and usage.
upgrade_operator
Description
Returns a Helm upgrade command to upgrade the NodeZero Kubernetes Operator Helm chart to the latest available version.
Run the returned command against your Kubernetes cluster to apply the upgrade.
Response
Returns an UpgradeOperatorOutput!
mutation UpgradeOperator {
upgrade_operator {
command
}
}
Examples may not include all available fields for a type.
{
"data": {
"upgrade_operator": {
"command": "helm upgrade nodezero-operator horizon3/nodezero-operator --namespace nodezero --reuse-values"
}
}
}
python h3_gql.py ./upgrade_operator.graphql
Save the example request as ./upgrade_operator.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./upgrade_operator.graphql
Save the example request as ./upgrade_operator.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./upgrade_operator.graphql
Save the example request as ./upgrade_operator.graphql.
See h3-cli Examples for installation and usage.
delete_operator
Description
Deletes the NodeZero Kubernetes Operator identified by the given operator_uuid.
Deleting an Operator also revokes and deletes the API key associated with it. Any Runners managed by this Operator should be removed from the cluster before deleting the Operator.
Response
Returns an Operator
Arguments
operator_uuid - String!
mutation DeleteOperator($operator_uuid: String!) {
delete_operator(operator_uuid: $operator_uuid) {
uuid
name
version
chart_version
is_registered
}
}
Examples may not include all available fields for a type.
{
"data": {
"delete_operator": {
"uuid": "3456cdef-3456-cdef-3456-cdef3456cdef",
"name": "nodezero-operator-prod",
"version": "2.1.0",
"chart_version": "1.5.2",
"is_registered": false
}
}
}
python h3_gql.py ./delete_operator.graphql '{
"operator_uuid": "3456cdef-3456-cdef-3456-cdef3456cdef"
}'
Save the example request as ./delete_operator.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./delete_operator.graphql '{
"operator_uuid": "3456cdef-3456-cdef-3456-cdef3456cdef"
}'
Save the example request as ./delete_operator.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./delete_operator.graphql '{
"operator_uuid": "3456cdef-3456-cdef-3456-cdef3456cdef"
}'
Save the example request as ./delete_operator.graphql.
See h3-cli Examples for installation and usage.
agents_facets
Description
Returns the available facet (filter) values for the Runner list, along with occurrence counts for each value.
Use these facets to build dynamic filter controls for the agents_page query. Supports the same filtering criteria via PageInput. Set include_sub_client_agents to true to include facet values from sub-client accounts.
Response
Returns an AgentsFacets!
query AgentsFacets($page_input: PageInput, $include_sub_clients: Boolean) {
agents_facets(
page_input: $page_input
include_sub_client_agents: $include_sub_clients
) {
kubernetes_namespace {
label
value
value_count
}
user_account_name {
label
value
value_count
}
user_role_id {
label
value
value_count
}
page_info {
page_num
page_size
}
}
}
Examples may not include all available fields for a type.
{
"data": {
"agents_facets": {
"kubernetes_namespace": [
{ "label": "default", "value": "default", "value_count": 3 },
{ "label": "nodezero", "value": "nodezero", "value_count": 5 },
{ "label": "production", "value": "production", "value_count": 2 }
],
"user_account_name": [
{ "label": "admin@example.com", "value": "admin@example.com", "value_count": 4 },
{ "label": "devops@example.com", "value": "devops@example.com", "value_count": 3 },
{ "label": "security@example.com", "value": "security@example.com", "value_count": 1 }
],
"user_role_id": [
{ "label": "admin", "value": "admin", "value_count": 2 },
{ "label": "operator", "value": "operator", "value_count": 5 },
{ "label": "viewer", "value": "viewer", "value_count": 3 }
],
"page_info": {
"page_num": 1,
"page_size": 10
}
}
}
}
python h3_gql.py ./agents_facets.graphql '{
"include_sub_clients": false
}'
Save the example request as ./agents_facets.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./agents_facets.graphql '{
"include_sub_clients": false
}'
Save the example request as ./agents_facets.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./agents_facets.graphql '{
"include_sub_clients": false
}'
Save the example request as ./agents_facets.graphql.
See h3-cli Examples for installation and usage.
agent_commands_facets
Description
Returns the available facet (filter) values for a specific Runner's command list, along with occurrence counts for each value.
The agent_uuid parameter identifies the Runner whose commands should be analyzed.
Response
Returns an AgentCommandsFacets!
query AgentCommandsFacets(
$agent_uuid: String!
$page_input: PageInput
) {
agent_commands_facets(
agent_uuid: $agent_uuid
page_input: $page_input
) {
exit_status {
label
value
value_count
}
page_info {
page_num
page_size
}
}
}
Examples may not include all available fields for a type.
{
"data": {
"agent_commands_facets": {
"exit_status": [
{ "label": "0", "value": "0", "value_count": 15 },
{ "label": "1", "value": "1", "value_count": 3 },
{ "label": "null", "value": "null", "value_count": 2 }
],
"page_info": {
"page_num": 1,
"page_size": 10
}
}
}
}
python h3_gql.py ./agent_commands_facets.graphql '{
"agent_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./agent_commands_facets.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./agent_commands_facets.graphql '{
"agent_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./agent_commands_facets.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./agent_commands_facets.graphql '{
"agent_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./agent_commands_facets.graphql.
See h3-cli Examples for installation and usage.
operators_facets
Description
Returns the available facet (filter) values for the Operator list, along with occurrence counts for each value.
Use these facets to build dynamic filter controls for the operators_page query. Supports the same filtering criteria via PageInput. Set include_sub_client_operators to true to include facet values from sub-client accounts.
Response
Returns an OperatorsFacets!
query OperatorsFacets(
$page_input: PageInput
$include_sub_client_operators: Boolean
) {
operators_facets(
page_input: $page_input
include_sub_client_operators: $include_sub_client_operators
) {
version {
label
value
value_count
}
chart_version {
label
value
value_count
}
user_role_id {
label
value
value_count
}
}
}
Examples may not include all available fields for a type.
{
"data": {
"operators_facets": {
"version": [
{ "label": "1.2.0", "value": "1.2.0", "value_count": 3 },
{ "label": "1.1.0", "value": "1.1.0", "value_count": 2 }
],
"chart_version": [
{ "label": "0.5.0", "value": "0.5.0", "value_count": 4 }
],
"user_role_id": [
{ "label": "ORG_ADMIN", "value": "ORG_ADMIN", "value_count": 2 },
{ "label": "USER", "value": "USER", "value_count": 3 }
]
}
}
}
python h3_gql.py ./operators_facets.graphql '{
"include_sub_client_operators": false
}'
Save the example request as ./operators_facets.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./operators_facets.graphql '{
"include_sub_client_operators": false
}'
Save the example request as ./operators_facets.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./operators_facets.graphql '{
"include_sub_client_operators": false
}'
Save the example request as ./operators_facets.graphql.
See h3-cli Examples for installation and usage.
Agent
Description
Represents a NodeZero Runner.
A NodeZero Runner is a lightweight agent that runs on your infrastructure and enables the automated deployment and execution of NodeZero pentests. Runners periodically heartbeat to the platform to receive and execute commands such as launching an Op, upgrading, or caching credentials.
Note: Runners are referred to as "Agents" throughout the API.
Fields
uuid - String!
name - String!
user_account_name - String
api_key_uuid - String!
api_key - APIKey!
uname - String
uname system command on the Runner's host machine. Provides operating system and kernel information. log_file - String
last_heartbeat_at - Datetime
last_heartbeat_time_ago - String
last_heartbeat_at, for example "3 minutes ago". Returns null if the Runner has never sent a heartbeat. last_heartbeat_source_ip - String
last_command - AgentCommand
commands - [AgentCommand]
last_n commands for this Runner, ordered by most recent first. Defaults to 20; maximum is 100. Arguments
last_n - Int
commands_page - AgentCommandsPage
Arguments
page_input - PageInput
created_at - Datetime!
h3_cli_version - String
is_kubernetes - Boolean!
kubernetes_namespace - String
is_kubernetes is true. fragment AgentFragment on Agent {
uuid
name
user_account_name
api_key_uuid
api_key
uname
log_file
last_heartbeat_at
last_heartbeat_time_ago
last_heartbeat_source_ip
last_command
commands
created_at
h3_cli_version
is_kubernetes
kubernetes_namespace
active_op_id
op_next_scheduled_at
}
Examples may not include all available fields for a type.
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"name": "runner-production",
"user_account_name": "admin@example.com",
"api_key_uuid": "5678efgh-5678-efgh-5678-efgh5678efgh",
"api_key": "h3_api_sk_abcdef123456789",
"uname": "Linux hostname 5.15.0-56-generic #62-Ubuntu SMP",
"log_file": "/var/log/nodezero/runner.log",
"last_heartbeat_at": "2024-01-15T14:25:00Z",
"last_heartbeat_time_ago": "5 minutes ago",
"last_heartbeat_source_ip": "192.168.1.100",
"last_command": "h3 op run --op-id op-9012ijkl-9012-ijkl-9012-ijkl9012ijkl",
"commands": [
"h3 op run --op-id op-9012ijkl-9012-ijkl-9012-ijkl9012ijkl",
"h3 agent heartbeat"
],
"created_at": "2024-01-15T10:30:00Z",
"h3_cli_version": "4.2.1",
"is_kubernetes": false,
"kubernetes_namespace": null,
"active_op_id": "op-9012ijkl-9012-ijkl-9012-ijkl9012ijkl",
"op_next_scheduled_at": "2024-01-16T02:00:00Z"
}
Operator
Description
A Kubernetes (K8s) Operator that manages the lifecycle of NodeZero Runners (Agents) within a Kubernetes cluster.
The Operator is installed via a Helm chart (see create_operator) and manages the deployment, scaling, and upgrading of Runners as Kubernetes custom resources.
Fields
uuid - ID!
name - String!
version - String
chart_version - String
is_registered - Boolean!
fragment OperatorFragment on Operator {
uuid
name
version
chart_version
is_registered
}
Examples may not include all available fields for a type.
{
"uuid": "3456cdef-3456-cdef-3456-cdef3456cdef",
"name": "nodezero-operator-prod",
"version": "2.1.0",
"chart_version": "1.5.2",
"is_registered": true
}
AgentCommand
Description
Represents a command that has been queued or executed by a NodeZero Runner (see Agent).
Commands are created by the platform (for example, via hello_agent or upgrade_agent) and delivered to the Runner during its next heartbeat. The Runner then executes the command and reports back the exit status and log output.
Fields
uuid - String!
command - String!
hello-world, upgrade, or run-nodezero <op_id>). received_at - Datetime
null if the command has not yet been picked up. completed_at - Datetime
null if the command has not yet completed. exit_status - String
"0" indicates success. log - String
created_at - Datetime!
fragment AgentCommandFragment on AgentCommand {
uuid
agent_uuid
command
received_at
completed_at
exit_status
log
created_at
}
Examples may not include all available fields for a type.
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"agent_uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"command": "upgrade",
"received_at": "2024-01-15T09:00:05Z",
"completed_at": "2024-01-15T09:01:30Z",
"exit_status": "0",
"log": "Upgrade completed successfully",
"created_at": "2024-01-15T09:00:00Z"
}
AgentCommandOutput
Description
Output type for mutations that create or update AgentCommands, such as upgrade_agent and hello_agent.
Fields
agent_command - AgentCommand
message - String
fragment AgentCommandOutputFragment on AgentCommandOutput {
agent_command {
uuid
agent_uuid
command
received_at
completed_at
exit_status
log
created_at
}
message
}
Examples may not include all available fields for a type.
{
"agent_command": {
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"agent_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"command": "upgrade",
"received_at": "2024-01-15T10:30:05Z",
"completed_at": "2024-01-15T10:31:30Z",
"exit_status": "0",
"log": "Upgrade completed successfully",
"created_at": "2024-01-15T10:30:00Z"
},
"message": "Upgrade command queued for runner-production"
}
AgentCommandsFacets
Description
Facet values for filtering AgentCommands. Each facet field returns the distinct values present in the current dataset along with their occurrence counts, enabling you to build dynamic filter controls.
Fields
page_info - PageInfo
exit_status - [FacetValue]
fragment AgentCommandsFacetsFragment on AgentCommandsFacets {
exit_status {
label
value
value_count
}
page_info {
page_num
page_size
}
}
Examples may not include all available fields for a type.
{
"exit_status": [
{ "label": "0", "value": "0", "value_count": 15 },
{ "label": "1", "value": "1", "value_count": 3 },
{ "label": "null", "value": "null", "value_count": 2 }
],
"page_info": {
"page_num": 1,
"page_size": 10
}
}
AgentCommandsPage
Description
A paginated list of AgentCommands for a given Runner.
Fields
agent_commands - [AgentCommand]!
page_info - PageInfo
total_count - Int!
fragment AgentCommandsPageFragment on AgentCommandsPage {
agent_commands {
uuid
agent_uuid
command
exit_status
received_at
completed_at
created_at
}
page_info {
page_num
page_size
}
}
Examples may not include all available fields for a type.
{
"agent_commands": [
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"agent_uuid": "5678efgh-5678-efgh-5678-efgh5678efgh",
"command": "upgrade",
"exit_status": "0",
"received_at": "2024-03-10T14:30:00Z",
"completed_at": "2024-03-10T14:31:15Z",
"created_at": "2024-03-10T14:29:50Z"
},
{
"uuid": "2345bcde-2345-bcde-2345-bcde2345bcde",
"agent_uuid": "5678efgh-5678-efgh-5678-efgh5678efgh",
"command": "hello",
"exit_status": "0",
"received_at": "2024-03-10T14:00:00Z",
"completed_at": "2024-03-10T14:00:05Z",
"created_at": "2024-03-10T13:59:55Z"
}
],
"page_info": {
"page_num": 1,
"page_size": 10
}
}
AgentInput
Description
Input type for Mutation.hello_agent.
Identifies a NodeZero Runner by name. The name field is required and must match an existing Runner in your ClientAccount.
mutation HelloAgent($input: AgentInput! = {
name: "runner-production"
}) {
hello_agent(input: $input) {
uuid
agent_uuid
command
created_at
}
}
Examples may not include all available fields for a type.
AgentOutput
Description
Output type for mutations that operate on Agents, such as delete_agent.
fragment AgentOutputFragment on AgentOutput {
agent {
uuid
name
user_account_name
uname
last_heartbeat_at
last_heartbeat_time_ago
h3_cli_version
created_at
is_kubernetes
}
}
Examples may not include all available fields for a type.
{
"agent": {
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"name": "runner-production",
"user_account_name": "admin@example.com",
"uname": "Linux runner-host 5.15.0-91-generic x86_64",
"last_heartbeat_at": "2024-01-15T10:35:00Z",
"last_heartbeat_time_ago": "3 minutes ago",
"h3_cli_version": "3.42.0",
"created_at": "2024-01-10T08:00:00Z",
"is_kubernetes": false
}
}
AgentsFacets
Description
Facet values for filtering Agents (NodeZero Runners). Each facet field returns the distinct values present in the current dataset along with their occurrence counts, enabling you to build dynamic filter controls for the Runner list.
Fields
page_info - PageInfo
kubernetes_namespace - [FacetValue]
user_account_name - [FacetValue]
user_role_id - [FacetValue]
user_role_id) present in the data after applying any active filters, along with the count of Runners for each role. fragment AgentsFacetsFragment on AgentsFacets {
kubernetes_namespace
user_account_name
user_role_id
page_info {
page_num
page_size
}
}
Examples may not include all available fields for a type.
{
"kubernetes_namespace": ["default", "nodezero", "production"],
"user_account_name": ["admin@example.com", "devops@example.com", "security@example.com"],
"user_role_id": ["admin", "operator", "viewer"],
"page_info": {
"page_num": 1,
"page_size": 10
}
}
AgentsPage
Description
A paginated list of NodeZero Runners (Agents).
fragment AgentsPageFragment on AgentsPage {
agents {
uuid
name
user_account_name
created_at
is_kubernetes
}
page_info {
page_num
page_size
}
}
Examples may not include all available fields for a type.
{
"agents": [
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"name": "runner-production",
"user_account_name": "admin@example.com",
"created_at": "2024-01-15T10:30:00Z",
"is_kubernetes": false
},
{
"uuid": "2345bcde-2345-bcde-2345-bcde2345bcde",
"name": "runner-staging",
"user_account_name": "devops@example.com",
"created_at": "2024-01-14T09:15:00Z",
"is_kubernetes": true
}
],
"page_info": {
"page_num": 1,
"page_size": 10
}
}
CreateOperatorOutput
Description
Output type for create_operator.
Contains the Helm install command, the newly created API key, and the Operator record.
Fields
command - String!
fragment CreateOperatorOutputFragment on CreateOperatorOutput {
command
operator {
uuid
name
version
chart_version
is_registered
}
}
Examples may not include all available fields for a type.
{
"command": "helm install nodezero-operator-prod horizon3/nodezero-operator --namespace nodezero --create-namespace --set apiKey=h3_api_sk_xyz789 --set operatorName=nodezero-operator-prod",
"operator": {
"uuid": "3456cdef-3456-cdef-3456-cdef3456cdef",
"name": "nodezero-operator-prod",
"version": "2.1.0",
"chart_version": "1.5.2",
"is_registered": true
}
}
InstallAgentOutput
Description
Output type for install_agent.
Contains the shell command needed to install and start a NodeZero Runner on the target host, along with the API key and Agent record created for the Runner.
Fields
command - String
The shell command for installing the NodeZero Runner on a Docker host. Run this command on the machine where you want the Runner to operate. It downloads, installs, and starts the Runner process.
This field is populated only when is_kubernetes is false (or omitted) in install_agent. For Kubernetes deployments, use the kubernetes_install_command field instead.
kubernetes_install_command - String
The kubectl command for deploying the NodeZero Runner as a custom resource in a Kubernetes cluster. Run this command against the cluster where the Operator is installed.
This field is populated only when is_kubernetes is true in install_agent. For non-Kubernetes deployments, use the command field instead.
api_key - APIKey
NODEZERO_RUNNER permissions. For Kubernetes Runners, the existing Operator's NODEZERO_OPERATOR key is returned. agent - Agent
uuid to assign the Runner to an OpTemplate or Op even before the Runner has been installed and started on the host. fragment InstallAgentOutputFragment on InstallAgentOutput {
command
kubernetes_install_command
agent {
uuid
name
created_at
is_kubernetes
}
}
Examples may not include all available fields for a type.
{
"command": "docker run -d --name runner-production --restart unless-stopped -v /var/run/docker.sock:/var/run/docker.sock -e H3_API_KEY=h3_api_sk_abcdef123456789 -e H3_AGENT_NAME=runner-production horizon3ai/h3-cli:latest agent start",
"kubernetes_install_command": null,
"agent": {
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"name": "runner-production",
"created_at": "2024-01-15T10:30:00Z",
"is_kubernetes": false
}
}
OperatorsFacets
Description
Facet values for filtering Operators. Each facet field returns the distinct values present in the current dataset along with their occurrence counts, enabling you to build dynamic filter controls for the Operator list.
Fields
page_info - PageInfo
version - [FacetValue]
chart_version - [FacetValue]
user_role_id - [FacetValue]
user_role_id) present in the data after applying any active filters, along with the count of Operators for each role. fragment OperatorsFacetsFragment on OperatorsFacets {
page_info {
page_num
page_size
}
version {
label
value
value_count
}
chart_version {
label
value
value_count
}
user_role_id {
label
value
value_count
}
}
Examples may not include all available fields for a type.
{
"page_info": {
"page_num": 1,
"page_size": 10
},
"version": [
{ "label": "1.2.0", "value": "1.2.0", "value_count": 3 },
{ "label": "1.1.0", "value": "1.1.0", "value_count": 2 }
],
"chart_version": [
{ "label": "0.5.0", "value": "0.5.0", "value_count": 4 }
],
"user_role_id": [
{ "label": "ORG_ADMIN", "value": "ORG_ADMIN", "value_count": 2 },
{ "label": "USER", "value": "USER", "value_count": 3 }
]
}
OperatorsPage
Description
A paginated list of NodeZero Kubernetes Operators.
Fields
page_info - PageInfo
operators - [Operator!]!
fragment OperatorsPageFragment on OperatorsPage {
operators {
uuid
name
version
chart_version
is_registered
}
page_info {
page_num
page_size
}
}
Examples may not include all available fields for a type.
{
"operators": [
{
"uuid": "3456cdef-3456-cdef-3456-cdef3456cdef",
"name": "nodezero-operator-prod",
"version": "2.1.0",
"chart_version": "1.5.2",
"is_registered": true
},
{
"uuid": "4567defg-4567-defg-4567-defg4567defg",
"name": "nodezero-operator-dev",
"version": "2.0.9",
"chart_version": "1.5.1",
"is_registered": true
}
],
"page_info": {
"page_num": 1,
"page_size": 10
}
}
UpgradeOperatorOutput
Description
Output type for upgrade_operator.
Fields
command - String!
fragment UpgradeOperatorOutputFragment on UpgradeOperatorOutput {
command
}
Examples may not include all available fields for a type.
{
"command": "helm upgrade nodezero-operator horizon3/nodezero-operator --namespace nodezero --reuse-values"
}
Setup: Schedules
Automate recurring pentests and operations with flexible scheduling. Create, update, and manage scheduled actions that run pentests at specified intervals (daily, weekly, monthly) to maintain continuous security validation.
schedules_page
Description
List of Schedules and ScheduledActions in the current account.
The Schedule.uuid field can be used to fetch more details about a specific Schedule via Query.schedule.
Response
Returns a SchedulesPage!
Arguments
page_input - PageInput
query SchedulesPage($page_input: PageInput) {
schedules_page(page_input: $page_input) {
schedules {
uuid
name
is_disabled
ops_count
last_op {
op_name
op_state
}
actions {
uuid
action
cadence
cron_expression
cron_description
is_disabled
schedule_uuid
schedule_name
op_template_uuid
last_triggered_at
last_triggered_time_ago
next_triggered_at
next_triggered_time_in
total_triggers
}
}
page_info {
page_num
page_size
}
}
}
Examples may not include all available fields for a type.
{
"data": {
"schedules_page": {
"schedules": [
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"name": "Weekly Infrastructure Scan",
"is_disabled": false,
"ops_count": 52,
"last_op": {
"op_name": "Weekly Scan - Week 52",
"op_state": "done"
},
"actions": [
{
"uuid": "5678efgh-5678-efgh-5678-efgh5678efgh",
"action": "run-pentest",
"cadence": "Weekly",
"cron_expression": "0 2 * * MON",
"cron_description": "Every Monday at 2:00 AM",
"is_disabled": false,
"schedule_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"schedule_name": "Weekly Infrastructure Scan",
"op_template_uuid": "9999aaaa-9999-aaaa-9999-aaaa9999aaaa",
"last_triggered_at": "2024-12-30T02:00:00Z",
"last_triggered_time_ago": "5 days ago",
"next_triggered_at": "2025-01-06T02:00:00Z",
"next_triggered_time_in": "in 2 days",
"total_triggers": 52
}
]
}
],
"page_info": {
"page_num": 1,
"page_size": 25
}
}
}
}
python h3_gql.py ./schedules_page.graphql '{
"page_input": {
"page_size": 10,
"page_num": 1
}
}'
Save the example request as ./schedules_page.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./schedules_page.graphql '{
"page_input": {
"page_size": 10,
"page_num": 1
}
}'
Save the example request as ./schedules_page.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./schedules_page.graphql '{
"page_input": {
"page_size": 10,
"page_num": 1
}
}'
Save the example request as ./schedules_page.graphql.
See h3-cli Examples for installation and usage.
schedules_count
Description
Count of Schedules in the current account.
Response
Returns an Int!
Arguments
page_input - PageInput
query SchedulesCount($page_input: PageInput) {
schedules_count(page_input: $page_input)
}
Examples may not include all available fields for a type.
{
"data": {
"schedules_count": 3
}
}
python h3_gql.py ./schedules_count.graphql '{
"page_input": {
"page_size": 100
}
}'
Save the example request as ./schedules_count.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./schedules_count.graphql '{
"page_input": {
"page_size": 100
}
}'
Save the example request as ./schedules_count.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./schedules_count.graphql '{
"page_input": {
"page_size": 100
}
}'
Save the example request as ./schedules_count.graphql.
See h3-cli Examples for installation and usage.
schedule
Description
Get the Schedule with the given uuid or name. Provide either uuid or name to identify the schedule.
Response
Returns a Schedule
query Schedule($uuid: String, $name: String) {
schedule(uuid: $uuid, name: $name) {
uuid
name
is_disabled
ops_count
last_op {
op_name
op_state
op_type
}
actions {
uuid
action
cadence
cron_expression
cron_description
is_disabled
schedule_uuid
schedule_name
op_template_uuid
last_triggered_at
last_triggered_time_ago
next_triggered_at
next_triggered_time_in
total_triggers
}
}
}
Examples may not include all available fields for a type.
{
"data": {
"schedule": {
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"name": "Weekly Infrastructure Scan",
"is_disabled": false,
"ops_count": 52,
"last_op": {
"op_name": "Weekly Scan - Week 52",
"op_state": "done",
"op_type": "NodeZero"
},
"actions": [
{
"uuid": "5678efgh-5678-efgh-5678-efgh5678efgh",
"action": "run-pentest",
"cadence": "Weekly",
"cron_expression": "0 2 * * MON",
"cron_description": "Every Monday at 2:00 AM",
"is_disabled": false,
"schedule_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"schedule_name": "Weekly Infrastructure Scan",
"op_template_uuid": "9999aaaa-9999-aaaa-9999-aaaa9999aaaa",
"last_triggered_at": "2024-12-30T02:00:00Z",
"last_triggered_time_ago": "5 days ago",
"next_triggered_at": "2025-01-06T02:00:00Z",
"next_triggered_time_in": "in 2 days",
"total_triggers": 52
}
]
}
}
}
python h3_gql.py ./schedule.graphql '{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./schedule.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./schedule.graphql '{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./schedule.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./schedule.graphql '{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./schedule.graphql.
See h3-cli Examples for installation and usage.
create_scheduled_action
Description
Create or update a ScheduledAction.
ScheduledActions are actions within a Schedule that run at a specific time, similar to a cron job. A Schedule is automatically created if one doesn't already exist for the given schedule_name.
A ScheduledAction can be used to run a pentest on a recurring basis, eg. weekly or monthly.
You can also use ScheduledActions to pause, resume, and cancel a pentest at specific times, for example to pause a pentest during a maintenance window. See CreateScheduledActionInput.action for more details.
Response
Returns a ScheduledActionOutput!
Arguments
input - CreateScheduledActionInput!
mutation CreateScheduledAction($input: CreateScheduledActionInput!) {
create_scheduled_action(input: $input) {
scheduled_action {
uuid
action
cadence
cron_expression
cron_description
is_disabled
schedule_uuid
schedule_name
op_template_uuid
last_triggered_at
next_triggered_at
next_triggered_time_in
total_triggers
}
}
}
Examples may not include all available fields for a type.
{
"data": {
"create_scheduled_action": {
"scheduled_action": {
"uuid": "5678efgh-5678-efgh-5678-efgh5678efgh",
"action": "run-pentest",
"cadence": "Weekly",
"cron_expression": "0 2 * * MON",
"cron_description": "Every Monday at 2:00 AM",
"is_disabled": false,
"schedule_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"schedule_name": "Weekly Infrastructure Scan",
"op_template_uuid": "9999aaaa-9999-aaaa-9999-aaaa9999aaaa",
"last_triggered_at": null,
"next_triggered_at": "2025-01-06T02:00:00Z",
"next_triggered_time_in": "in 2 days",
"total_triggers": 0
}
}
}
}
python h3_gql.py ./create_scheduled_action.graphql '{
"input": {
"schedule_name": "Weekly Infrastructure Scan",
"action": "run-pentest",
"cron_expression": "0 2 * * MON",
"op_template_uuid": "9999aaaa-9999-aaaa-9999-aaaa9999aaaa"
}
}'
Save the example request as ./create_scheduled_action.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./create_scheduled_action.graphql '{
"input": {
"schedule_name": "Weekly Infrastructure Scan",
"action": "run-pentest",
"cron_expression": "0 2 * * MON",
"op_template_uuid": "9999aaaa-9999-aaaa-9999-aaaa9999aaaa"
}
}'
Save the example request as ./create_scheduled_action.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./create_scheduled_action.graphql '{
"input": {
"schedule_name": "Weekly Infrastructure Scan",
"action": "run-pentest",
"cron_expression": "0 2 * * MON",
"op_template_uuid": "9999aaaa-9999-aaaa-9999-aaaa9999aaaa"
}
}'
Save the example request as ./create_scheduled_action.graphql.
See h3-cli Examples for installation and usage.
trigger_scheduled_action
Description
Trigger a ScheduledAction to run now.
This mutation can be used to verify a ScheduledAction's configuration and ensure it behaves as expected. It can also be used as a convenient way to run a pentest immediately, without waiting for the next scheduled time.
Response
Returns a ScheduledActionOutput!
Arguments
input - TriggerScheduledActionInput!
mutation TriggerScheduledAction($input: TriggerScheduledActionInput!) {
trigger_scheduled_action(input: $input) {
scheduled_action {
uuid
action
schedule_name
last_triggered_at
last_triggered_time_ago
next_triggered_at
next_triggered_time_in
total_triggers
}
}
}
Examples may not include all available fields for a type.
{
"data": {
"trigger_scheduled_action": {
"scheduled_action": {
"uuid": "5678efgh-5678-efgh-5678-efgh5678efgh",
"action": "run-pentest",
"schedule_name": "Weekly Infrastructure Scan",
"last_triggered_at": "2024-12-31T14:30:00Z",
"last_triggered_time_ago": "just now",
"next_triggered_at": "2025-01-06T02:00:00Z",
"next_triggered_time_in": "in 6 days",
"total_triggers": 53
}
}
}
}
python h3_gql.py ./trigger_scheduled_action.graphql '{
"input": {
"schedule_name": "Weekly Infrastructure Scan",
"action": "run-pentest"
}
}'
Save the example request as ./trigger_scheduled_action.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./trigger_scheduled_action.graphql '{
"input": {
"schedule_name": "Weekly Infrastructure Scan",
"action": "run-pentest"
}
}'
Save the example request as ./trigger_scheduled_action.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./trigger_scheduled_action.graphql '{
"input": {
"schedule_name": "Weekly Infrastructure Scan",
"action": "run-pentest"
}
}'
Save the example request as ./trigger_scheduled_action.graphql.
See h3-cli Examples for installation and usage.
update_scheduled_action
Description
Update a ScheduledAction.
Response
Returns a ScheduledActionOutput!
Arguments
input - UpdateScheduledActionInput!
mutation UpdateScheduledAction($input: UpdateScheduledActionInput!) {
update_scheduled_action(input: $input) {
scheduled_action {
uuid
action
cadence
cron_expression
cron_description
is_disabled
schedule_uuid
schedule_name
op_template_uuid
last_triggered_at
next_triggered_at
next_triggered_time_in
total_triggers
}
}
}
Examples may not include all available fields for a type.
{
"data": {
"update_scheduled_action": {
"scheduled_action": {
"uuid": "5678efgh-5678-efgh-5678-efgh5678efgh",
"action": "run-pentest",
"cadence": "Daily",
"cron_expression": "0 3 * * *",
"cron_description": "Every day at 3:00 AM",
"is_disabled": false,
"schedule_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"schedule_name": "Weekly Infrastructure Scan",
"op_template_uuid": "9999aaaa-9999-aaaa-9999-aaaa9999aaaa",
"last_triggered_at": "2024-12-30T03:00:00Z",
"next_triggered_at": "2024-12-31T03:00:00Z",
"next_triggered_time_in": "in 1 day",
"total_triggers": 30
}
}
}
}
python h3_gql.py ./update_scheduled_action.graphql '{
"input": {
"uuid": "5678abcd-5678-abcd-5678-abcd5678abcd",
"cron_expression": "0 3 * * *"
}
}'
Save the example request as ./update_scheduled_action.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./update_scheduled_action.graphql '{
"input": {
"uuid": "5678abcd-5678-abcd-5678-abcd5678abcd",
"cron_expression": "0 3 * * *"
}
}'
Save the example request as ./update_scheduled_action.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./update_scheduled_action.graphql '{
"input": {
"uuid": "5678abcd-5678-abcd-5678-abcd5678abcd",
"cron_expression": "0 3 * * *"
}
}'
Save the example request as ./update_scheduled_action.graphql.
See h3-cli Examples for installation and usage.
delete_scheduled_action
Description
Delete a ScheduledAction. To fully delete a Schedule, delete all ScheduledActions within it.
Response
Returns a ScheduledActionOutput!
Arguments
input - DeleteScheduledActionInput!
mutation DeleteScheduledAction($input: DeleteScheduledActionInput!) {
delete_scheduled_action(input: $input) {
scheduled_action {
uuid
action
schedule_name
is_disabled
}
}
}
Examples may not include all available fields for a type.
{
"data": {
"delete_scheduled_action": {
"scheduled_action": {
"uuid": "5678efgh-5678-efgh-5678-efgh5678efgh",
"action": "run-pentest",
"schedule_name": "Weekly Infrastructure Scan",
"is_disabled": true
}
}
}
}
python h3_gql.py ./delete_scheduled_action.graphql '{
"input": {
"schedule_name": "Weekly Infrastructure Scan",
"action": "run-pentest"
}
}'
Save the example request as ./delete_scheduled_action.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./delete_scheduled_action.graphql '{
"input": {
"schedule_name": "Weekly Infrastructure Scan",
"action": "run-pentest"
}
}'
Save the example request as ./delete_scheduled_action.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./delete_scheduled_action.graphql '{
"input": {
"schedule_name": "Weekly Infrastructure Scan",
"action": "run-pentest"
}
}'
Save the example request as ./delete_scheduled_action.graphql.
See h3-cli Examples for installation and usage.
Schedule
Description
A Schedule is a set of ScheduledActions that can be used together to control the execution of a pentest on a recurring basis.
Use Mutation.create_scheduled_action to create a Schedule.
Typically a Schedule has only one ScheduledAction, with its action set to run-pentest. This is used to run a pentest at a specific date and time on a recurring basis.
A Schedule may further control the execution of pentests by using additional ScheduledActions with actions set to pause-pentest, resume-pentest, and/or cancel-pentest, for pausing, resuming, and canceling/ending the pentest respectively.
Fields
uuid - String!
name - String!
op_template_name - String
run-pentest action. actions - [ScheduledAction]
created_at - Datetime!
last_updated_at - Datetime
is_disabled - Boolean
true, no actions will execute at their scheduled times. Use Mutation.enable_schedule or Mutation.disable_schedule to toggle. state - String
ENABLED or DISABLED. ops_count - Int!
Arguments
page_input - PageInput
ops_page - OpsPage!
Arguments
page_input - PageInput
run_pentest_action - ScheduledAction
run-pentest ScheduledAction for this schedule, if one exists. total_triggers - Int
fragment ScheduleFragment on Schedule {
uuid
name
is_disabled
ops_count
last_op {
op_name
op_state
op_type
}
actions {
uuid
action
cadence
cron_expression
cron_description
is_disabled
op_template_uuid
last_triggered_at
next_triggered_at
total_triggers
}
}
Examples may not include all available fields for a type.
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"name": "Weekly Infrastructure Scan",
"is_disabled": false,
"ops_count": 52,
"last_op": {
"op_name": "Weekly Scan - Week 52",
"op_state": "done",
"op_type": "NodeZero"
},
"actions": [
{
"uuid": "5678efgh-5678-efgh-5678-efgh5678efgh",
"action": "run-pentest",
"cadence": "Weekly",
"cron_expression": "0 2 * * MON",
"cron_description": "Every Monday at 2:00 AM",
"is_disabled": false,
"op_template_uuid": "9999aaaa-9999-aaaa-9999-aaaa9999aaaa",
"last_triggered_at": "2024-12-30T02:00:00Z",
"next_triggered_at": "2025-01-06T02:00:00Z",
"total_triggers": 52
}
]
}
ScheduledAction
Description
An action to run at a specific time on a recurring schedule, like a cron job. ScheduledActions are useful for running pentests on a recurring basis, such as weekly or monthly.
There are four types of actions:
run-pentest: Run a pentest using the OpTemplate configured in the ScheduledAction.pause-pentest: Pause a pentest that is currently running.resume-pentest: Resume a paused pentest.cancel-pentest: Cancel a pentest that is currently running.
Fields
uuid - String!
schedule_name - String!
schedule_uuid - String!
action - String!
The action to execute. Supported actions are:
- run-pentest: Run a pentest using the OpTemplate configured in the ScheduledAction.
- pause-pentest: Pause a pentest that is currently running.
- resume-pentest: Resume a paused pentest.
- cancel-pentest: Cancel a pentest that is currently running.
cron_expression - String!
A cron expression that defines when the action is executed.
A cron expression is a string consisting of 5 fields separated by spaces. The 5 fields represent the following:
- minute (0–59) - this field must always be set to '*' or '0'.
- hour (0–23) - note this is in UTC time.
- day of the month (1–31)
- month (1–12)
- day of the week (0–6) (Sunday to Saturday)
Notes:
- ScheduledActions only support hourly resolution. The minutes field must always be set to '*' or '0'.
- The cron expression is configured in UTC time. If you want to run the action at a specific time in another timezone, you will need to convert that time to UTC.
- runs at midnight UTC every saturday
cron_description - String
op_template_uuid - String
run-pentest action. This is the uuid of the OpTemplate that will be used to run the pentest when the ScheduledAction is triggered. op_template - OpTemplate
run-pentest action. This is the OpTemplate that will be used to run the pentest when the ScheduledAction is triggered. last_triggered_at - Datetime
last_triggered_time_ago - String
last_triggered_at as a human-friendly "time ago" statement, eg. "3 minutes ago" last_triggered_error - String
next_triggered_at - Datetime
next_triggered_time_in - String
next_triggered_at as a human-friendly statement, eg. "3 minutes from now" next_triggered_ats - [Datetime]
next_n argument to specify how many upcoming times to return. Arguments
next_n - Int
cadence - String
is_disabled - Boolean
total_triggers - Int
fragment ScheduledActionFragment on ScheduledAction {
uuid
action
cadence
cron_expression
cron_description
is_disabled
schedule_uuid
schedule_name
op_template_uuid
last_triggered_at
last_triggered_time_ago
last_triggered_error
next_triggered_at
next_triggered_ats
next_triggered_time_in
total_triggers
}
Examples may not include all available fields for a type.
{
"uuid": "5678efgh-5678-efgh-5678-efgh5678efgh",
"action": "run-pentest",
"cadence": "Weekly",
"cron_expression": "0 2 * * MON",
"cron_description": "Every Monday at 2:00 AM",
"is_disabled": false,
"schedule_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"schedule_name": "Weekly Infrastructure Scan",
"op_template_uuid": "9999aaaa-9999-aaaa-9999-aaaa9999aaaa",
"last_triggered_at": "2024-12-30T02:00:00Z",
"last_triggered_time_ago": "5 days ago",
"last_triggered_error": null,
"next_triggered_at": "2025-01-06T02:00:00Z",
"next_triggered_ats": ["2025-01-06T02:00:00Z", "2025-01-13T02:00:00Z", "2025-01-20T02:00:00Z"],
"next_triggered_time_in": "in 2 days",
"total_triggers": 52
}
CreateScheduledActionInput
Description
Input type for Mutation.create_scheduled_action
Fields
schedule_name - String!
action - String!
The action to execute. Supported actions are:
- run-pentest: Run a pentest using the OpTemplate configured in the ScheduledAction.
- pause-pentest: Pause a pentest that is currently running.
- resume-pentest: Resume a paused pentest.
- cancel-pentest: Cancel a pentest that is currently running.
cron_expression - String!
A cron expression that defines when the action is executed.
A cron expression is a string consisting of 5 fields separated by spaces. The 5 fields represent the following:
- minute (0–59) - this field must always be set to '*' or '0'.
- hour (0–23) - note this is in UTC time.
- day of the month (1–31)
- month (1–12)
- day of the week (0–6) (Sunday to Saturday)
Notes:
- ScheduledActions only support hourly resolution. The minutes field must always be set to '*' or '0'.
- The cron expression is configured in UTC time. If you want to run the action at a specific time in another timezone, you will need to convert that time to UTC.
op_template_uuid - String
run-pentest action. This is the OpTemplate that will be used to run the pentest when the ScheduledAction is triggered. mutation CreateScheduledActionExample(
$input: CreateScheduledActionInput = {
schedule_name: "Weekly Infrastructure Scan"
action: "run-pentest"
cron_expression: "0 2 * * MON"
op_template_uuid: "9999aaaa-9999-aaaa-9999-aaaa9999aaaa"
}
) {
create_scheduled_action(input: $input) {
scheduled_action {
uuid
schedule_name
action
cron_expression
}
}
}
Examples may not include all available fields for a type.
DeleteScheduledActionInput
Description
Input type for Mutation.delete_scheduled_action
mutation DeleteScheduledActionExample(
$input: DeleteScheduledActionInput = {
schedule_name: "Weekly Infrastructure Scan"
action: "run-pentest"
}
) {
delete_scheduled_action(input: $input) {
scheduled_action {
uuid
schedule_name
action
is_disabled
}
}
}
Examples may not include all available fields for a type.
ScheduledActionOutput
Description
Output type for Mutation.create_scheduled_action and other mutations.
Fields
scheduled_action - ScheduledAction
fragment ScheduledActionOutputFragment on ScheduledActionOutput {
scheduled_action {
uuid
action
cadence
cron_expression
cron_description
is_disabled
schedule_uuid
schedule_name
op_template_uuid
total_triggers
}
}
Examples may not include all available fields for a type.
{
"scheduled_action": {
"uuid": "5678efgh-5678-efgh-5678-efgh5678efgh",
"action": "run-pentest",
"cadence": "Weekly",
"cron_expression": "0 2 * * MON",
"cron_description": "Every Monday at 2:00 AM",
"is_disabled": false,
"schedule_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"schedule_name": "Weekly Infrastructure Scan",
"op_template_uuid": "9999aaaa-9999-aaaa-9999-aaaa9999aaaa",
"total_triggers": 52
}
}
SchedulesPage
Description
Paginated list of Schedules.
Fields
page_info - PageInfo
schedules - [Schedule!]!
fragment SchedulesPageFragment on SchedulesPage {
schedules {
uuid
name
is_disabled
ops_count
actions {
uuid
action
}
}
page_info {
page_num
page_size
}
}
Examples may not include all available fields for a type.
{
"schedules": [
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"name": "Weekly Infrastructure Scan",
"is_disabled": false,
"ops_count": 52,
"actions": [
{
"uuid": "5678efgh-5678-efgh-5678-efgh5678efgh",
"action": "run-pentest"
}
]
},
{
"uuid": "9999bbbb-9999-bbbb-9999-bbbb9999bbbb",
"name": "Monthly Security Assessment",
"is_disabled": false,
"ops_count": 12,
"actions": [
{
"uuid": "aaaacccc-aaaa-cccc-aaaa-ccccaaaacccc",
"action": "run-pentest"
}
]
}
],
"page_info": {
"page_num": 1,
"page_size": 25
}
}
TriggerScheduledActionInput
Description
Input type for Mutation.trigger_scheduled_action.
mutation TriggerScheduledActionExample(
$input: TriggerScheduledActionInput = {
schedule_name: "Weekly Infrastructure Scan"
action: "run-pentest"
}
) {
trigger_scheduled_action(input: $input) {
scheduled_action {
uuid
schedule_name
action
last_triggered_at
total_triggers
}
}
}
Examples may not include all available fields for a type.
UpdateScheduledActionInput
Description
Input type for Mutation.update_scheduled_action
Fields
uuid - String!
cron_expression - String
A cron expression that defines when the action is executed.
A cron expression is a string consisting of 5 fields separated by spaces. The 5 fields represent the following:
- minute (0–59) - this field must always be set to '*' or '0'.
- hour (0–23) - note this is in UTC time.
- day of the month (1–31)
- month (1–12)
- day of the week (0–6) (Sunday to Saturday)
Notes:
- ScheduledActions only support hourly resolution. The minutes field must always be set to '*' or '0'.
- The cron expression is configured in UTC time. If you want to run the action at a specific time in another timezone, you will need to convert that time to UTC.
op_template_uuid - String
run-pentest action. This is the OpTemplate that will be used to run the pentest when the ScheduledAction is triggered. mutation UpdateScheduledActionExample(
$input: UpdateScheduledActionInput = {
uuid: "5678abcd-5678-abcd-5678-abcd5678abcd"
cron_expression: "0 3 * * *"
op_template_uuid: "9999aaaa-9999-aaaa-9999-aaaa9999aaaa"
}
) {
update_scheduled_action(input: $input) {
scheduled_action {
uuid
cron_expression
cron_description
}
}
}
Examples may not include all available fields for a type.
Setup: Asset Groups
Organize external attack surface assets (domains and IP ranges) into logical groups for targeted pentesting. Asset groups enable you to define and manage different segments of your external infrastructure for focused security assessments.
asset_groups_page
Description
Paginated list of asset groups in this account.
The AssetGroup.uuid field can be used to fetch more details about a specific AssetGroup using Query.asset_group.
Response
Returns an AssetGroupsPage!
Arguments
page_input - PageInput
query AssetGroupsPage($page_input: PageInput) {
asset_groups_page(page_input: $page_input) {
asset_groups {
...AssetGroupPageFragment
}
}
}
fragment AssetGroupPageFragment on AssetGroup {
uuid
name
op_template_uuid
user_account_name
client_account_company_name
last_ead_etl_completed_at
created_at
updated_at
op_series_uuid
op_series_status
assets_count
authorized_assets_count
external_domain_xops_count
in_scope_host_tab_xops_count
}
Examples may not include all available fields for a type.
{
"data": {
"asset_groups_page": {
"asset_groups": [
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"name": "Production External Assets",
"op_template_uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"user_account_name": "jane.doe@acme.com",
"client_account_company_name": "Acme Corp",
"last_ead_etl_completed_at": "2024-01-14T22:30:00Z",
"created_at": "2024-01-10T15:00:00Z",
"updated_at": "2024-01-14T22:30:00Z",
"op_series_uuid": "cccc3333-cccc-3333-cccc-3333cccc3333",
"op_series_status": "Done",
"assets_count": 42,
"authorized_assets_count": 38,
"external_domain_xops_count": 25,
"in_scope_host_tab_xops_count": 17
},
{
"uuid": "5678efgh-5678-efgh-5678-efgh5678efgh",
"name": "Staging Environment",
"op_template_uuid": "efgh5678-efgh-5678-efgh-5678efgh5678",
"user_account_name": "john.smith@acme.com",
"client_account_company_name": "Acme Corp",
"last_ead_etl_completed_at": "2024-01-13T18:00:00Z",
"created_at": "2024-01-05T12:00:00Z",
"updated_at": "2024-01-13T18:00:00Z",
"op_series_uuid": "dddd4444-dddd-4444-dddd-4444dddd4444",
"op_series_status": "Done",
"assets_count": 18,
"authorized_assets_count": 15,
"external_domain_xops_count": 10,
"in_scope_host_tab_xops_count": 8
}
]
}
}
}
python h3_gql.py ./asset_groups_page.graphql '{
"page_input": {
"page_size": 10
}
}'
Save the example request as ./asset_groups_page.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./asset_groups_page.graphql '{
"page_input": {
"page_size": 10
}
}'
Save the example request as ./asset_groups_page.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./asset_groups_page.graphql '{
"page_input": {
"page_size": 10
}
}'
Save the example request as ./asset_groups_page.graphql.
See h3-cli Examples for installation and usage.
asset_groups_count
Description
The total number of asset groups in this account.
Response
Returns an Int!
Arguments
page_input - PageInput
query AssetGroupsCount($page_input: PageInput) {
asset_groups_count(page_input: $page_input)
}
Examples may not include all available fields for a type.
{
"data": {
"asset_groups_count": 5
}
}
python h3_gql.py ./asset_groups_count.graphql '{
"page_input": null
}'
Save the example request as ./asset_groups_count.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./asset_groups_count.graphql '{
"page_input": null
}'
Save the example request as ./asset_groups_count.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./asset_groups_count.graphql '{
"page_input": null
}'
Save the example request as ./asset_groups_count.graphql.
See h3-cli Examples for installation and usage.
asset_group
Description
Fetch a specific asset group by its unique identifier.
Response
Returns an AssetGroup
Arguments
uuid - String!
query AssetGroup($uuid: String!) {
asset_group(uuid: $uuid) {
...AssetGroupFragment
}
}
fragment AssetGroupFragment on AssetGroup {
uuid
name
op_template_uuid
user_account_uuid
user_account_name
client_account_uuid
client_account_company_name
last_ead_etl_completed_at
created_at
updated_at
op_series_uuid
op_series_status
assets_count
authorized_assets_count
external_domain_xops_count
authorized_external_domain_xops_count
in_scope_host_tab_xops_count
authorized_host_tab_xops_count
}
Examples may not include all available fields for a type.
{
"data": {
"asset_group": {
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"name": "Production External Assets",
"op_template_uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"user_account_uuid": "aaaa1111-aaaa-1111-aaaa-1111aaaa1111",
"user_account_name": "jane.doe@acme.com",
"client_account_uuid": "bbbb2222-bbbb-2222-bbbb-2222bbbb2222",
"client_account_company_name": "Acme Corp",
"last_ead_etl_completed_at": "2024-01-14T22:30:00Z",
"created_at": "2024-01-10T15:00:00Z",
"updated_at": "2024-01-14T22:30:00Z",
"op_series_uuid": "cccc3333-cccc-3333-cccc-3333cccc3333",
"op_series_status": "Done",
"assets_count": 42,
"authorized_assets_count": 38,
"external_domain_xops_count": 25,
"authorized_external_domain_xops_count": 20,
"in_scope_host_tab_xops_count": 17,
"authorized_host_tab_xops_count": 15
}
}
}
python h3_gql.py ./asset_group.graphql '{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./asset_group.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./asset_group.graphql '{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./asset_group.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./asset_group.graphql '{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./asset_group.graphql.
See h3-cli Examples for installation and usage.
create_asset_group
Description
Create a new asset group.
The asset group's scan scope is defined by the provided ScheduleOpFormInput. Set the asset group name via schedule_op_form.op_name.
Response
Returns an AssetGroupOutput!
Arguments
schedule_op_form - ScheduleOpFormInput!
mutation CreateAssetGroup(
$schedule_op_form: ScheduleOpFormInput!
) {
create_asset_group(schedule_op_form: $schedule_op_form) {
asset_group {
uuid
name
op_template_uuid
op_series_uuid
op_series_status
created_at
assets_count
external_domain_xops_count
in_scope_host_tab_xops_count
}
}
}
Examples may not include all available fields for a type.
{
"data": {
"create_asset_group": {
"asset_group": {
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"name": "Production External Assets",
"op_template_uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"op_series_uuid": "cccc3333-cccc-3333-cccc-3333cccc3333",
"op_series_status": "Created",
"created_at": "2024-01-15T10:00:00Z",
"assets_count": 0,
"external_domain_xops_count": 0,
"in_scope_host_tab_xops_count": 0
}
}
}
}
python h3_gql.py ./create_asset_group.graphql '{
"schedule_op_form": {
"op_name": "Production External Assets",
"osint_domains": [
"acme.com",
"acme.io"
]
}
}'
Save the example request as ./create_asset_group.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./create_asset_group.graphql '{
"schedule_op_form": {
"op_name": "Production External Assets",
"osint_domains": [
"acme.com",
"acme.io"
]
}
}'
Save the example request as ./create_asset_group.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./create_asset_group.graphql '{
"schedule_op_form": {
"op_name": "Production External Assets",
"osint_domains": [
"acme.com",
"acme.io"
]
}
}'
Save the example request as ./create_asset_group.graphql.
See h3-cli Examples for installation and usage.
update_asset_group_template
Description
Update an asset group's scan scope configuration.
The asset group name can be updated via schedule_op_form.op_name.
Response
Returns a SaveOpTemplateOutput!
Arguments
asset_group_uuid - String!
schedule_op_form - ScheduleOpFormInput!
mutation UpdateAssetGroupTemplate(
$asset_group_uuid: String!
$schedule_op_form: ScheduleOpFormInput!
) {
update_asset_group_template(
asset_group_uuid: $asset_group_uuid
schedule_op_form: $schedule_op_form
) {
op_template {
uuid
op_template_name
op_type
schedule_op_form {
op_name
osint_domains
}
}
asset_group {
uuid
name
op_series_uuid
}
}
}
Examples may not include all available fields for a type.
{
"data": {
"update_asset_group_template": {
"op_template": {
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"op_template_name": "Updated External Assets",
"op_type": "ExternalAssetDiscovery",
"schedule_op_form": {
"op_name": "Updated External Assets",
"osint_domains": ["acme.com", "acme.io", "acme.net"]
}
},
"asset_group": {
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"name": "Updated External Assets",
"op_series_uuid": "cccc3333-cccc-3333-cccc-3333cccc3333"
}
}
}
}
python h3_gql.py ./update_asset_group_template.graphql '{
"asset_group_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"schedule_op_form": {
"op_name": "Updated External Assets",
"osint_domains": [
"acme.com",
"acme.io",
"acme.net"
]
}
}'
Save the example request as ./update_asset_group_template.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./update_asset_group_template.graphql '{
"asset_group_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"schedule_op_form": {
"op_name": "Updated External Assets",
"osint_domains": [
"acme.com",
"acme.io",
"acme.net"
]
}
}'
Save the example request as ./update_asset_group_template.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./update_asset_group_template.graphql '{
"asset_group_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"schedule_op_form": {
"op_name": "Updated External Assets",
"osint_domains": [
"acme.com",
"acme.io",
"acme.net"
]
}
}'
Save the example request as ./update_asset_group_template.graphql.
See h3-cli Examples for installation and usage.
AssetGroup
Description
An asset group represents a collection of discovered assets (domains and IPs) in your environment.
Assets are discovered by running External Asset Discovery scans using the scope defined in the asset group's associated OpTemplate. Once discovered, assets can be authorized for pentesting and used as the scope for External Attack operations.
Use Mutation.create_asset_group to create a new asset group.
Fields
uuid - String!
name - String!
op_template_uuid - String!
OpTemplate that defines this asset group's scan scope. op_template - OpTemplate!
OpTemplate that defines this asset group's scan scope and configuration. user_account_uuid - String!
user_account_name - String!
client_account_uuid - String!
client_account_company_name - String!
last_ead_etl_completed_at - Datetime
created_at - Datetime!
updated_at - Datetime
op_series_uuid - String!
assets_count - Int!
authorized_assets_count - Int!
external_domain_xops_count - Int!
external_domain_xops_page - ExternalDomainXopsPage!
Arguments
page_input - PageInput
authorized_external_domain_xops_count - Int!
in_scope_host_tab_xops_count - Int!
in_scope_host_tab_xops_page - HostTabXopsPage!
Arguments
page_input - PageInput
authorized_host_tab_xops_count - Int!
fragment AssetGroupFragment on AssetGroup {
uuid
name
op_template_uuid
user_account_uuid
user_account_name
client_account_uuid
client_account_company_name
last_ead_etl_completed_at
created_at
updated_at
op_series_uuid
op_series_status
assets_count
authorized_assets_count
external_domain_xops_count
authorized_external_domain_xops_count
in_scope_host_tab_xops_count
authorized_host_tab_xops_count
}
Examples may not include all available fields for a type.
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"name": "Production External Assets",
"op_template_uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"user_account_uuid": "aaaa1111-aaaa-1111-aaaa-1111aaaa1111",
"user_account_name": "jane.doe@acme.com",
"client_account_uuid": "bbbb2222-bbbb-2222-bbbb-2222bbbb2222",
"client_account_company_name": "Acme Corp",
"last_ead_etl_completed_at": "2024-01-14T22:30:00Z",
"created_at": "2024-01-10T15:00:00Z",
"updated_at": "2024-01-14T22:30:00Z",
"op_series_uuid": "cccc3333-cccc-3333-cccc-3333cccc3333",
"op_series_status": "Done",
"assets_count": 42,
"authorized_assets_count": 38,
"external_domain_xops_count": 25,
"authorized_external_domain_xops_count": 20,
"in_scope_host_tab_xops_count": 17,
"authorized_host_tab_xops_count": 15
}
AssetGroupOutput
Description
Output type returned by asset group mutations.
Fields
asset_group - AssetGroup!
AssetGroup. fragment AssetGroupOutputFragment on AssetGroupOutput {
asset_group {
uuid
name
op_template_uuid
op_series_uuid
op_series_status
created_at
updated_at
assets_count
authorized_assets_count
external_domain_xops_count
in_scope_host_tab_xops_count
}
}
Examples may not include all available fields for a type.
{
"asset_group": {
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"name": "Production External Assets",
"op_template_uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"op_series_uuid": "cccc3333-cccc-3333-cccc-3333cccc3333",
"op_series_status": "Done",
"created_at": "2024-01-10T15:00:00Z",
"updated_at": "2024-01-14T22:30:00Z",
"assets_count": 42,
"authorized_assets_count": 38,
"external_domain_xops_count": 25,
"in_scope_host_tab_xops_count": 17
}
}
AssetGroupsPage
Description
Contains a paginated list of AssetGroup records.
Fields
page_info - PageInfo
asset_groups - [AssetGroup!]!
asset groups. fragment AssetGroupsPageFragment on AssetGroupsPage {
page_info {
page_num
page_size
}
asset_groups {
uuid
name
op_template_uuid
user_account_name
last_ead_etl_completed_at
created_at
updated_at
op_series_uuid
op_series_status
assets_count
authorized_assets_count
external_domain_xops_count
in_scope_host_tab_xops_count
}
}
Examples may not include all available fields for a type.
{
"page_info": {
"page_num": 1,
"page_size": 10
},
"asset_groups": [
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"name": "Production External Assets",
"op_template_uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"user_account_name": "jane.doe@acme.com",
"last_ead_etl_completed_at": "2024-01-14T22:30:00Z",
"created_at": "2024-01-10T15:00:00Z",
"updated_at": "2024-01-14T22:30:00Z",
"op_series_uuid": "cccc3333-cccc-3333-cccc-3333cccc3333",
"op_series_status": "Done",
"assets_count": 42,
"authorized_assets_count": 38,
"external_domain_xops_count": 25,
"in_scope_host_tab_xops_count": 17
},
{
"uuid": "5678efgh-5678-efgh-5678-efgh5678efgh",
"name": "Staging Environment",
"op_template_uuid": "efgh5678-efgh-5678-efgh-5678efgh5678",
"user_account_name": "john.smith@acme.com",
"last_ead_etl_completed_at": "2024-01-13T18:00:00Z",
"created_at": "2024-01-05T12:00:00Z",
"updated_at": "2024-01-13T18:00:00Z",
"op_series_uuid": "dddd4444-dddd-4444-dddd-4444dddd4444",
"op_series_status": "Done",
"assets_count": 18,
"authorized_assets_count": 15,
"external_domain_xops_count": 10,
"in_scope_host_tab_xops_count": 8
}
]
}
Setup: Asset Groups: Domains
Manage domains within asset groups for external pentesting. Query discovered domains, view their testing history across operations, and add or remove domains from asset groups to control your external attack surface scope.
external_domain_xops_page
Description
Returns a paginated list of ExternalDomainXop records (domains) in the given AssetGroup.op_series_uuid. Supports filtering, sorting, and pagination via page_input.
Response
Returns an ExternalDomainXopsPage!
query ExternalDomainXopsPage(
$op_series_uuid: String!
$page_input: PageInput
) {
external_domain_xops_page(
op_series_uuid: $op_series_uuid
page_input: $page_input
) {
external_domain_xops {
...ExternalDomainXopPageFragment
}
}
}
fragment ExternalDomainXopPageFragment on ExternalDomainXop {
uuid
op_series_uuid
xop_id
last_op_id
current_op_id
is_authorized
is_dynamic_ip
third_party_aliases
pentestable_rules {
is_allowed
}
}
Examples may not include all available fields for a type.
{
"data": {
"external_domain_xops_page": {
"external_domain_xops": [
{
"uuid": "cccc3333-cccc-3333-cccc-3333cccc3333/app.acme.com",
"op_series_uuid": "cccc3333-cccc-3333-cccc-3333cccc3333",
"xop_id": "app.acme.com",
"last_op_id": "aaaa1111-aaaa-1111-aaaa-1111aaaa1111",
"current_op_id": "aaaa1111-aaaa-1111-aaaa-1111aaaa1111",
"is_authorized": true,
"is_dynamic_ip": false,
"third_party_aliases": [],
"pentestable_rules": {
"is_allowed": true
}
},
{
"uuid": "cccc3333-cccc-3333-cccc-3333cccc3333/api.acme.com",
"op_series_uuid": "cccc3333-cccc-3333-cccc-3333cccc3333",
"xop_id": "api.acme.com",
"last_op_id": "aaaa1111-aaaa-1111-aaaa-1111aaaa1111",
"current_op_id": "aaaa1111-aaaa-1111-aaaa-1111aaaa1111",
"is_authorized": false,
"is_dynamic_ip": false,
"third_party_aliases": ["cdn.cloudfront.net"],
"pentestable_rules": {
"is_allowed": false
}
}
]
}
}
}
python h3_gql.py ./external_domain_xops_page.graphql '{
"op_series_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"page_input": {
"page_size": 10
}
}'
Save the example request as ./external_domain_xops_page.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./external_domain_xops_page.graphql '{
"op_series_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"page_input": {
"page_size": 10
}
}'
Save the example request as ./external_domain_xops_page.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./external_domain_xops_page.graphql '{
"op_series_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"page_input": {
"page_size": 10
}
}'
Save the example request as ./external_domain_xops_page.graphql.
See h3-cli Examples for installation and usage.
external_domain_xops_count
Description
Returns the total number of ExternalDomainXop records (domains) in the given AssetGroup.op_series_uuid. Supports filtering via page_input.
Response
Returns an Int!
query ExternalDomainXopsCount(
$op_series_uuid: String!
$page_input: PageInput
) {
external_domain_xops_count(
op_series_uuid: $op_series_uuid
page_input: $page_input
)
}
Examples may not include all available fields for a type.
{
"data": {
"external_domain_xops_count": 25
}
}
python h3_gql.py ./external_domain_xops_count.graphql '{
"op_series_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"page_input": null
}'
Save the example request as ./external_domain_xops_count.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./external_domain_xops_count.graphql '{
"op_series_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"page_input": null
}'
Save the example request as ./external_domain_xops_count.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./external_domain_xops_count.graphql '{
"op_series_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"page_input": null
}'
Save the example request as ./external_domain_xops_count.graphql.
See h3-cli Examples for installation and usage.
external_domain_xop
Description
Returns the ExternalDomainXop with the given uuid. The UUID is in the format {op_series_uuid}/{domain_name}.
Response
Returns an ExternalDomainXop
Arguments
uuid - String!
query ExternalDomainXop($uuid: String!) {
external_domain_xop(uuid: $uuid) {
...ExternalDomainXopFragment
}
}
fragment ExternalDomainXopFragment on ExternalDomainXop {
uuid
op_series_uuid
xop_id
last_op_id
current_op_id
is_authorized
is_dynamic_ip
third_party_aliases
third_party_certificate_subject_cns
pentestable_rules {
is_allowed
action_tooltip
authz_warning
}
excluded_domain_from_last_pentest {
op_id
domain
reason
}
}
Examples may not include all available fields for a type.
{
"data": {
"external_domain_xop": {
"uuid": "cccc3333-cccc-3333-cccc-3333cccc3333/app.acme.com",
"op_series_uuid": "cccc3333-cccc-3333-cccc-3333cccc3333",
"xop_id": "app.acme.com",
"last_op_id": "aaaa1111-aaaa-1111-aaaa-1111aaaa1111",
"current_op_id": "aaaa1111-aaaa-1111-aaaa-1111aaaa1111",
"is_authorized": true,
"is_dynamic_ip": false,
"third_party_aliases": ["cdn.cloudfront.net"],
"third_party_certificate_subject_cns": ["*.cloudfront.net"],
"pentestable_rules": {
"is_allowed": true,
"action_tooltip": null,
"authz_warning": null
},
"excluded_domain_from_last_pentest": null
}
}
}
python h3_gql.py ./external_domain_xop.graphql '{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./external_domain_xop.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./external_domain_xop.graphql '{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./external_domain_xop.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./external_domain_xop.graphql '{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./external_domain_xop.graphql.
See h3-cli Examples for installation and usage.
add_domains_to_asset_group
Description
Adds one or more domains to the given AssetGroup's configured scope. The new domains are merged into the AssetGroup's existing domain list. Duplicate domains are automatically deduplicated. Returns the updated AssetGroup.
Response
Returns an AssetGroupOutput!
Arguments
asset_group_uuid - String!
domains - [StringNotEmpty]!
["example.com", "sub.example.com"]). mutation AddDomainsToAssetGroup(
$asset_group_uuid: String!
$domains: [StringNotEmpty]!
) {
add_domains_to_asset_group(
asset_group_uuid: $asset_group_uuid
domains: $domains
) {
asset_group {
uuid
name
op_series_uuid
assets_count
external_domain_xops_count
authorized_external_domain_xops_count
}
}
}
Examples may not include all available fields for a type.
{
"data": {
"add_domains_to_asset_group": {
"asset_group": {
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"name": "Production External Assets",
"op_series_uuid": "cccc3333-cccc-3333-cccc-3333cccc3333",
"assets_count": 44,
"external_domain_xops_count": 27,
"authorized_external_domain_xops_count": 20
}
}
}
}
python h3_gql.py ./add_domains_to_asset_group.graphql '{
"asset_group_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"domains": [
"newdomain.acme.com",
"extra.acme.io"
]
}'
Save the example request as ./add_domains_to_asset_group.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./add_domains_to_asset_group.graphql '{
"asset_group_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"domains": [
"newdomain.acme.com",
"extra.acme.io"
]
}'
Save the example request as ./add_domains_to_asset_group.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./add_domains_to_asset_group.graphql '{
"asset_group_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"domains": [
"newdomain.acme.com",
"extra.acme.io"
]
}'
Save the example request as ./add_domains_to_asset_group.graphql.
See h3-cli Examples for installation and usage.
remove_domains_from_asset_group
Description
Removes one or more domains from the given AssetGroup's configured scope. Returns the updated AssetGroup.
Response
Returns an AssetGroupOutput!
Arguments
asset_group_uuid - String!
domains - [StringNotEmpty]!
mutation RemoveDomainsFromAssetGroup(
$asset_group_uuid: String!
$domains: [StringNotEmpty]!
) {
remove_domains_from_asset_group(
asset_group_uuid: $asset_group_uuid
domains: $domains
) {
asset_group {
uuid
name
op_series_uuid
assets_count
external_domain_xops_count
authorized_external_domain_xops_count
}
}
}
Examples may not include all available fields for a type.
{
"data": {
"remove_domains_from_asset_group": {
"asset_group": {
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"name": "Production External Assets",
"op_series_uuid": "cccc3333-cccc-3333-cccc-3333cccc3333",
"assets_count": 41,
"external_domain_xops_count": 24,
"authorized_external_domain_xops_count": 19
}
}
}
}
python h3_gql.py ./remove_domains_from_asset_group.graphql '{
"asset_group_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"domains": [
"oldsite.acme.com"
]
}'
Save the example request as ./remove_domains_from_asset_group.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./remove_domains_from_asset_group.graphql '{
"asset_group_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"domains": [
"oldsite.acme.com"
]
}'
Save the example request as ./remove_domains_from_asset_group.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./remove_domains_from_asset_group.graphql '{
"asset_group_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"domains": [
"oldsite.acme.com"
]
}'
Save the example request as ./remove_domains_from_asset_group.graphql.
See h3-cli Examples for installation and usage.
external_domain_xops_csv_presigned_url
Description
Returns a temporary presigned URL for downloading a CSV export of all ExternalDomainXop records (domains) in the given AssetGroup.op_series_uuid.
The CSV format is documented under ExternalDomainXopCSV.
Response
Returns a String
Arguments
op_series_uuid - String!
query ExternalDomainXopsCsvPresignedUrl(
$op_series_uuid: String!
) {
external_domain_xops_csv_presigned_url(
op_series_uuid: $op_series_uuid
)
}
Examples may not include all available fields for a type.
{
"data": {
"external_domain_xops_csv_presigned_url": "https://s3.amazonaws.com/h3-exports/external-domains/1234abcd-1234-abcd-1234-abcd1234abcd.csv?X-Amz-Algorithm=AWS4-HMAC-SHA256&..."
}
}
python h3_gql.py ./external_domain_xops_csv_presigned_url.graphql '{
"op_series_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./external_domain_xops_csv_presigned_url.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./external_domain_xops_csv_presigned_url.graphql '{
"op_series_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./external_domain_xops_csv_presigned_url.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./external_domain_xops_csv_presigned_url.graphql '{
"op_series_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./external_domain_xops_csv_presigned_url.graphql.
See h3-cli Examples for installation and usage.
ExternalDomainXop
Description
An ExternalDomainXop represents a unique external domain name tracked across a series of Ops within an AssetGroup. Each ExternalDomainXop is uniquely identified by its xop_id, which is the domain name itself (e.g., example.com).
As new pentests run within the same AssetGroup, the ExternalDomainXop record is updated with data from the most recent Op while retaining historical tracking information such as the first and last time the domain appeared.
Fields
uuid - String!
{op_series_uuid}/{xop_id}. op_series_uuid - String!
xop_id - String!
xop_id is the domain name (e.g., example.com). last_external_domain - ExternalDomain!
last_external_domains - [ExternalDomain]!
is_authorized - Boolean
pentestable_rules - PentestableRules
is_dynamic_ip - Boolean
true, the platform accounts for the fact that the domain's resolved IP may change between pentests. excluded_domain_from_last_pentest - ExcludedDomain
third_party_aliases - [String]
third_party_certificate_subject_cns - [String]
fragment ExternalDomainXopFragment on ExternalDomainXop {
uuid
op_series_uuid
xop_id
last_op_id
current_op_id
is_authorized
is_dynamic_ip
third_party_aliases
third_party_certificate_subject_cns
pentestable_rules {
is_allowed
action_tooltip
authz_warning
authz_warning_label
}
excluded_domain_from_last_pentest {
op_id
domain
reason
}
}
Examples may not include all available fields for a type.
{
"uuid": "cccc3333-cccc-3333-cccc-3333cccc3333/app.acme.com",
"op_series_uuid": "cccc3333-cccc-3333-cccc-3333cccc3333",
"xop_id": "app.acme.com",
"last_op_id": "aaaa1111-aaaa-1111-aaaa-1111aaaa1111",
"current_op_id": "aaaa1111-aaaa-1111-aaaa-1111aaaa1111",
"is_authorized": true,
"is_dynamic_ip": false,
"third_party_aliases": ["cdn.cloudfront.net"],
"third_party_certificate_subject_cns": ["*.cloudfront.net"],
"pentestable_rules": {
"is_allowed": true,
"action_tooltip": null,
"authz_warning": null,
"authz_warning_label": null
},
"excluded_domain_from_last_pentest": null
}
ExcludedDomain
Description
Represents an external domain that was authorized for pentesting but was excluded from the pentest at runtime. Domains are typically excluded due to DNS drift (the domain's IP changed), unreachability, or the domain no longer resolving. See ExcludedReason for the possible reasons.
fragment ExcludedDomainFragment on ExcludedDomain {
op_id
domain
reason
}
Examples may not include all available fields for a type.
{
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"domain": "legacy.acme.com",
"reason": "Unreachable"
}
ExternalDomainXopsPage
Description
Contains a paginated list of ExternalDomainXop records (domains tracked across pentests).
Fields
page_info - PageInfo
external_domain_xops - [ExternalDomainXop!]!
fragment ExternalDomainXopsPageFragment on ExternalDomainXopsPage {
page_info {
page_num
page_size
}
external_domain_xops {
uuid
op_series_uuid
xop_id
last_op_id
current_op_id
is_authorized
is_dynamic_ip
third_party_aliases
pentestable_rules {
is_allowed
}
}
}
Examples may not include all available fields for a type.
{
"page_info": {
"page_num": 1,
"page_size": 10
},
"external_domain_xops": [
{
"uuid": "cccc3333-cccc-3333-cccc-3333cccc3333/app.acme.com",
"op_series_uuid": "cccc3333-cccc-3333-cccc-3333cccc3333",
"xop_id": "app.acme.com",
"last_op_id": "aaaa1111-aaaa-1111-aaaa-1111aaaa1111",
"current_op_id": "aaaa1111-aaaa-1111-aaaa-1111aaaa1111",
"is_authorized": true,
"is_dynamic_ip": false,
"third_party_aliases": [],
"pentestable_rules": {
"is_allowed": true
}
},
{
"uuid": "cccc3333-cccc-3333-cccc-3333cccc3333/api.acme.com",
"op_series_uuid": "cccc3333-cccc-3333-cccc-3333cccc3333",
"xop_id": "api.acme.com",
"last_op_id": "aaaa1111-aaaa-1111-aaaa-1111aaaa1111",
"current_op_id": "aaaa1111-aaaa-1111-aaaa-1111aaaa1111",
"is_authorized": false,
"is_dynamic_ip": false,
"third_party_aliases": ["cdn.cloudfront.net"],
"pentestable_rules": {
"is_allowed": false
}
}
]
}
Setup: Asset Groups: IPs
Manage IP addresses and ranges within asset groups for external pentesting. Query discovered IPs, view their testing history across operations, and add or remove IPs from asset groups to control your external attack surface scope.
host_tab_xops_page
Description
Returns a paginated list of HostTabXop records (IPs) in the given AssetGroup.op_series_uuid. This includes all discovered IPs, whether or not they fall within the configured scope. For only in-scope IPs, use in_scope_host_tab_xops_page. Supports filtering, sorting, and pagination via page_input.
Response
Returns a HostTabXopsPage!
query HostTabXopsPage($op_series_uuid: String!, $page_input: PageInput) {
host_tab_xops_page(op_series_uuid: $op_series_uuid, page_input: $page_input) {
host_tab_xops {
...HostTabXopPageFragment
}
}
}
fragment HostTabXopPageFragment on HostTabXop {
uuid
op_series_uuid
xop_id
ip
last_op_id
current_op_id
is_authorized
third_party_aliases
third_party_certificate_subject_cns
pentestable_rules {
is_allowed
action_tooltip
authz_warning
}
}
Examples may not include all available fields for a type.
{
"data": {
"host_tab_xops_page": {
"host_tab_xops": [
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd/203.0.113.10",
"op_series_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"xop_id": "203.0.113.10",
"ip": "203.0.113.10",
"last_op_id": "abcd1234-abcd-1234-abcd-1234abcd1234",
"current_op_id": "abcd1234-abcd-1234-abcd-1234abcd1234",
"is_authorized": true,
"third_party_aliases": [],
"third_party_certificate_subject_cns": [],
"pentestable_rules": {
"is_allowed": true,
"action_tooltip": null,
"authz_warning": null
}
},
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd/198.51.100.5",
"op_series_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"xop_id": "198.51.100.5",
"ip": "198.51.100.5",
"last_op_id": "abcd1234-abcd-1234-abcd-1234abcd1234",
"current_op_id": "abcd1234-abcd-1234-abcd-1234abcd1234",
"is_authorized": false,
"third_party_aliases": ["cdn.provider.com"],
"third_party_certificate_subject_cns": ["*.provider.com"],
"pentestable_rules": {
"is_allowed": false,
"action_tooltip": "This IP is hosted by a provider that does not permit pentesting.",
"authz_warning": null
}
}
]
}
}
}
python h3_gql.py ./host_tab_xops_page.graphql '{
"op_series_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"page_input": {
"page_size": 10
}
}'
Save the example request as ./host_tab_xops_page.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./host_tab_xops_page.graphql '{
"op_series_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"page_input": {
"page_size": 10
}
}'
Save the example request as ./host_tab_xops_page.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./host_tab_xops_page.graphql '{
"op_series_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"page_input": {
"page_size": 10
}
}'
Save the example request as ./host_tab_xops_page.graphql.
See h3-cli Examples for installation and usage.
host_tab_xops_count
Description
Returns the total number of HostTabXop records (IPs) in the given AssetGroup.op_series_uuid. This includes all discovered IPs, whether or not they fall within the configured scope. Supports filtering via page_input.
Response
Returns an Int!
query HostTabXopsCount($op_series_uuid: String!, $page_input: PageInput) {
host_tab_xops_count(op_series_uuid: $op_series_uuid, page_input: $page_input)
}
Examples may not include all available fields for a type.
{
"data": {
"host_tab_xops_count": 42
}
}
python h3_gql.py ./host_tab_xops_count.graphql '{
"op_series_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"page_input": null
}'
Save the example request as ./host_tab_xops_count.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./host_tab_xops_count.graphql '{
"op_series_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"page_input": null
}'
Save the example request as ./host_tab_xops_count.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./host_tab_xops_count.graphql '{
"op_series_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"page_input": null
}'
Save the example request as ./host_tab_xops_count.graphql.
See h3-cli Examples for installation and usage.
host_tab_xop
Description
Returns the HostTabXop with the given uuid. The UUID is in the format {op_series_uuid}/{ip_address}.
Response
Returns a HostTabXop
Arguments
uuid - String!
query HostTabXop($uuid: String!) {
host_tab_xop(uuid: $uuid) {
...HostTabXopFragment
}
}
fragment HostTabXopFragment on HostTabXop {
uuid
op_series_uuid
xop_id
ip
last_op_id
current_op_id
is_authorized
third_party_aliases
third_party_certificate_subject_cns
pentestable_rules {
is_allowed
action_tooltip
authz_warning
}
}
Examples may not include all available fields for a type.
{
"data": {
"host_tab_xop": {
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_series_uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"xop_id": "198.51.100.10",
"ip": "198.51.100.10",
"last_op_id": "5678efab-5678-efab-5678-efab5678efab",
"current_op_id": "5678efab-5678-efab-5678-efab5678efab",
"is_authorized": true,
"third_party_aliases": ["cdn.example.net"],
"third_party_certificate_subject_cns": ["*.example.net"],
"pentestable_rules": {
"is_allowed": true,
"action_tooltip": null,
"authz_warning": null
}
}
}
}
python h3_gql.py ./host_tab_xop.graphql '{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./host_tab_xop.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./host_tab_xop.graphql '{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./host_tab_xop.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./host_tab_xop.graphql '{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./host_tab_xop.graphql.
See h3-cli Examples for installation and usage.
in_scope_host_tab_xops_page
Description
Returns a paginated list of HostTabXop records (unique IPs) that fall within the configured scope of the AssetGroup associated with the given op_series_uuid.
An External Asset Discovery may find many domains that resolve to IPs outside the AssetGroup's configured scope. Those out-of-scope IPs are excluded from this result set but are included in host_tab_xops_page.
Response
Returns a HostTabXopsPage!
query InScopeHostTabXopsPage($op_series_uuid: String!, $page_input: PageInput) {
in_scope_host_tab_xops_page(op_series_uuid: $op_series_uuid, page_input: $page_input) {
host_tab_xops {
...InScopeHostTabXopFragment
}
}
}
fragment InScopeHostTabXopFragment on HostTabXop {
uuid
op_series_uuid
xop_id
ip
last_op_id
current_op_id
is_authorized
third_party_aliases
third_party_certificate_subject_cns
excluded_ip_from_last_pentest {
op_id
ip
reason
}
}
Examples may not include all available fields for a type.
{
"data": {
"in_scope_host_tab_xops_page": {
"host_tab_xops": [
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd/203.0.113.10",
"op_series_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"xop_id": "203.0.113.10",
"ip": "203.0.113.10",
"last_op_id": "abcd1234-abcd-1234-abcd-1234abcd1234",
"current_op_id": "abcd1234-abcd-1234-abcd-1234abcd1234",
"is_authorized": true,
"third_party_aliases": [],
"third_party_certificate_subject_cns": [],
"excluded_ip_from_last_pentest": null
},
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd/198.51.100.5",
"op_series_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"xop_id": "198.51.100.5",
"ip": "198.51.100.5",
"last_op_id": "abcd1234-abcd-1234-abcd-1234abcd1234",
"current_op_id": "abcd1234-abcd-1234-abcd-1234abcd1234",
"is_authorized": true,
"third_party_aliases": [],
"third_party_certificate_subject_cns": [],
"excluded_ip_from_last_pentest": {
"op_id": "abcd1234-abcd-1234-abcd-1234abcd1234",
"ip": "198.51.100.5",
"reason": "Unreachable"
}
}
]
}
}
}
python h3_gql.py ./in_scope_host_tab_xops_page.graphql '{
"op_series_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"page_input": {
"page_size": 10
}
}'
Save the example request as ./in_scope_host_tab_xops_page.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./in_scope_host_tab_xops_page.graphql '{
"op_series_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"page_input": {
"page_size": 10
}
}'
Save the example request as ./in_scope_host_tab_xops_page.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./in_scope_host_tab_xops_page.graphql '{
"op_series_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"page_input": {
"page_size": 10
}
}'
Save the example request as ./in_scope_host_tab_xops_page.graphql.
See h3-cli Examples for installation and usage.
in_scope_host_tab_xops_count
Description
Returns the total number of HostTabXop records (unique IPs) that fall within the configured scope of the AssetGroup associated with the given op_series_uuid.
An External Asset Discovery may find many domains that resolve to IPs outside the AssetGroup's configured scope. Those out-of-scope IPs are excluded from this count but are included in host_tab_xops_count.
Response
Returns an Int!
query InScopeHostTabXopsCount($op_series_uuid: String!, $page_input: PageInput) {
in_scope_host_tab_xops_count(op_series_uuid: $op_series_uuid, page_input: $page_input)
}
Examples may not include all available fields for a type.
{
"data": {
"in_scope_host_tab_xops_count": 38
}
}
python h3_gql.py ./in_scope_host_tab_xops_count.graphql '{
"op_series_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"page_input": null
}'
Save the example request as ./in_scope_host_tab_xops_count.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./in_scope_host_tab_xops_count.graphql '{
"op_series_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"page_input": null
}'
Save the example request as ./in_scope_host_tab_xops_count.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./in_scope_host_tab_xops_count.graphql '{
"op_series_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"page_input": null
}'
Save the example request as ./in_scope_host_tab_xops_count.graphql.
See h3-cli Examples for installation and usage.
in_scope_host_tab_xops_csv_presigned_url
Description
Returns a temporary presigned URL for downloading a CSV export of in-scope HostTabXop records (unique IPs) in the AssetGroup associated with the given op_series_uuid.
The CSV format is documented under HostXopCSV.
Response
Returns a String
Arguments
op_series_uuid - String!
query InScopeHostTabXopsCsvPresignedUrl($op_series_uuid: String!) {
in_scope_host_tab_xops_csv_presigned_url(op_series_uuid: $op_series_uuid)
}
Examples may not include all available fields for a type.
{
"data": {
"in_scope_host_tab_xops_csv_presigned_url": "https://s3.amazonaws.com/h3-exports/host-xops/1234abcd-1234-abcd-1234-abcd1234abcd.csv?X-Amz-Algorithm=AWS4-HMAC-SHA256&..."
}
}
python h3_gql.py ./in_scope_host_tab_xops_csv_presigned_url.graphql '{
"op_series_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./in_scope_host_tab_xops_csv_presigned_url.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./in_scope_host_tab_xops_csv_presigned_url.graphql '{
"op_series_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./in_scope_host_tab_xops_csv_presigned_url.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./in_scope_host_tab_xops_csv_presigned_url.graphql '{
"op_series_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./in_scope_host_tab_xops_csv_presigned_url.graphql.
See h3-cli Examples for installation and usage.
HostTabXop
Description
A HostTabXop represents a unique IP address tracked across a series of Ops within an AssetGroup. Each HostTabXop is uniquely identified by its xop_id, which is the IP address itself.
As new pentests run within the same AssetGroup, the HostTabXop record is updated with data from the most recent Op while retaining historical tracking information.
Fields
uuid - String!
{op_series_uuid}/{xop_id}. op_series_uuid - String!
xop_id - String!
xop_id is the IP address (e.g., 192.168.1.1). ip - String!
is_authorized - Boolean
excluded_ip_from_last_pentest - ExcludedIP
pentestable_rules - PentestableRules
third_party_aliases - [String]
third_party_certificate_subject_cns - [String]
fragment HostTabXopFragment on HostTabXop {
uuid
op_series_uuid
xop_id
ip
last_op_id
current_op_id
is_authorized
third_party_aliases
third_party_certificate_subject_cns
excluded_ip_from_last_pentest {
op_id
ip
reason
}
pentestable_rules {
is_allowed
action_tooltip
authz_warning
authz_warning_label
}
}
Examples may not include all available fields for a type.
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd/203.0.113.10",
"op_series_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"xop_id": "203.0.113.10",
"ip": "203.0.113.10",
"last_op_id": "abcd1234-abcd-1234-abcd-1234abcd1234",
"current_op_id": "abcd1234-abcd-1234-abcd-1234abcd1234",
"is_authorized": true,
"third_party_aliases": [],
"third_party_certificate_subject_cns": [],
"excluded_ip_from_last_pentest": null,
"pentestable_rules": {
"is_allowed": true,
"action_tooltip": null,
"authz_warning": null,
"authz_warning_label": null
}
}
ExcludedIP
Description
Represents an IP address that was authorized for pentesting but was excluded from the pentest at runtime. IPs are typically excluded due to drift (the IP is no longer associated with the domain) or unreachability. See ExcludedReason for the possible reasons.
fragment ExcludedIPFragment on ExcludedIP {
op_id
ip
reason
}
Examples may not include all available fields for a type.
{
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"ip": "203.0.113.10",
"reason": "Unreachable"
}
HostTabXopsPage
Description
Contains a paginated list of HostTabXop records (IP addresses tracked across pentests).
Fields
page_info - PageInfo
host_tab_xops - [HostTabXop!]!
fragment HostTabXopsPageFragment on HostTabXopsPage {
page_info {
page_num
page_size
}
host_tab_xops {
uuid
op_series_uuid
xop_id
ip
last_op_id
current_op_id
is_authorized
third_party_aliases
pentestable_rules {
is_allowed
action_tooltip
}
}
}
Examples may not include all available fields for a type.
{
"page_info": {
"page_num": 1,
"page_size": 10
},
"host_tab_xops": [
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd/203.0.113.10",
"op_series_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"xop_id": "203.0.113.10",
"ip": "203.0.113.10",
"last_op_id": "abcd1234-abcd-1234-abcd-1234abcd1234",
"current_op_id": "abcd1234-abcd-1234-abcd-1234abcd1234",
"is_authorized": true,
"third_party_aliases": [],
"pentestable_rules": {
"is_allowed": true,
"action_tooltip": null
}
},
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd/198.51.100.5",
"op_series_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"xop_id": "198.51.100.5",
"ip": "198.51.100.5",
"last_op_id": "abcd1234-abcd-1234-abcd-1234abcd1234",
"current_op_id": "abcd1234-abcd-1234-abcd-1234abcd1234",
"is_authorized": false,
"third_party_aliases": ["cdn.provider.com"],
"pentestable_rules": {
"is_allowed": false,
"action_tooltip": "This IP is hosted by a provider that does not permit pentesting."
}
}
]
}
Setup: Asset Groups: Authorization
Authorize or deauthorize domains and IP addresses for external pentesting.
authorize_domains
Description
Authorizes the specified ExternalDomainXop domains for External Attack pentesting. Each domain is evaluated against PentestableRules; domains that pass the rules are authorized, while domains owned by providers that do not permit pentesting are returned in the blocked_pentestable_entities list.
Response
Returns a PentestableEntitiesOutput!
Arguments
external_domain_xop_uuids - [String!]!
mutation AuthorizeDomains($external_domain_xop_uuids: [String!]!) {
authorize_domains(external_domain_xop_uuids: $external_domain_xop_uuids) {
pentestable_entities {
uuid
entity_type
is_authorized
}
blocked_pentestable_entities {
pentestable_entity {
uuid
entity_type
is_authorized
}
pentestable_rules {
is_allowed
action_tooltip
authz_warning
}
}
}
}
Examples may not include all available fields for a type.
{
"data": {
"authorize_domains": {
"pentestable_entities": [
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd/example.com",
"entity_type": "ExternalDomainXop",
"is_authorized": true
}
],
"blocked_pentestable_entities": [
{
"pentestable_entity": {
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd/api.example.com",
"entity_type": "ExternalDomainXop",
"is_authorized": false
},
"pentestable_rules": {
"is_allowed": false,
"action_tooltip": "This domain is hosted by a provider that does not permit pentesting.",
"authz_warning": null
}
}
]
}
}
}
python h3_gql.py ./authorize_domains.graphql '{
"external_domain_xop_uuids": [
"1234abcd-1234-abcd-1234-abcd1234abcd/example.com",
"1234abcd-1234-abcd-1234-abcd1234abcd/api.example.com"
]
}'
Save the example request as ./authorize_domains.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./authorize_domains.graphql '{
"external_domain_xop_uuids": [
"1234abcd-1234-abcd-1234-abcd1234abcd/example.com",
"1234abcd-1234-abcd-1234-abcd1234abcd/api.example.com"
]
}'
Save the example request as ./authorize_domains.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./authorize_domains.graphql '{
"external_domain_xop_uuids": [
"1234abcd-1234-abcd-1234-abcd1234abcd/example.com",
"1234abcd-1234-abcd-1234-abcd1234abcd/api.example.com"
]
}'
Save the example request as ./authorize_domains.graphql.
See h3-cli Examples for installation and usage.
deauthorize_domains
Description
Deauthorizes the specified ExternalDomainXop domains, removing them from the scope of future External Attack pentests. Deauthorization requests are always allowed (they are not subject to PentestableRules blocking).
Response
Returns a PentestableEntitiesOutput!
Arguments
external_domain_xop_uuids - [String!]!
mutation DeauthorizeDomains($external_domain_xop_uuids: [String!]!) {
deauthorize_domains(external_domain_xop_uuids: $external_domain_xop_uuids) {
pentestable_entities {
uuid
entity_type
is_authorized
}
blocked_pentestable_entities {
pentestable_entity {
uuid
entity_type
is_authorized
}
pentestable_rules {
is_allowed
action_tooltip
}
}
}
}
Examples may not include all available fields for a type.
{
"data": {
"deauthorize_domains": {
"pentestable_entities": [
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd/example.com",
"entity_type": "ExternalDomainXop",
"is_authorized": false
}
],
"blocked_pentestable_entities": []
}
}
}
python h3_gql.py ./deauthorize_domains.graphql '{
"external_domain_xop_uuids": [
"1234abcd-1234-abcd-1234-abcd1234abcd/example.com"
]
}'
Save the example request as ./deauthorize_domains.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./deauthorize_domains.graphql '{
"external_domain_xop_uuids": [
"1234abcd-1234-abcd-1234-abcd1234abcd/example.com"
]
}'
Save the example request as ./deauthorize_domains.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./deauthorize_domains.graphql '{
"external_domain_xop_uuids": [
"1234abcd-1234-abcd-1234-abcd1234abcd/example.com"
]
}'
Save the example request as ./deauthorize_domains.graphql.
See h3-cli Examples for installation and usage.
bulk_authorize_domains
Description
Bulk authorizes all eligible ExternalDomainXop domains in the given OpSeries for External Attack pentesting. Only domains whose PentestableRules evaluate to is_allowed = true will be authorized. Optionally filter to only domains within the configured scope or matching specific criteria.
Response
Returns a PentestableEntitiesBulkOutput!
Arguments
op_series_uuid - String!
configured_domains_only - Boolean
page_input - PageInput
mutation BulkAuthorizeDomains(
$op_series_uuid: String!,
$configured_domains_only: Boolean,
$page_input: PageInput
) {
bulk_authorize_domains(
op_series_uuid: $op_series_uuid,
configured_domains_only: $configured_domains_only,
page_input: $page_input
) {
pentestable_entities_count
}
}
Examples may not include all available fields for a type.
{
"data": {
"bulk_authorize_domains": {
"pentestable_entities_count": 15
}
}
}
python h3_gql.py ./bulk_authorize_domains.graphql '{
"op_series_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"configured_domains_only": true,
"page_input": null
}'
Save the example request as ./bulk_authorize_domains.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./bulk_authorize_domains.graphql '{
"op_series_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"configured_domains_only": true,
"page_input": null
}'
Save the example request as ./bulk_authorize_domains.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./bulk_authorize_domains.graphql '{
"op_series_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"configured_domains_only": true,
"page_input": null
}'
Save the example request as ./bulk_authorize_domains.graphql.
See h3-cli Examples for installation and usage.
bulk_deauthorize_domains
Description
Bulk deauthorizes all ExternalDomainXop domains in the given OpSeries, removing them from the scope of future External Attack pentests. Optionally use page_input filters to narrow which domains are deauthorized.
Response
Returns a PentestableEntitiesBulkOutput!
Arguments
op_series_uuid - String!
page_input - PageInput
mutation BulkDeauthorizeDomains(
$op_series_uuid: String!,
$page_input: PageInput
) {
bulk_deauthorize_domains(
op_series_uuid: $op_series_uuid,
page_input: $page_input
) {
pentestable_entities_count
}
}
Examples may not include all available fields for a type.
{
"data": {
"bulk_deauthorize_domains": {
"pentestable_entities_count": 15
}
}
}
python h3_gql.py ./bulk_deauthorize_domains.graphql '{
"op_series_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"page_input": null
}'
Save the example request as ./bulk_deauthorize_domains.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./bulk_deauthorize_domains.graphql '{
"op_series_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"page_input": null
}'
Save the example request as ./bulk_deauthorize_domains.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./bulk_deauthorize_domains.graphql '{
"op_series_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"page_input": null
}'
Save the example request as ./bulk_deauthorize_domains.graphql.
See h3-cli Examples for installation and usage.
authorize_ips
Description
Authorizes the specified HostTabXop IPs for External Attack pentesting. Each IP is evaluated against PentestableRules; IPs that pass the rules are authorized, while IPs owned by providers that do not permit pentesting are returned in the blocked_pentestable_entities list.
Response
Returns a PentestableEntitiesOutput!
Arguments
host_tab_xop_uuids - [String!]!
mutation AuthorizeIps($host_tab_xop_uuids: [String!]!) {
authorize_ips(host_tab_xop_uuids: $host_tab_xop_uuids) {
pentestable_entities {
uuid
entity_type
is_authorized
}
blocked_pentestable_entities {
pentestable_entity {
uuid
entity_type
is_authorized
}
pentestable_rules {
is_allowed
action_tooltip
authz_warning
}
}
}
}
Examples may not include all available fields for a type.
{
"data": {
"authorize_ips": {
"pentestable_entities": [
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd/203.0.113.10",
"entity_type": "HostTabXop",
"is_authorized": true
}
],
"blocked_pentestable_entities": [
{
"pentestable_entity": {
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd/198.51.100.5",
"entity_type": "HostTabXop",
"is_authorized": false
},
"pentestable_rules": {
"is_allowed": false,
"action_tooltip": "This IP is hosted by a provider that does not permit pentesting.",
"authz_warning": null
}
}
]
}
}
}
python h3_gql.py ./authorize_ips.graphql '{
"host_tab_xop_uuids": [
"1234abcd-1234-abcd-1234-abcd1234abcd/203.0.113.10",
"1234abcd-1234-abcd-1234-abcd1234abcd/198.51.100.5"
]
}'
Save the example request as ./authorize_ips.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./authorize_ips.graphql '{
"host_tab_xop_uuids": [
"1234abcd-1234-abcd-1234-abcd1234abcd/203.0.113.10",
"1234abcd-1234-abcd-1234-abcd1234abcd/198.51.100.5"
]
}'
Save the example request as ./authorize_ips.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./authorize_ips.graphql '{
"host_tab_xop_uuids": [
"1234abcd-1234-abcd-1234-abcd1234abcd/203.0.113.10",
"1234abcd-1234-abcd-1234-abcd1234abcd/198.51.100.5"
]
}'
Save the example request as ./authorize_ips.graphql.
See h3-cli Examples for installation and usage.
deauthorize_ips
Description
Deauthorizes the specified HostTabXop IPs, removing them from the scope of future External Attack pentests. Deauthorization requests are always allowed (they are not subject to PentestableRules blocking).
Response
Returns a PentestableEntitiesOutput!
Arguments
host_tab_xop_uuids - [String!]!
mutation DeauthorizeIps($host_tab_xop_uuids: [String!]!) {
deauthorize_ips(host_tab_xop_uuids: $host_tab_xop_uuids) {
pentestable_entities {
uuid
entity_type
is_authorized
}
blocked_pentestable_entities {
pentestable_entity {
uuid
entity_type
is_authorized
}
pentestable_rules {
is_allowed
action_tooltip
}
}
}
}
Examples may not include all available fields for a type.
{
"data": {
"deauthorize_ips": {
"pentestable_entities": [
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd/203.0.113.10",
"entity_type": "HostTabXop",
"is_authorized": false
}
],
"blocked_pentestable_entities": []
}
}
}
python h3_gql.py ./deauthorize_ips.graphql '{
"host_tab_xop_uuids": [
"1234abcd-1234-abcd-1234-abcd1234abcd/203.0.113.10"
]
}'
Save the example request as ./deauthorize_ips.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./deauthorize_ips.graphql '{
"host_tab_xop_uuids": [
"1234abcd-1234-abcd-1234-abcd1234abcd/203.0.113.10"
]
}'
Save the example request as ./deauthorize_ips.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./deauthorize_ips.graphql '{
"host_tab_xop_uuids": [
"1234abcd-1234-abcd-1234-abcd1234abcd/203.0.113.10"
]
}'
Save the example request as ./deauthorize_ips.graphql.
See h3-cli Examples for installation and usage.
bulk_authorize_ips
Description
Bulk authorizes all eligible in-scope HostTabXop IPs in the given OpSeries for External Attack pentesting. Only IPs whose PentestableRules evaluate to is_allowed = true and that are within the configured scope will be authorized. Optionally use page_input filters to narrow which IPs are authorized.
Response
Returns a PentestableEntitiesBulkOutput!
Arguments
op_series_uuid - String!
page_input - PageInput
mutation BulkAuthorizeIps(
$op_series_uuid: String!,
$page_input: PageInput
) {
bulk_authorize_ips(
op_series_uuid: $op_series_uuid,
page_input: $page_input
) {
pentestable_entities_count
}
}
Examples may not include all available fields for a type.
{
"data": {
"bulk_authorize_ips": {
"pentestable_entities_count": 8
}
}
}
python h3_gql.py ./bulk_authorize_ips.graphql '{
"op_series_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"page_input": null
}'
Save the example request as ./bulk_authorize_ips.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./bulk_authorize_ips.graphql '{
"op_series_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"page_input": null
}'
Save the example request as ./bulk_authorize_ips.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./bulk_authorize_ips.graphql '{
"op_series_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"page_input": null
}'
Save the example request as ./bulk_authorize_ips.graphql.
See h3-cli Examples for installation and usage.
bulk_deauthorize_ips
Description
Bulk deauthorizes all HostTabXop IPs in the given OpSeries, removing them from the scope of future External Attack pentests. Optionally use page_input filters to narrow which IPs are deauthorized.
Response
Returns a PentestableEntitiesBulkOutput!
Arguments
op_series_uuid - String!
page_input - PageInput
mutation BulkDeauthorizeIps(
$op_series_uuid: String!,
$page_input: PageInput
) {
bulk_deauthorize_ips(
op_series_uuid: $op_series_uuid,
page_input: $page_input
) {
pentestable_entities_count
}
}
Examples may not include all available fields for a type.
{
"data": {
"bulk_deauthorize_ips": {
"pentestable_entities_count": 8
}
}
}
python h3_gql.py ./bulk_deauthorize_ips.graphql '{
"op_series_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"page_input": null
}'
Save the example request as ./bulk_deauthorize_ips.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./bulk_deauthorize_ips.graphql '{
"op_series_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"page_input": null
}'
Save the example request as ./bulk_deauthorize_ips.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./bulk_deauthorize_ips.graphql '{
"op_series_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"page_input": null
}'
Save the example request as ./bulk_deauthorize_ips.graphql.
See h3-cli Examples for installation and usage.
PentestableEntity
Description
A PentestableEntity links a domain (ExternalDomainXop) or IP (HostTabXop) to its current authorization status for external pentesting.
fragment PentestableEntityFragment on PentestableEntity {
uuid
entity_type
is_authorized
}
Examples may not include all available fields for a type.
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd/example.com",
"entity_type": "ExternalDomainXop",
"is_authorized": true
}
PentestableRules
Description
The result of evaluating authorization rules for an ExternalDomainXop or HostTabXop. These rules determine whether a domain or IP asset is permitted to be authorized for External Attack pentesting. The evaluation considers factors such as third-party ownership and provider policies regarding pentesting.
Fields
action_tooltip - String
authz_warning - String
authz_warning_label - String
authz_warning message (e.g., the category of warning). is_allowed - Boolean!
true, the asset is permitted to be authorized for external pentesting. When false, the asset is blocked. fragment PentestableRulesFragment on PentestableRules {
is_allowed
action_tooltip
authz_warning
authz_warning_label
}
Examples may not include all available fields for a type.
{
"is_allowed": false,
"action_tooltip": "This domain is hosted by a provider that does not permit pentesting.",
"authz_warning": "This domain resolves to a third-party CDN. Verify that you own this asset before authorizing.",
"authz_warning_label": "Third-party CDN detected"
}
BlockedPentestableEntity
Description
A BlockedPentestableEntity pairs a domain or IP asset (PentestableEntity) with the PentestableRules that caused it to be blocked from authorization. Assets are blocked when the rules determine they are owned by providers that do not permit pentesting.
Fields
pentestable_entity - PentestableEntity
pentestable_rules - PentestableRules
fragment BlockedPentestableEntityFragment on BlockedPentestableEntity {
pentestable_entity {
uuid
entity_type
is_authorized
}
pentestable_rules {
is_allowed
action_tooltip
authz_warning
authz_warning_label
}
}
Examples may not include all available fields for a type.
{
"pentestable_entity": {
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd/api.example.com",
"entity_type": "ExternalDomainXop",
"is_authorized": false
},
"pentestable_rules": {
"is_allowed": false,
"action_tooltip": "This domain is hosted by a provider that does not permit pentesting.",
"authz_warning": null,
"authz_warning_label": null
}
}
PentestableEntitiesBulkOutput
Description
Output type for bulk authorization mutations such as bulk_authorize_domains, bulk_deauthorize_domains, bulk_authorize_ips, and bulk_deauthorize_ips.
Fields
pentestable_entities_count - Int!
fragment PentestableEntitiesBulkOutputFragment on PentestableEntitiesBulkOutput {
pentestable_entities_count
}
Examples may not include all available fields for a type.
{
"pentestable_entities_count": 15
}
PentestableEntitiesOutput
Description
Output type for mutations that authorize or deauthorize individual domain and IP assets for external pentesting, such as authorize_domains, deauthorize_domains, authorize_ips, and deauthorize_ips.
Fields
pentestable_entities - [PentestableEntity]
blocked_pentestable_entities - [BlockedPentestableEntity]
fragment PentestableEntitiesOutputFragment on PentestableEntitiesOutput {
pentestable_entities {
uuid
entity_type
is_authorized
}
blocked_pentestable_entities {
pentestable_entity {
uuid
entity_type
is_authorized
}
pentestable_rules {
is_allowed
action_tooltip
authz_warning
authz_warning_label
}
}
}
Examples may not include all available fields for a type.
{
"pentestable_entities": [
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd/example.com",
"entity_type": "ExternalDomainXop",
"is_authorized": true
}
],
"blocked_pentestable_entities": [
{
"pentestable_entity": {
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd/api.example.com",
"entity_type": "ExternalDomainXop",
"is_authorized": false
},
"pentestable_rules": {
"is_allowed": false,
"action_tooltip": "This domain is hosted by a provider that does not permit pentesting.",
"authz_warning": null,
"authz_warning_label": null
}
}
]
}
Pentesting
Access comprehensive pentest results and operational data. Query pentests and their findings including attack paths (impacts), weaknesses (vulnerabilities), compromised credentials, discovered hosts and services, proof artifacts, EDR detections, and detailed action logs. This is the core section for retrieving and analyzing the results of your autonomous pentests.
Pentesting: Ops
Manage operations (ops) which represent cybersecurity activities conducted by NodeZero. Query ops, create new pentests and other operation types, control execution (pause, resume, cancel), and track operational status and configuration.
ops_page
Description
Returns a paginated list of ops for the current client account.
Includes all op types and archived ops. Use page_input to paginate, sort, and filter results.
Response
Returns an OpsPage!
Arguments
page_input - PageInput
query OpsPage($page_input: PageInput) {
ops_page(page_input: $page_input) {
ops {
...OpFragment
}
}
}
fragment OpFragment on Op {
op_id
op_type
op_name
op_state
portal_op_state
op_param_max_scope
scheduled_at
created_at
launched_at
completed_at
duration_hms
hosts_count
weaknesses_count
runner_uuid
runner_name
portal_url
}
Examples may not include all available fields for a type.
{
"data": {
"ops_page": {
"ops": [
{
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_type": "NodeZero",
"op_name": "Weekly Internal Pentest",
"op_state": "done",
"portal_op_state": "done",
"op_param_max_scope": ["10.0.0.0/8"],
"scheduled_at": "2024-01-15T09:00:00Z",
"created_at": "2024-01-15T09:00:00Z",
"launched_at": "2024-01-15T09:05:00Z",
"completed_at": "2024-01-15T17:30:00Z",
"duration_hms": "08:25:00",
"hosts_count": 150,
"weaknesses_count": 23,
"runner_uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"runner_name": "runner-01",
"portal_url": "https://portal.yourorg.com/ops/1234abcd-1234-abcd-1234-abcd1234abcd"
},
{
"op_id": "5678efgh-5678-efgh-5678-efgh5678efgh",
"op_type": "ExternalAttack",
"op_name": "Monthly External Assessment",
"op_state": "done",
"portal_op_state": "done",
"op_param_max_scope": null,
"scheduled_at": "2024-01-08T14:00:00Z",
"created_at": "2024-01-08T14:00:00Z",
"launched_at": "2024-01-08T14:05:00Z",
"completed_at": "2024-01-08T18:15:00Z",
"duration_hms": "04:10:00",
"hosts_count": 45,
"weaknesses_count": 8,
"runner_uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"runner_name": "runner-01",
"portal_url": "https://portal.yourorg.com/ops/5678efgh-5678-efgh-5678-efgh5678efgh"
}
]
}
}
}
python h3_gql.py ./ops_page.graphql '{
"page_input": {
"page_size": 10
}
}'
Save the example request as ./ops_page.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./ops_page.graphql '{
"page_input": {
"page_size": 10
}
}'
Save the example request as ./ops_page.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./ops_page.graphql '{
"page_input": {
"page_size": 10
}
}'
Save the example request as ./ops_page.graphql.
See h3-cli Examples for installation and usage.
ops_count
Description
Returns the total number of ops for the current client account.
Includes all op types, including non-pentest types such as ExternalAssetDiscovery. Includes archived ops.
Use page_input filters to narrow results (e.g. by op_type or date range).
Response
Returns an Int!
query OpsCount($client_account_uuid: String) {
ops_count(client_account_uuid: $client_account_uuid)
}
Examples may not include all available fields for a type.
{
"data": {
"ops_count": 42
}
}
python h3_gql.py ./ops_count.graphql
Save the example request as ./ops_count.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./ops_count.graphql
Save the example request as ./ops_count.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./ops_count.graphql
Save the example request as ./ops_count.graphql.
See h3-cli Examples for installation and usage.
op
Description
Returns a single Op by its op_id.
The returned Op includes summary counts, timestamps, configuration, and links to related entities such as weaknesses, attack paths, and assets.
Response
Returns an Op
Arguments
op_id - String!
query Op($op_id: String!) {
op(op_id: $op_id) {
...OpFragment
}
}
fragment OpFragment on Op {
op_id
op_type
op_name
op_state
portal_op_state
op_param_max_scope
scheduled_at
created_at
launched_at
completed_at
duration_hms
hosts_count
weaknesses_count
runner_uuid
runner_name
portal_url
}
Examples may not include all available fields for a type.
{
"data": {
"op": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_type": "NodeZero",
"op_name": "Weekly Internal Pentest",
"op_state": "done",
"portal_op_state": "done",
"op_param_max_scope": ["10.0.0.0/8"],
"scheduled_at": "2024-01-15T09:00:00Z",
"created_at": "2024-01-15T09:00:00Z",
"launched_at": "2024-01-15T09:05:00Z",
"completed_at": "2024-01-15T17:30:00Z",
"duration_hms": "08:25:00",
"hosts_count": 150,
"weaknesses_count": 23,
"runner_uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"runner_name": "runner-01",
"portal_url": "https://portal.yourorg.com/ops/1234abcd-1234-abcd-1234-abcd1234abcd"
}
}
}
python h3_gql.py ./op.graphql '{
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./op.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./op.graphql '{
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./op.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./op.graphql '{
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./op.graphql.
See h3-cli Examples for installation and usage.
create_op
Description
Creates a new Op for immediate execution. An op is an autonomous cybersecurity assessment conducted by NodeZero.
See ScheduleOpFormInput for the full set of configuration options available when creating an op, and OpType for the list of supported operation types (e.g. internal pentest, external pentest, AD password audit) and their configuration requirements.
You can optionally base the op on an OpTemplate by passing op_template_uuid. Op templates store reusable configurations, making it easy to run similar ops repeatedly. See Mutation.create_op_template for creating op templates.
To run ops on an automated recurring schedule (e.g. weekly or monthly), see Schedule and Mutation.create_scheduled_action.
Response
Returns a CreateOpOutput!
Arguments
op_template_uuid - String
The OpTemplate UUID to use as the base configuration for this op.
If not specified, the default op template for the op type in schedule_op_form.op_type is used. If schedule_op_form.op_type is also not defined, the default op type is NodeZero (internal pentest).
schedule_op_form - ScheduleOpFormInput
schedule_op_form. See ScheduleOpFormInput for available options. mutation CreateOp($schedule_op_form: ScheduleOpFormInput) {
create_op(schedule_op_form: $schedule_op_form) {
op {
...OpFragment
}
}
}
fragment OpFragment on Op {
op_id
op_type
op_name
op_state
portal_op_state
op_param_max_scope
scheduled_at
nodezero_script_url
nodezero_ip
runner_uuid
runner_name
}
Examples may not include all available fields for a type.
{
"data": {
"create_op": {
"op": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_type": "NodeZero",
"op_name": "Weekly Internal Pentest",
"op_state": "scheduled",
"portal_op_state": "scheduled",
"op_param_max_scope": ["10.0.0.0/8"],
"scheduled_at": "2024-01-15T09:00:00Z",
"nodezero_script_url": "https://download.yourorg.com/nodezero.sh",
"nodezero_ip": null,
"runner_uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"runner_name": "runner-01"
}
}
}
}
python h3_gql.py ./create_op.graphql '{
"schedule_op_form": {
"op_name": "Weekly Internal Pentest",
"op_type": "NodeZero",
"op_param_max_scope": "10.0.0.0/8",
"maximum_run_time": 480
}
}'
Save the example request as ./create_op.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./create_op.graphql '{
"schedule_op_form": {
"op_name": "Weekly Internal Pentest",
"op_type": "NodeZero",
"op_param_max_scope": "10.0.0.0/8",
"maximum_run_time": 480
}
}'
Save the example request as ./create_op.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./create_op.graphql '{
"schedule_op_form": {
"op_name": "Weekly Internal Pentest",
"op_type": "NodeZero",
"op_param_max_scope": "10.0.0.0/8",
"maximum_run_time": 480
}
}'
Save the example request as ./create_op.graphql.
See h3-cli Examples for installation and usage.
pause_op
Description
Pauses a running Op.
The op must be in a pausable state (e.g. running). Returns an error if the op is already paused or in a non-pausable state.
Use Mutation.resume_op to resume a paused op.
Response
Returns an OpTab!
Arguments
op_id - String!
mutation PauseOp($op_id: String!) {
pause_op(op_id: $op_id) {
op_id
op_name
op_state
portal_op_state
}
}
Examples may not include all available fields for a type.
{
"data": {
"pause_op": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_name": "Weekly Internal Pentest",
"op_state": "paused",
"portal_op_state": "paused"
}
}
}
python h3_gql.py ./pause_op.graphql '{
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./pause_op.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./pause_op.graphql '{
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./pause_op.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./pause_op.graphql '{
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./pause_op.graphql.
See h3-cli Examples for installation and usage.
resume_op
Description
Resumes a paused Op.
The op must be in a resumable state (e.g. paused, user_paused, start_paused). Returns an error if the op is already running or in a non-resumable state.
Use Mutation.pause_op to pause a running op.
Response
Returns an OpTab!
Arguments
op_id - String!
mutation ResumeOp($op_id: String!) {
resume_op(op_id: $op_id) {
op_id
op_name
op_state
portal_op_state
}
}
Examples may not include all available fields for a type.
{
"data": {
"resume_op": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_name": "Weekly Internal Pentest",
"op_state": "running",
"portal_op_state": "running"
}
}
}
python h3_gql.py ./resume_op.graphql '{
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./resume_op.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./resume_op.graphql '{
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./resume_op.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./resume_op.graphql '{
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./resume_op.graphql.
See h3-cli Examples for installation and usage.
cancel_op
Description
Cancels an Op, ending it early.
The op must be in a cancelable state (e.g. running, paused, ready). Returns an error if the op is already in a terminal state such as done or canceled.
Partial results from the op may still be available in Portal after cancellation.
Response
Returns an OpTab!
Arguments
op_id - String!
mutation CancelOp($op_id: String!) {
cancel_op(op_id: $op_id) {
op_id
op_name
op_state
portal_op_state
}
}
Examples may not include all available fields for a type.
{
"data": {
"cancel_op": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_name": "Weekly Internal Pentest",
"op_state": "cancelling",
"portal_op_state": "ended"
}
}
}
python h3_gql.py ./cancel_op.graphql '{
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./cancel_op.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./cancel_op.graphql '{
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./cancel_op.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./cancel_op.graphql '{
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./cancel_op.graphql.
See h3-cli Examples for installation and usage.
update_op
Description
Updates an existing Op. Supports renaming, archiving, and deleting ops.
See UpdateOpInput for the set of fields that can be updated.
Response
Returns an UpdateOpOutput
Arguments
op_id - String!
update_op_input - UpdateOpInput!
mutation UpdateOp($op_id: String!, $update_op_input: UpdateOpInput!) {
update_op(op_id: $op_id, update_op_input: $update_op_input) {
op {
...OpFragment
}
}
}
fragment OpFragment on Op {
op_id
op_type
op_name
op_state
portal_op_state
op_param_max_scope
scheduled_at
created_at
launched_at
completed_at
duration_hms
hosts_count
weaknesses_count
runner_uuid
runner_name
portal_url
}
Examples may not include all available fields for a type.
{
"data": {
"update_op": {
"op": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_type": "NodeZero",
"op_name": "Renamed Pentest",
"op_state": "done",
"portal_op_state": "done",
"op_param_max_scope": ["10.0.0.0/8"],
"scheduled_at": "2024-01-15T09:00:00Z",
"created_at": "2024-01-15T09:00:00Z",
"launched_at": "2024-01-15T09:05:00Z",
"completed_at": "2024-01-15T17:30:00Z",
"duration_hms": "08:25:00",
"hosts_count": 150,
"weaknesses_count": 23,
"runner_uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"runner_name": "runner-01",
"portal_url": "https://portal.yourorg.com/ops/1234abcd-1234-abcd-1234-abcd1234abcd"
}
}
}
}
python h3_gql.py ./update_op.graphql '{
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"update_op_input": {
"op_name": "Renamed Pentest"
}
}'
Save the example request as ./update_op.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./update_op.graphql '{
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"update_op_input": {
"op_name": "Renamed Pentest"
}
}'
Save the example request as ./update_op.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./update_op.graphql '{
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"update_op_input": {
"op_name": "Renamed Pentest"
}
}'
Save the example request as ./update_op.graphql.
See h3-cli Examples for installation and usage.
rerun_op
Description
Creates a new Op using the same configuration as a previously run op.
This is a convenient way to re-run an op with the same (or similar) settings. You can optionally override specific configuration parameters via schedule_op_form.
The new op is created for immediate execution.
Response
Returns a ScheduleOpOutput!
Arguments
op_id - String!
op_id of the previously run op whose configuration will be used as the base. op_name - String
schedule_op_form - ScheduleOpFormInput
agent_name - String
runner_uuid - String
mutation RerunOp($op_id: String!, $op_name: String, $runner_uuid: String) {
rerun_op(op_id: $op_id, op_name: $op_name, runner_uuid: $runner_uuid) {
op {
...OpFragment
}
}
}
fragment OpFragment on Op {
op_id
op_type
op_name
op_state
portal_op_state
op_param_max_scope
scheduled_at
created_at
nodezero_script_url
runner_uuid
runner_name
portal_url
}
Examples may not include all available fields for a type.
{
"data": {
"rerun_op": {
"op": {
"op_id": "9012ijkl-9012-ijkl-9012-ijkl9012ijkl",
"op_type": "NodeZero",
"op_name": "Rerun - Weekly Internal Pentest",
"op_state": "scheduled",
"portal_op_state": "scheduled",
"op_param_max_scope": ["10.0.0.0/8"],
"scheduled_at": "2024-01-16T09:00:00Z",
"created_at": "2024-01-16T09:00:00Z",
"nodezero_script_url": "https://download.yourorg.com/nodezero.sh",
"runner_uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"runner_name": "runner-01",
"portal_url": "https://portal.yourorg.com/ops/9012ijkl-9012-ijkl-9012-ijkl9012ijkl"
}
}
}
}
python h3_gql.py ./rerun_op.graphql '{
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_name": "Rerun - Weekly Internal Pentest",
"runner_uuid": "abcd1234-abcd-1234-abcd-1234abcd1234"
}'
Save the example request as ./rerun_op.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./rerun_op.graphql '{
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_name": "Rerun - Weekly Internal Pentest",
"runner_uuid": "abcd1234-abcd-1234-abcd-1234abcd1234"
}'
Save the example request as ./rerun_op.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./rerun_op.graphql '{
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_name": "Rerun - Weekly Internal Pentest",
"runner_uuid": "abcd1234-abcd-1234-abcd-1234abcd1234"
}'
Save the example request as ./rerun_op.graphql.
See h3-cli Examples for installation and usage.
sample_ops_page
Description
Get a list of ops for the Horizon3 sample client account. Includes all op types. Includes archived ops.
Response
Returns an OpsPage!
Arguments
page_input - PageInput
query SampleOpsPage($page_input: PageInput) {
sample_ops_page(page_input: $page_input) {
ops {
...OpFragment
}
}
}
fragment OpFragment on Op {
op_id
op_type
op_name
op_state
portal_op_state
op_param_max_scope
scheduled_at
created_at
launched_at
completed_at
duration_hms
hosts_count
weaknesses_count
runner_uuid
runner_name
portal_url
}
Examples may not include all available fields for a type.
{
"data": {
"sample_ops_page": {
"ops": [
{
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_type": "NodeZero",
"op_name": "Sample Internal Pentest",
"op_state": "done",
"portal_op_state": "done",
"op_param_max_scope": ["10.0.0.0/8"],
"scheduled_at": "2024-01-15T09:00:00Z",
"created_at": "2024-01-15T09:00:00Z",
"launched_at": "2024-01-15T09:05:00Z",
"completed_at": "2024-01-15T17:30:00Z",
"duration_hms": "08:25:00",
"hosts_count": 150,
"weaknesses_count": 23,
"runner_uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"runner_name": "runner-01",
"portal_url": "https://portal.yourorg.com/ops/1234abcd-1234-abcd-1234-abcd1234abcd"
},
{
"op_id": "5678efgh-5678-efgh-5678-efgh5678efgh",
"op_type": "ExternalAttack",
"op_name": "Sample External Assessment",
"op_state": "done",
"portal_op_state": "done",
"op_param_max_scope": null,
"scheduled_at": "2024-01-08T14:00:00Z",
"created_at": "2024-01-08T14:00:00Z",
"launched_at": "2024-01-08T14:05:00Z",
"completed_at": "2024-01-08T18:15:00Z",
"duration_hms": "04:10:00",
"hosts_count": 45,
"weaknesses_count": 8,
"runner_uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"runner_name": "runner-01",
"portal_url": "https://portal.yourorg.com/ops/5678efgh-5678-efgh-5678-efgh5678efgh"
}
]
}
}
}
python h3_gql.py ./sample_ops_page.graphql '{
"page_input": {
"page_size": 10
}
}'
Save the example request as ./sample_ops_page.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./sample_ops_page.graphql '{
"page_input": {
"page_size": 10
}
}'
Save the example request as ./sample_ops_page.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./sample_ops_page.graphql '{
"page_input": {
"page_size": 10
}
}'
Save the example request as ./sample_ops_page.graphql.
See h3-cli Examples for installation and usage.
sample_op
Description
Get pentest data for a Horizon3 sample client account Op.
Response
Returns an Op
Arguments
op_id - String!
query SampleOp($op_id: String!) {
sample_op(op_id: $op_id) {
...OpFragment
}
}
fragment OpFragment on Op {
op_id
op_type
op_name
op_state
portal_op_state
op_param_max_scope
scheduled_at
created_at
launched_at
completed_at
duration_hms
hosts_count
weaknesses_count
runner_uuid
runner_name
portal_url
}
Examples may not include all available fields for a type.
{
"data": {
"sample_op": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_type": "NodeZero",
"op_name": "Sample Internal Pentest",
"op_state": "done",
"portal_op_state": "done",
"op_param_max_scope": ["10.0.0.0/8"],
"scheduled_at": "2024-01-15T09:00:00Z",
"created_at": "2024-01-15T09:00:00Z",
"launched_at": "2024-01-15T09:05:00Z",
"completed_at": "2024-01-15T17:30:00Z",
"duration_hms": "08:25:00",
"hosts_count": 150,
"weaknesses_count": 23,
"runner_uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"runner_name": "runner-01",
"portal_url": "https://portal.yourorg.com/ops/1234abcd-1234-abcd-1234-abcd1234abcd"
}
}
}
python h3_gql.py ./sample_op.graphql '{
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./sample_op.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./sample_op.graphql '{
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./sample_op.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./sample_op.graphql '{
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./sample_op.graphql.
See h3-cli Examples for installation and usage.
Op
Description
An Op represents an autonomous cybersecurity operation conducted by NodeZero.
The most common type of Op is an internal Pentest, but NodeZero supports several other operation types including external pentesting, asset discovery, Active Directory password audits, and more.
See OpType for the full list of supported operation types and their configuration requirements.
Use Query.ops_page to list ops, Query.op to retrieve a single op, and Mutation.create_op to create a new op.
Fields
op_id - String
op_type - OpType
op_state - String!
The current state of the op. Possible values include:
scheduled- The op has been created and is queued to start.provisioning- Resources are being provisioned.ready- NodeZero is ready to launch.running- The op is actively scanning the environment.complete- The scan has finished; results are being processed.post-processing- Op results are undergoing post-processing.done- The op is complete and results are available.cancelling- The op is in the process of being canceled.canceled- The op was canceled by a user.paused- The op is paused.error- The op encountered an error.
See PortalOpState for an alternative representation of op state used by the Portal UI.
portal_op_state - PortalOpState!
op_name - String!
op_param_min_scope - [String]
The minimum scope for this op, as a list of IPs and CIDR ranges.
When set, the Auto-Expand Scope feature is enabled. NodeZero will scan these specific hosts plus any additional hosts it discovers organically during the op.
See ScheduleOpForm.op_param_min_scope for full details on how minimum and maximum scope interact.
op_param_max_scope - [String]
The maximum scope for this op, as a list of IPs and CIDR ranges.
When set, NodeZero will only scan hosts and subnets that fall within this scope. The Auto-Expand Scope feature is disabled.
See ScheduleOpForm.op_param_max_scope for full details on how minimum and maximum scope interact.
op_param_blacklist - String
scheduled_timestamp - Float!
scheduled_timestamp_iso - String!
scheduled_at instead
scheduled_at - Datetime!
created_at. scheduled_at_date - Date!
created_at - Datetime!
completed_timestamp_iso - String
completed_at instead
completed_at - Datetime
Op.etl_completed_at to get the timestamp that includes post-processing. canceled_at - Datetime
launched_timestamp_iso - String
launched_at instead
launched_at - Datetime
etl_completed_at - Datetime
duration_s - Int
launched_at and completed_at. services_count - Int!
credentials_count - Int!
confirmed_credentials_count - Int
hosts_count - Int
out_of_scope_hosts_count - Int
external_domains_count - Int
users_count - Int
websites_count - Int
data_stores_count - Int
data_resources_count - Long
weaknesses_count - Int
weaknesses_page - WeaknessesPage!
Arguments
page_input - PageInput
proven_weaknesses_count - Int
in_scope_hosts_count - Int
hosts_count. feature_flags - [FeatureFlag]
nodezero_script_url - String
nodezero_ip - String
duration_hms - String
launched_at and completed_at. duration_humanize - String
launched_at and completed_at. op_template_uuid - String
op_template_name - String
impact_paths_count - Int
attack_paths_count. attack_paths_count - Int
impact_paths_count. attack_paths_page - AttackPathsPage!
Arguments
page_input - PageInput
phished_impact_paths_count - Int!
phished_attack_paths_count. phished_attack_paths_count - Int!
phished_impact_paths_count. runner_uuid - String
runner_name - String
schedule_uuid - String
schedule_name - String
schedule - Schedule
schedule_op_form - ScheduleOpForm!
asset_group_uuid - String
ExternalAssetDiscovery and ExternalAttack op types. asset_group - AssetGroup
portal_url - String
fragment OpFragment on Op {
op_id
op_type
op_name
op_state
portal_op_state
op_param_max_scope
op_param_blacklist
scheduled_at
created_at
launched_at
completed_at
etl_completed_at
canceled_at
duration_s
duration_hms
duration_humanize
hosts_count
services_count
credentials_count
users_count
weaknesses_count
attack_paths_count
nodezero_script_url
nodezero_ip
runner_uuid
runner_name
schedule_uuid
schedule_name
portal_url
}
Examples may not include all available fields for a type.
{
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_type": "NodeZero",
"op_name": "Weekly Internal Pentest",
"op_state": "done",
"portal_op_state": "done",
"op_param_max_scope": ["10.0.0.0/8"],
"op_param_blacklist": "10.0.0.1,10.0.0.2",
"scheduled_at": "2024-01-15T09:00:00Z",
"created_at": "2024-01-15T09:00:00Z",
"launched_at": "2024-01-15T09:05:00Z",
"completed_at": "2024-01-15T17:30:00Z",
"etl_completed_at": "2024-01-15T18:00:00Z",
"canceled_at": null,
"duration_s": 30300,
"duration_hms": "08:25:00",
"duration_humanize": "8 hours 25 minutes",
"hosts_count": 150,
"services_count": 320,
"credentials_count": 5,
"users_count": 85,
"weaknesses_count": 23,
"attack_paths_count": 45,
"nodezero_script_url": "https://download.yourorg.com/nodezero.sh",
"nodezero_ip": "10.0.0.100",
"runner_uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"runner_name": "runner-01",
"schedule_uuid": "efgh5678-efgh-5678-efgh-5678efgh5678",
"schedule_name": "Weekly Pentest Schedule",
"portal_url": "https://portal.yourorg.com/ops/1234abcd-1234-abcd-1234-abcd1234abcd"
}
OpType
Description
The type of operation to run. You must specify an op type when creating an Op or an OpTemplate.
Each op type has different configuration requirements. See the individual enum values below for details on each type and how to configure it via ScheduleOpFormInput.
For more information about op types, visit the Tests & Assessments section of the Horizon3.ai documentation.
Values
NodeZero
An Internal Pentest op, a simulated attack on your organization's internal network designed to identify vulnerabilities, misconfigurations, and exploitable attack paths.
NodeZero autonomously enumerates devices in scope, then chains together context, exploitable vulnerabilities, misconfigurations, and captured data to identify attack paths ranked by impact, with proof of exploitability.
Minimum configuration to get started:
- A network scope to pentest, specified in CIDR notation via
op_param_min_scopeorop_param_max_scope - A Docker Host within your network, on which to launch NodeZero
Scope options include:
- Intelligent Scope: NodeZero automatically expands from the Docker Host's subnet to discover nearby assets. Useful for scenario-based testing.
- Full private IP space (RFC 1918): Covers
10.0.0.0/8,172.16.0.0/12, and192.168.0.0/16for comprehensive coverage. - Custom IPs or subnets: Specify exact CIDR ranges. Can be combined with auto-expand scope (
op_param_min_scope) to let NodeZero discover additional assets beyond the initial scope.
Additional configuration options include attack configurations, credential injection, AWS account integration, OSINT terms, and tripwire deployment.
ExternalAssetDiscovery
An External Asset Discovery op, for discovering public-facing domains and IPs in an AssetGroup.
This op is usually run in advance of an ExternalAttack pentest. It performs initial discovery of your external attack surface, identifying domains, subdomains, and IP addresses associated with your organization. You may then select one or more of the discovered domains and IPs to authorize for external pentesting.
To run an ExternalAssetDiscovery op for an AssetGroup, use Mutation.create_op and pass the AssetGroup.uuid via schedule_op_form.asset_group_uuid. Alternatively, you can pass the AssetGroup.op_template_uuid via the op_template_uuid parameter.
This is an external operation and therefore NodeZero is launched from the H3 cloud. It does not require a Docker Host within your network.
ExternalAttack
An External Pentest op, for pentesting public-facing domains and IPs in an AssetGroup.
In many cases users will run an ExternalAssetDiscovery op first, to discover their external attack surface, then authorize NodeZero to pentest one or more of the discovered domains and IPs. This workflow involves several steps:
- create an
AssetGroup - run an
ExternalAssetDiscoveryop, to discover public domains and IPs - authorize discovered domains and IPs for external pentesting
- run an
ExternalAttackop against the authorized assets
However, this workflow is no longer strictly required. As of April 2025, you may now configure and run an external pentest directly, without first running an ExternalAssetDiscovery op. NodeZero will auto-discover your attack surface during the pentest, and it will auto-authorize and pentest any discovered domain that doesn't have a CNAME record from a third-party service.
After the external pentest completes, all discovered domains and IPs are included in the results in Portal. You may then authorize additional domains and IPs for further pentesting.
To run an ExternalAttack op for an AssetGroup use Mutation.create_op and pass the AssetGroup.uuid via schedule_op_form.asset_group_uuid.
Alternatively you can create an OpTemplate for the ExternalAttack op and set the AssetGroup.uuid in OpTemplate.schedule_op_form.asset_group_uuid.
This is an external operation and therefore NodeZero is launched from the H3 cloud. It does not require a Docker Host within your network.
NetworkEnumeration
A Network Enumeration op (also known as a Segmentation Test), for scanning and enumerating assets on an internal network.
NodeZero discovers IPs, ports, services, and applications within the target scope, but does not perform any attacks or exploitation. This is a discovery-only operation.
Common use cases include:
- Initial reconnaissance: Understand what exists on a network before running exploit-based tests.
- Asset inventorying: Get a snapshot of hosts, services, and applications on the network.
- Segmentation validation: Verify which assets are reachable from a given network segment.
Scope is configured via op_param_min_scope or op_param_max_scope using IPs or subnets in CIDR notation. The full private IP space (RFC 1918) can also be used for comprehensive coverage.
This is an internal operation and therefore requires that you launch NodeZero on a Docker Host within your network.
ADPasswordAudit
An Active Directory Password Audit op, for auditing the strength and security of user passwords in your Active Directory environment.
This is a gray-box style audit. NodeZero uses a privileged credential with DCSync permissions to extract NTLM password hashes from Active Directory domain controllers, then attempts to crack those hashes using multiple methods:
- Common weak passwords
- Passwords that resemble usernames
- Company-specific terms (company names, domain names)
- Dark web breach data associated with your organization
- Known breached password databases
- Custom weak password terms you provide via OSINT configuration
NodeZero also analyzes the population of passwords for password reuse -- cases where two or more users share the exact same or similar passwords.
The minimum required credential is a domain user account with DCSync privileges (Replicating Directory Changes, Replicating Directory Changes All, and Replicating Directory Changes in Filtered Set). A domain admin account may also be used.
Configure the domain controller IP address and the privileged credential via ScheduleOpFormInput.
This is an internal operation and therefore requires that you launch NodeZero on a Docker Host within your network.
Phishing
A Phishing Impact Test op, for measuring the real-world impact of successful phishing attacks within your organization.
This op works in conjunction with your organization's phishing simulation tools (e.g. KnowBe4, ProofPoint). NodeZero generates a JavaScript payload to embed in your phishing campaign's landing page. When a user is phished, their credentials are automatically captured and injected into NodeZero, which uses them to perform an authenticated internal pentest.
The results convey the business risk of a successful phishing attack by showing what an attacker could accomplish with the phished credentials, including lateral movement and privilege escalation.
Key configuration considerations:
- A minimum campaign runtime must be configured to match the duration of your phishing campaign. Campaigns of up to 28 days are supported.
- Up to 100 phished credentials can be captured per test.
- Scope should include networks where phishing targets have access, as well as networks they should not have access to, in order to validate security controls.
This is an internal operation and therefore requires that you launch NodeZero on a Docker Host within your network.
AWSPentest
An AWS Pentest op, a gray-box style assessment of your AWS cloud account security.
NodeZero uses a read-only IAM role to gain a comprehensive view of your AWS account and identify exploitable vulnerabilities and misconfigurations in IAM policies, security configurations, and cloud resources.
To run an AWS Pentest, you must first configure one or more AWSConnection objects, one for each AWS account you want to assess. Cloud connections are long-lived and reusable across multiple pentests. The connections are specified via schedule_op_form.aws_connection_uuids.
Two IAM policy options are available when creating a connection:
- SecurityAudit: Grants access to read security configuration metadata only, allowing NodeZero to analyze IAM and security configurations.
- ReadOnlyAccess: Provides read-only access to all AWS services, allowing NodeZero to also analyze sensitive information stored in resources such as S3 buckets and Lambda functions.
This is an external operation and therefore NodeZero is launched from the H3 cloud. It does not require a Docker Host within your network.
K8sPentest
A Kubernetes Pentest op, for pentesting the security of your Kubernetes clusters.
NodeZero runs from inside your cluster to simulate the scenario where an attacker has gained a foothold -- for example, through a compromised kubeconfig file or a vulnerable application running in a pod. All Kubernetes resources (nodes, pods, services) are treated as in-scope.
Prerequisites:
- The NodeZero Operator must be installed in the target cluster. Supported on Kubernetes cluster versions 1.24.0 and above.
- NodeZero is launched from within the cluster using a NodeZero Runner for Kubernetes. See
Mutation.install_agentfor how to install a Runner.
Scope configuration options to consider include:
k8s_deployment(should be set totrue)k8s_namespace: the namespace for NodeZero to run ink8s_service_account_name: specify a service account to simulate a compromised pod scenariok8s_node: target a specific node
Including the CIDR ranges of your cluster and the surrounding internal network or VPC is recommended, to test whether NodeZero can reach outside the cluster to other hosts.
AzurePentest
An Azure Entra ID Pentest op, for assessing the security of your Azure Active Directory / Entra ID environment.
This is a gray-box style pentest that evaluates the security posture of your hybrid Azure AD environment by identifying misconfigurations and exploitable weaknesses. NodeZero requires a privileged AD credential with DCSync permissions and an Azure Entra ID user credential to enumerate the environment and identify attack paths.
This is an internal operation and therefore requires that you launch NodeZero on a Docker Host within your network.
See also AzureInternalPentest for an enhanced Azure assessment with additional cloud-native capabilities.
AzureInternalPentest
An Azure Internal Pentest op, a gray-box style assessment that evaluates attack paths from on-premise Active Directory to Azure Entra ID tenant compromise.
This pentest requires two credentials:
- A privileged AD credential with DCSync permissions, allowing NodeZero to simulate a domain compromise and evaluate attack vectors such as Entra Connect credential dumping and Azure Seamless SSO Silver Ticket attacks.
- An Azure Entra ID user credential, allowing NodeZero to enumerate the Entra ID environment and identify privilege escalation misconfigurations. This credential does not need to be privileged, as Entra ID allows users to enumerate a significant portion of tenant configuration by default.
NodeZero uses the Azure Device Code Flow (OAuth Device Authorization Grant) for the Entra ID credential. During configuration, provide the Entra tenant ID. After the pentest launches, you will be prompted to complete the MFA authentication flow.
This is an internal operation and therefore requires that you launch NodeZero on a Docker Host within your private network.
InsiderThreatAttack
An Insider Threat Attack op, for simulating the fallout from an insider-turned-attacker and measuring the blast radius of compromised employee credentials.
This is essentially an internal pentest with the additional requirement of injecting the credentials of an insider-threat actor (e.g. an employee's domain credentials). NodeZero uses these credentials as a starting point and demonstrates how far an attacker could move laterally, escalate privileges, and access sensitive data.
The pentest results help you understand the degree to which that employee -- or an attacker who has compromised that employee's credentials -- can attack your network, and identify security controls that can mitigate the risk.
Credential types supported include cleartext passwords and NTLM hashes. Additional configuration options include AWS account integration, OSINT terms, tripwire deployment, and attack configurations. See ScheduleOpFormInput for details.
This is an internal operation and therefore requires that you launch NodeZero on a Docker Host within your network.
TripwiresInternal
A "Drop Tripwires" op, for deploying deceptive tokens (tripwires) on designated targets within your internal network. Tripwires detect real-world unauthorized access by triggering alerts when an attacker interacts with them.
An injected credential should be included for each target in the scope of the op, allowing NodeZero to authenticate and deploy the tripwire tokens on those targets. A maximum of 100 tripwires are deployed per operation.
This op type requires that the Tripwires feature is enabled for your account.
This is an internal operation and therefore requires that you launch NodeZero on a Docker Host within your network.
Example
"NodeZero"
PortalOpState
Description
Represents the current state of an Op as displayed in the Portal UI.
These states map to the op lifecycle: scheduling, provisioning, running, pausing/resuming, post-processing, and completion. See Op.portal_op_state for usage.
Values
done
ended
error
installation_needed
awaiting_runner
start_paused
Mutation.resume_op to begin the scan. user_paused
Mutation.resume_op to continue. paused
pausing
preparing
preparing_start_paused
processing
resuming
running
scheduled
queued
unknown
Example
"done"
CreateOpOutput
Description
The output from Mutation.create_op.
fragment CreateOpOutputFragment on CreateOpOutput {
op {
op_id
op_type
op_name
op_state
portal_op_state
op_param_max_scope
scheduled_at
nodezero_script_url
runner_uuid
runner_name
}
}
Examples may not include all available fields for a type.
{
"op": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_type": "NodeZero",
"op_name": "Weekly Internal Pentest",
"op_state": "scheduled",
"portal_op_state": "scheduled",
"op_param_max_scope": ["10.0.0.0/8"],
"scheduled_at": "2024-01-15T09:00:00Z",
"nodezero_script_url": "https://download.yourorg.com/nodezero.sh",
"runner_uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"runner_name": "runner-01"
}
}
OpTab
Fields
uuid - String
op_id - String
uuid. op_state - String!
State of pentest:
- scheduled
- provisioning
- ready
- running
- complete
- post-processing
- done
- cancelling
- canceled
- paused
- error
portal_op_state - PortalOpState!
op_name - String!
scheduled_timestamp - Float!
scheduled_at - Datetime!
scheduled_at_date - Date!
scheduled_timestamp_iso - String!
create_timestamp - Int!
create_timestamp_iso - String!
launched_timestamp - Int
launched_timestamp_iso - String
launched_at - Datetime
completed_at - Datetime
completed_timestamp - Float
completed_timestamp_iso - String
canceled_at - Datetime
canceled_timestamp - Int
canceled_timestamp_iso - String
duration_hms - String
duration_humanize - String
op_type - OpType
weakness_types_count - Int
weaknesses_count - Int
host_tabs_count - Int
in_scope_endpoints_count. domain_controllers_count - Int
credentials_count - Int
proven_credentials_count - Int
confirmed_credentials_count - Int
proven_credentials_count. unproven_credentials_count - Int
activedir_passwords_count - Int
enabled_activedir_passwords_count - Int
disabled_activedir_passwords_count - Int
feature_flags - [FeatureFlag]
impacts_headline_count - Int
impact_paths_count - Int
attack_paths_count. attack_paths_count - Int
impact_paths_count. phished_impact_paths_count - Int!
phished_attack_paths_count phished_attack_paths_count - Int!
phished_impact_paths_count. nodezero_script_url - String
nodezero_ip - String
etl_completed_at - Datetime
start_paused - Boolean
minimum_run_time - Int
maximum_run_time - Int
paused_at - Datetime
paused_by_user_account_uuid - String
paused_by_user_account - UserAccount
op_template_uuid - String
op_template_name - String
excluded_ips - [ExcludedIP]
excluded_domains - [ExcludedDomain]
runner_uuid - String
runner_name - String
schedule_uuid - String
schedule_name - String
schedule - Schedule
auto_injected_credential_uuids - [String]
tripwires_count - Int
fragment OpTabFragment on OpTab {
uuid
op_id
op_state
portal_op_state
op_name
op_type
scheduled_at
launched_at
completed_at
canceled_at
etl_completed_at
duration_hms
duration_humanize
weaknesses_count
weakness_types_count
host_tabs_count
credentials_count
attack_paths_count
impacts_headline_count
nodezero_script_url
nodezero_ip
runner_uuid
runner_name
schedule_uuid
schedule_name
op_template_uuid
op_template_name
tripwires_count
}
Examples may not include all available fields for a type.
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_state": "done",
"portal_op_state": "done",
"op_name": "Weekly Internal Pentest",
"op_type": "NodeZero",
"scheduled_at": "2024-01-15T09:00:00Z",
"launched_at": "2024-01-15T09:05:00Z",
"completed_at": "2024-01-15T17:30:00Z",
"canceled_at": null,
"etl_completed_at": "2024-01-15T18:00:00Z",
"duration_hms": "08:25:00",
"duration_humanize": "8 hours, 25 minutes",
"weaknesses_count": 23,
"weakness_types_count": 15,
"host_tabs_count": 150,
"credentials_count": 5,
"attack_paths_count": 45,
"impacts_headline_count": 12,
"nodezero_script_url": "https://download.yourorg.com/nodezero.sh",
"nodezero_ip": "10.0.0.100",
"runner_uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"runner_name": "runner-01",
"schedule_uuid": "efgh5678-efgh-5678-efgh-5678efgh5678",
"schedule_name": "Weekly Pentest Schedule",
"op_template_uuid": "9012ijkl-9012-ijkl-9012-ijkl9012ijkl",
"op_template_name": "Default Internal Template",
"tripwires_count": 8
}
OpTabsPage
fragment OpTabsPageFragment on OpTabsPage {
page_info {
page_num
page_size
}
op_tabs {
op_id
op_name
op_state
op_type
}
}
Examples may not include all available fields for a type.
{
"page_info": {
"page_num": 1,
"page_size": 10
},
"op_tabs": [
{
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_name": "Weekly Internal Pentest",
"op_state": "done",
"op_type": "NodeZero"
}
]
}
OpsPage
Description
A paginated list of Op objects. Returned by Query.ops_page.
fragment OpsPageFragment on OpsPage {
page_info {
page_num
page_size
}
ops {
...OpFragment
}
}
fragment OpFragment on Op {
op_id
op_type
op_name
op_state
portal_op_state
op_param_max_scope
scheduled_at
created_at
launched_at
completed_at
duration_hms
hosts_count
weaknesses_count
runner_uuid
runner_name
portal_url
}
Examples may not include all available fields for a type.
{
"page_info": {
"page_num": 1,
"page_size": 10
},
"ops": [
{
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_type": "NodeZero",
"op_name": "Weekly Internal Pentest",
"op_state": "done",
"portal_op_state": "done",
"op_param_max_scope": ["10.0.0.0/8"],
"scheduled_at": "2024-01-15T09:00:00Z",
"created_at": "2024-01-15T09:00:00Z",
"launched_at": "2024-01-15T09:05:00Z",
"completed_at": "2024-01-15T17:30:00Z",
"duration_hms": "08:25:00",
"hosts_count": 150,
"weaknesses_count": 23,
"runner_uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"runner_name": "runner-01",
"portal_url": "https://portal.yourorg.com/ops/1234abcd-1234-abcd-1234-abcd1234abcd"
},
{
"op_id": "5678efgh-5678-efgh-5678-efgh5678efgh",
"op_type": "ExternalAttack",
"op_name": "Monthly External Assessment",
"op_state": "done",
"portal_op_state": "done",
"op_param_max_scope": null,
"scheduled_at": "2024-01-08T14:00:00Z",
"created_at": "2024-01-08T14:00:00Z",
"launched_at": "2024-01-08T14:05:00Z",
"completed_at": "2024-01-08T18:15:00Z",
"duration_hms": "04:10:00",
"hosts_count": 45,
"weaknesses_count": 8,
"runner_uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"runner_name": "runner-01",
"portal_url": "https://portal.yourorg.com/ops/5678efgh-5678-efgh-5678-efgh5678efgh"
}
]
}
ScheduleOpOutput
Description
The output from a range of mutations that create ops.
fragment ScheduleOpOutputFragment on ScheduleOpOutput {
op {
op_id
op_type
op_name
op_state
portal_op_state
op_param_max_scope
scheduled_at
created_at
nodezero_script_url
runner_uuid
runner_name
portal_url
}
}
Examples may not include all available fields for a type.
{
"op": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_type": "NodeZero",
"op_name": "Weekly Internal Pentest",
"op_state": "scheduled",
"portal_op_state": "scheduled",
"op_param_max_scope": ["10.0.0.0/8"],
"scheduled_at": "2024-01-15T09:00:00Z",
"created_at": "2024-01-15T09:00:00Z",
"nodezero_script_url": "https://download.yourorg.com/nodezero.sh",
"runner_uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"runner_name": "runner-01",
"portal_url": "https://portal.yourorg.com/ops/1234abcd-1234-abcd-1234-abcd1234abcd"
}
}
UpdateOpInput
Description
Input for Mutation.update_op. Supports renaming, archiving, and deleting ops.
Fields
op_name - StringNotEmpty
is_deleted - Boolean
true, permanently deletes the op. Deleted ops are removed from the main views and most aggregations, and are no longer retrievable in Portal or via the API. is_archived - Boolean
true, archives the op. Archived ops are removed from the main views and most aggregations, but remain retrievable in Portal and via the API. # Example 1: Rename an op
mutation RenameOp($op_id: String!, $update_op_input: UpdateOpInput! = {
op_name: "Renamed Pentest"
}) {
update_op(op_id: $op_id, update_op_input: $update_op_input) {
op {
op_id
op_name
}
}
}
# Example 2: Archive an op
mutation ArchiveOp($op_id: String!, $update_op_input: UpdateOpInput! = {
is_archived: true
}) {
update_op(op_id: $op_id, update_op_input: $update_op_input) {
op {
op_id
op_name
}
}
}
# Example 3: Delete an op
mutation DeleteOp($op_id: String!, $update_op_input: UpdateOpInput! = {
is_deleted: true
}) {
update_op(op_id: $op_id, update_op_input: $update_op_input) {
op {
op_id
op_name
}
}
}
Examples may not include all available fields for a type.
UpdateOpOutput
Description
The output from Mutation.update_op.
fragment UpdateOpOutputFragment on UpdateOpOutput {
op {
op_id
op_type
op_name
op_state
portal_op_state
op_param_max_scope
scheduled_at
created_at
launched_at
completed_at
duration_hms
hosts_count
weaknesses_count
runner_uuid
runner_name
portal_url
}
}
Examples may not include all available fields for a type.
{
"op": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_type": "NodeZero",
"op_name": "Renamed Pentest",
"op_state": "done",
"portal_op_state": "done",
"op_param_max_scope": ["10.0.0.0/8"],
"scheduled_at": "2024-01-15T09:00:00Z",
"created_at": "2024-01-15T09:00:00Z",
"launched_at": "2024-01-15T09:05:00Z",
"completed_at": "2024-01-15T17:30:00Z",
"duration_hms": "08:25:00",
"hosts_count": 150,
"weaknesses_count": 23,
"runner_uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"runner_name": "runner-01",
"portal_url": "https://portal.yourorg.com/ops/1234abcd-1234-abcd-1234-abcd1234abcd"
}
}
Pentesting: Pentests
Access completed pentest results with high-level metrics and status information. Query pentests to retrieve summary data including discovered assets, findings counts, completion timestamps, and download comprehensive reports.
pentests_page
Description
Returns a paginated list of Pentest records in the current client account. By default, archived pentests are excluded unless the is_archived filter is explicitly set. Non-pentest operation types (such as external asset discovery) are always excluded.
Use the Pentest.op_id field to fetch full details about a specific pentest via Query.pentest.
Response
Returns a PentestsPage!
Arguments
page_input - PageInput
query PentestsPage($page_input: PageInput) {
pentests_page(page_input: $page_input) {
pentests {
...PentestFragment
}
}
}
fragment PentestFragment on Pentest {
op_id
op_type
name
state
user_name
scheduled_at
launched_at
completed_at
duration_s
impacts_count
attack_paths_count
weaknesses_count
hosts_count
credentials_count
}
Examples may not include all available fields for a type.
{
"data": {
"pentests_page": {
"pentests": [
{
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_type": "NodeZero",
"name": "Weekly Internal Pentest",
"state": "done",
"user_name": "admin@example.com",
"scheduled_at": "2024-01-15T09:00:00Z",
"launched_at": "2024-01-15T09:05:00Z",
"completed_at": "2024-01-15T17:30:00Z",
"duration_s": 30300,
"impacts_count": 12,
"attack_paths_count": 45,
"weaknesses_count": 23,
"hosts_count": 150,
"credentials_count": 5
},
{
"op_id": "5678efgh-5678-efgh-5678-efgh5678efgh",
"op_type": "ExternalAttack",
"name": "Monthly External Pentest",
"state": "done",
"user_name": "admin@example.com",
"scheduled_at": "2024-01-08T14:00:00Z",
"launched_at": "2024-01-08T14:02:00Z",
"completed_at": "2024-01-08T18:45:00Z",
"duration_s": 17100,
"impacts_count": 3,
"attack_paths_count": 8,
"weaknesses_count": 7,
"hosts_count": 25,
"credentials_count": 0
},
{
"op_id": "9012ijkl-9012-ijkl-9012-ijkl9012ijkl",
"op_type": "ADPasswordAudit",
"name": "AD Password Audit Q1",
"state": "done",
"user_name": "security@example.com",
"scheduled_at": "2024-01-01T08:00:00Z",
"launched_at": "2024-01-01T08:01:00Z",
"completed_at": "2024-01-01T10:30:00Z",
"duration_s": 9000,
"impacts_count": 0,
"attack_paths_count": 0,
"weaknesses_count": 45,
"hosts_count": 1,
"credentials_count": 120
}
]
}
}
}
python h3_gql.py ./pentests_page.graphql '{
"page_input": {
"page_size": 10
}
}'
Save the example request as ./pentests_page.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./pentests_page.graphql '{
"page_input": {
"page_size": 10
}
}'
Save the example request as ./pentests_page.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./pentests_page.graphql '{
"page_input": {
"page_size": 10
}
}'
Save the example request as ./pentests_page.graphql.
See h3-cli Examples for installation and usage.
pentests_count
Description
Returns the total number of Pentest records in the current client account, after applying any filters specified in page_input. By default, archived pentests are excluded unless the is_archived filter is explicitly set. Non-pentest operation types (such as external asset discovery) are always excluded from this count.
Response
Returns an Int!
Arguments
page_input - PageInput
query PentestsCount($page_input: PageInput) {
pentests_count(page_input: $page_input)
}
Examples may not include all available fields for a type.
{
"data": {
"pentests_count": 42
}
}
python h3_gql.py ./pentests_count.graphql '{
"page_input": {
"filter_by_inputs": [
{
"field_name": "op_type",
"values": [
"NodeZero"
]
}
]
}
}'
Save the example request as ./pentests_count.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./pentests_count.graphql '{
"page_input": {
"filter_by_inputs": [
{
"field_name": "op_type",
"values": [
"NodeZero"
]
}
]
}
}'
Save the example request as ./pentests_count.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./pentests_count.graphql '{
"page_input": {
"filter_by_inputs": [
{
"field_name": "op_type",
"values": [
"NodeZero"
]
}
]
}
}'
Save the example request as ./pentests_count.graphql.
See h3-cli Examples for installation and usage.
pentest
Description
Returns a single Pentest by its op_id. Returns null if the pentest does not exist or the caller does not have access to it.
Response
Returns a Pentest
Arguments
op_id - String!
query Pentest($op_id: String!) {
pentest(op_id: $op_id) {
...PentestFragment
}
}
fragment PentestFragment on Pentest {
op_id
op_type
name
state
user_name
client_name
min_scope
max_scope
exclude_scope
scheduled_at
launched_at
completed_at
duration_s
impacts_count
attack_paths_count
weakness_types_count
weaknesses_count
hosts_count
credentials_count
nodezero_script_url
nodezero_ip
}
Examples may not include all available fields for a type.
{
"data": {
"pentest": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_type": "NodeZero",
"name": "Weekly Internal Pentest",
"state": "done",
"user_name": "admin@example.com",
"client_name": "Acme Corp",
"min_scope": ["10.0.0.0/24"],
"max_scope": ["10.0.0.0/8"],
"exclude_scope": ["10.0.0.1"],
"scheduled_at": "2024-01-15T09:00:00Z",
"launched_at": "2024-01-15T09:05:00Z",
"completed_at": "2024-01-15T17:30:00Z",
"duration_s": 30300,
"impacts_count": 12,
"attack_paths_count": 45,
"weakness_types_count": 8,
"weaknesses_count": 23,
"hosts_count": 150,
"credentials_count": 5,
"nodezero_script_url": "https://download.yourorg.com/nodezero.sh",
"nodezero_ip": "10.0.0.100"
}
}
}
python h3_gql.py ./pentest.graphql '{
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./pentest.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./pentest.graphql '{
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./pentest.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./pentest.graphql '{
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./pentest.graphql.
See h3-cli Examples for installation and usage.
pentest_reports_zip_url
Description
Returns a pre-signed URL to download a zip archive containing all CSV and PDF reports for the specified pentest. The pentest must have completed post-processing before reports are available.
If the zip file already exists, the pre-signed URL is returned immediately. If the zip file has not yet been generated (e.g., for older pentests prior to Sep 2022), the system will initiate an asynchronous build job and return a [202] error indicating the request is being processed. An email with a download link will be sent to the requesting user when the zip is ready. Subsequent calls after the zip is built will return the pre-signed URL directly.
The zip archive contains the following CSV files and their corresponding schema types:
- certificates.csv: CertificateCSV
- credentials.csv: CredentialCSV
- data_stores.csv: ShareCSV
- database_repos.csv: DatabaseRepoCSV
- docker_registries.csv: DockerRegistryCSV
- external_domains.csv: ExternalDomainCSV
- file_shares.csv: FileShareCSV
- git_repos.csv: GitRepoCSV
- hosts.csv: HostCSV
- impacts.csv: ImpactCSV
- s3_buckets.csv: S3BucketCSV
- services.csv: ServiceCSV
- users.csv: UserCSV
- weaknesses.csv: WeaknessCSV
- websites.csv: WebShareCSV
Response
Returns a String
Arguments
input - OpInput!
query PentestReportsZipUrl($input: OpInput!) {
pentest_reports_zip_url(input: $input)
}
Examples may not include all available fields for a type.
{
"data": {
"pentest_reports_zip_url": "https://s3.amazonaws.com/reports/1234abcd-1234-abcd-1234-abcd1234abcd.zip?X-Amz-Expires=3600"
}
}
python h3_gql.py ./pentest_reports_zip_url.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}
}'
Save the example request as ./pentest_reports_zip_url.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./pentest_reports_zip_url.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}
}'
Save the example request as ./pentest_reports_zip_url.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./pentest_reports_zip_url.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}
}'
Save the example request as ./pentest_reports_zip_url.graphql.
See h3-cli Examples for installation and usage.
Pentest
Description
A Pentest represents an autonomous penetration test or security assessment conducted by NodeZero. During a pentest, NodeZero identifies misconfigurations, vulnerabilities, exposed credentials, and other security risks within a defined network scope.
The Pentest type is a specialized view of Op that excludes non-pentest operation types such as external asset discovery. Use Query.pentests_page to list pentests, Query.pentest to retrieve a single pentest by ID, or Mutation.create_op to schedule a new pentest.
The Pentest type encompasses the following OpType values:
- Internal Pentest (
NodeZero) -- Tests your internal network from a Docker host deployed within it. - External Pentest (
ExternalAttack) -- Tests your public-facing assets from the Horizon3.ai cloud. - AD Password Audit (
ADPasswordAudit) -- Audits Active Directory passwords for weak, breached, or reused credentials. - Phishing Campaign (
Phishing) -- Measures the downstream impact of phished credentials via an internal pentest. - AWS Pentest (
AWSPentest) -- Discovers vulnerabilities and misconfigurations in your AWS environment. - Azure Pentest (
AzurePentest) -- Assesses attack paths within your hybrid Azure Entra ID environment. - Kubernetes Pentest (
K8sPentest) -- Tests security controls and vulnerabilities within a Kubernetes cluster.
See OpType for configuration details on each type.
Fields
op_id - String!
Query.pentest to fetch full pentest details. op_type - OpType
name - String!
state - PortalOpState!
user_name - String!
client_name - String!
min_scope - [String]
max_scope (if defined). If auto-expand is disabled, only the IPs in min_scope are scanned. max_scope - [String]
exclude_scope - [String]
git_accounts - [GitAccount]
aws_account_ids - [AWSAccountId]
feature_flags - [FeatureFlag]
scheduled_at - Datetime!
launched_at - Datetime
completed_at - Datetime
canceled_at - Datetime
etl_completed_at - Datetime
duration_s - Int
launched_at to completed_at. For pentests still in progress, reflects the elapsed time since launch. impacts_count - Int
impact_paths_count - Int
attack_paths_count. attack_paths_count - Int
impact_paths_count. attack_paths_page - AttackPathsPage!
Returns a paginated list of AttackPath records for this pentest.
Each attack path describes a sequence of steps NodeZero took to achieve an impact. Use the AttackPath.uuid field to fetch additional details via Query.attack_path.
Arguments
page_input - PageInput
phished_impact_paths_count - Int!
phished_attack_paths_count. Relevant only for Phishing pentests. phished_attack_paths_count - Int!
phished_impact_paths_count. Relevant only for Phishing pentests. weakness_types_count - Int
weaknesses_page - WeaknessesPage!
Returns a paginated list of Weakness records for this pentest.
Use the Weakness.uuid field to fetch additional details about a specific weakness via Query.weakness.
Arguments
page_input - PageInput
hosts_count - Int
out_of_scope_hosts_count - Int
external_domains_count - Int
services_count - Int
credentials_count - Int
users_count - Int
cred_access_count - Int
data_stores_count - Int
websites_count - Int
data_resources_count - Long
nodezero_script_url - String
nodezero_ip - String
fragment PentestFragment on Pentest {
op_id
op_type
name
state
user_name
client_name
min_scope
max_scope
exclude_scope
scheduled_at
launched_at
completed_at
etl_completed_at
duration_s
impacts_count
attack_paths_count
weakness_types_count
weaknesses_count
hosts_count
out_of_scope_hosts_count
services_count
credentials_count
users_count
data_stores_count
websites_count
nodezero_script_url
nodezero_ip
}
Examples may not include all available fields for a type.
{
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_type": "NodeZero",
"name": "Weekly Internal Pentest",
"state": "done",
"user_name": "admin@example.com",
"client_name": "Acme Corp",
"min_scope": ["10.0.0.0/24"],
"max_scope": ["10.0.0.0/8"],
"exclude_scope": ["10.0.0.1"],
"scheduled_at": "2024-01-15T09:00:00Z",
"launched_at": "2024-01-15T09:05:00Z",
"completed_at": "2024-01-15T17:30:00Z",
"etl_completed_at": "2024-01-15T18:00:00Z",
"duration_s": 30300,
"impacts_count": 12,
"attack_paths_count": 45,
"weakness_types_count": 8,
"weaknesses_count": 23,
"hosts_count": 150,
"out_of_scope_hosts_count": 25,
"services_count": 320,
"credentials_count": 5,
"users_count": 85,
"data_stores_count": 12,
"websites_count": 3,
"nodezero_script_url": "https://download.yourorg.com/nodezero.sh",
"nodezero_ip": "10.0.0.100"
}
PentestsPage
Description
Contains a paginated list of Pentest records. Returned by Query.pentests_page.
Fields
page_info - PageInfo
pentests - [Pentest!]!
fragment PentestsPageFragment on PentestsPage {
pentests {
op_id
op_type
name
state
user_name
scheduled_at
completed_at
duration_s
impacts_count
weaknesses_count
hosts_count
}
}
Examples may not include all available fields for a type.
{
"pentests": [
{
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_type": "NodeZero",
"name": "Weekly Internal Pentest",
"state": "done",
"user_name": "admin@example.com",
"scheduled_at": "2024-01-15T09:00:00Z",
"completed_at": "2024-01-15T17:30:00Z",
"duration_s": 30300,
"impacts_count": 12,
"weaknesses_count": 23,
"hosts_count": 150
},
{
"op_id": "5678efgh-5678-efgh-5678-efgh5678efgh",
"op_type": "ExternalAttack",
"name": "Monthly External Pentest",
"state": "done",
"user_name": "admin@example.com",
"scheduled_at": "2024-01-08T14:00:00Z",
"completed_at": "2024-01-08T18:45:00Z",
"duration_s": 17100,
"impacts_count": 3,
"weaknesses_count": 7,
"hosts_count": 25
}
]
}
Pentesting: Impacts
Explore attack paths (also called impacts) that show how NodeZero compromised critical assets. View attack graphs visualizing the sequence of exploits, examine attack vectors with detailed technique information, and understand the complete kill chain from initial access to objective.
attack_paths_page
Description
Returns a paginated list of AttackPaths discovered during the specified pentest. Each AttackPath represents the sequence of steps NodeZero took to achieve a specific Impact.
Use the AttackPath.uuid field to fetch full details about a specific AttackPath via Query.attack_path.
Response
Returns an AttackPathsPage!
query AttackPathsPage($input: OpInput!, $page_input: PageInput) {
attack_paths_page(input: $input, page_input: $page_input) {
attack_paths {
...AttackPathFragment
}
}
}
fragment AttackPathFragment on AttackPath {
uuid
impact_type
impact_title
name
score
severity
op_id
weakness_refs
credential_refs
host_refs
time_to_finding_hms
created_at
affected_asset_text
ip
portal_url
}
Examples may not include all available fields for a type.
{
"data": {
"attack_paths_page": {
"attack_paths": [
{
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"impact_type": "RansomwareExposure",
"impact_title": "Ransomware Exposure",
"name": "Ransomware exposure via SMB signing weakness on 10.0.1.25",
"score": 9.5,
"severity": "CRITICAL",
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"weakness_refs": ["abcd1234-abcd-1234-abcd-1234abcd1234,SMBSigningNotRequired,10.0.1.25"],
"credential_refs": ["cred1234-cred-1234-cred-1234cred1234,admin,DC01.acme.local"],
"host_refs": ["host1234-host-1234-host-1234host1234,10.0.1.25"],
"time_to_finding_hms": "02:45:30",
"created_at": "2024-01-15T11:50:30Z",
"affected_asset_text": "DC01.acme.local (10.0.1.50)",
"ip": "10.0.1.50",
"portal_url": "https://portal.yourorg.com/attack-paths/abcd1234-abcd-1234-abcd-1234abcd1234"
},
{
"uuid": "efgh5678-efgh-5678-efgh-5678efgh5678",
"impact_type": "SensitiveDataExposure",
"impact_title": "Sensitive Data Exposure",
"name": "Sensitive data exposure via compromised credentials on FileServer01",
"score": 7.2,
"severity": "HIGH",
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"weakness_refs": [],
"credential_refs": ["cred5678-cred-5678-cred-5678cred5678,svc_backup,FileServer01"],
"host_refs": ["host5678-host-5678-host-5678host5678,10.0.2.100"],
"time_to_finding_hms": "03:12:15",
"created_at": "2024-01-15T12:17:15Z",
"affected_asset_text": "FileServer01 (10.0.2.100)",
"ip": "10.0.2.100",
"portal_url": "https://portal.yourorg.com/attack-paths/efgh5678-efgh-5678-efgh-5678efgh5678"
}
]
}
}
}
python h3_gql.py ./attack_paths_page.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
},
"page_input": {
"page_size": 10
}
}'
Save the example request as ./attack_paths_page.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./attack_paths_page.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
},
"page_input": {
"page_size": 10
}
}'
Save the example request as ./attack_paths_page.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./attack_paths_page.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
},
"page_input": {
"page_size": 10
}
}'
Save the example request as ./attack_paths_page.graphql.
See h3-cli Examples for installation and usage.
attack_paths_count
Description
Returns the total count of AttackPaths discovered during the specified pentest. Supports the same filtering options as Query.attack_paths_page via page_input.
Response
Returns an Int!
query AttackPathsCount($input: OpInput!, $page_input: PageInput) {
attack_paths_count(input: $input, page_input: $page_input)
}
Examples may not include all available fields for a type.
{
"data": {
"attack_paths_count": 45
}
}
python h3_gql.py ./attack_paths_count.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}
}'
Save the example request as ./attack_paths_count.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./attack_paths_count.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}
}'
Save the example request as ./attack_paths_count.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./attack_paths_count.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}
}'
Save the example request as ./attack_paths_count.graphql.
See h3-cli Examples for installation and usage.
attack_path
Description
Returns a single AttackPath by its UUID. The AttackPath includes the target ImpactType, risk score, and the Weaknesses, Credentials, and Hosts involved.
Response
Returns an AttackPath
Arguments
uuid - String!
query AttackPath($uuid: String!) {
attack_path(uuid: $uuid) {
...AttackPathFragment
}
}
fragment AttackPathFragment on AttackPath {
uuid
impact_type
impact_title
name
score
severity
op_id
weakness_refs
credential_refs
host_refs
time_to_finding_hms
created_at
affected_asset_text
ip
portal_url
}
Examples may not include all available fields for a type.
{
"data": {
"attack_path": {
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"impact_type": "RansomwareExposure",
"impact_title": "Ransomware Exposure",
"name": "Ransomware exposure via SMB signing weakness on 10.0.1.25",
"score": 9.5,
"severity": "CRITICAL",
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"weakness_refs": ["abcd1234-abcd-1234-abcd-1234abcd1234,SMBSigningNotRequired,10.0.1.25"],
"credential_refs": ["cred1234-cred-1234-cred-1234cred1234,admin,DC01.acme.local"],
"host_refs": ["host1234-host-1234-host-1234host1234,10.0.1.25"],
"time_to_finding_hms": "02:45:30",
"created_at": "2024-01-15T11:50:30Z",
"affected_asset_text": "DC01.acme.local (10.0.1.50)",
"ip": "10.0.1.50",
"portal_url": "https://portal.yourorg.com/attack-paths/abcd1234-abcd-1234-abcd-1234abcd1234"
}
}
}
python h3_gql.py ./attack_path.graphql '{
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234"
}'
Save the example request as ./attack_path.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./attack_path.graphql '{
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234"
}'
Save the example request as ./attack_path.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./attack_path.graphql '{
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234"
}'
Save the example request as ./attack_path.graphql.
See h3-cli Examples for installation and usage.
attack_paths_csv_url
Description
Returns a temporary presigned URL to a CSV file containing all AttackPaths discovered during the specified pentest.
The CSV format is documented under ImpactCSV.
Response
Returns a String
Arguments
input - OpInput!
query AttackPathsCsvUrl($input: OpInput!) {
attack_paths_csv_url(input: $input)
}
Examples may not include all available fields for a type.
{
"data": {
"attack_paths_csv_url": "https://s3.amazonaws.com/attack-paths/1234abcd-1234-abcd-1234-abcd1234abcd.csv?X-Amz-Expires=3600"
}
}
python h3_gql.py ./attack_paths_csv_url.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}
}'
Save the example request as ./attack_paths_csv_url.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./attack_paths_csv_url.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}
}'
Save the example request as ./attack_paths_csv_url.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./attack_paths_csv_url.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}
}'
Save the example request as ./attack_paths_csv_url.graphql.
See h3-cli Examples for installation and usage.
AttackPath
Description
An AttackPath represents the sequence of steps NodeZero took to achieve a specific Impact during a pentest. Each AttackPath links to a target Impact and includes the exploited Weaknesses, compromised Credentials, and traversed Hosts that enabled NodeZero to reach that Impact.
Use Query.attack_paths_page to retrieve AttackPaths for a given pentest, or Query.attack_path to fetch a single AttackPath by its UUID.
The attack_vector field provides the full step-by-step AttackVector graph detailing how NodeZero navigated through your environment to achieve the Impact.
Fields
uuid - String!
impact_type - ImpactType!
impact_title - String!
impact_description - String!
name - String!
attack_path_title - String!
name. score - Float
context_score_description_md - String
context_score_description - String
attack_vector - AttackVector
algorithm argument to select the graph version (e.g., v3 for chronological layers, v4 for a consolidated view). Arguments
algorithm - AttackVectorAlgorithmInput
op_id - String!
weakness_refs - [String]
weaknesses - [Weakness!]
credential_refs - [String]
{credential_uuid},{user_or_role_name},{asset_name}. credentials - [Credential!]
host_refs - [String]
{host_uuid},{ip}. time_to_finding_hms - String
HH:MM:SS. time_to_finding_s - Int
created_at - Datetime
target_entity_text - String
target_entity_short_text - String
affected_asset_text - String
affected_asset_short_text - String
affected_credential - Credential
affected_data_store - DataStore
proofs - [Proof]
portal_url - String
business_risks - [String]
fragment AttackPathFragment on AttackPath {
uuid
impact_type
impact_title
impact_description
name
attack_path_title
score
severity
context_score_description_md
context_score_description
op_id
weakness_refs
credential_refs
host_refs
time_to_finding_hms
time_to_finding_s
created_at
target_entity_text
target_entity_short_text
affected_asset_text
affected_asset_short_text
ip
host_name
host_text
proofs_count
portal_url
business_risks
}
Examples may not include all available fields for a type.
{
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"impact_type": "RansomwareExposure",
"impact_title": "Ransomware Exposure",
"impact_description": "An attacker could deploy ransomware on this host.",
"name": "Ransomware exposure via SMB signing weakness on 10.0.1.25",
"attack_path_title": "Ransomware exposure via SMB signing weakness on 10.0.1.25",
"score": 9.5,
"severity": "CRITICAL",
"context_score_description_md": "NodeZero exploited **SMB Signing Not Required** on 10.0.1.25 to gain access to DC01.acme.local.",
"context_score_description": "NodeZero exploited SMB Signing Not Required on 10.0.1.25 to gain access to DC01.acme.local.",
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"weakness_refs": ["abcd1234-abcd-1234-abcd-1234abcd1234,SMBSigningNotRequired,10.0.1.25"],
"credential_refs": ["cred1234-cred-1234-cred-1234cred1234,admin,DC01.acme.local"],
"host_refs": ["host1234-host-1234-host-1234host1234,10.0.1.25"],
"time_to_finding_hms": "02:45:30",
"time_to_finding_s": 9930,
"created_at": "2024-01-15T11:50:30Z",
"target_entity_text": "SMB Signing Not Required on 10.0.1.25",
"target_entity_short_text": "SMBSigningNotRequired on 10.0.1.25",
"affected_asset_text": "DC01.acme.local (10.0.1.50)",
"affected_asset_short_text": "DC01.acme.local",
"ip": "10.0.1.50",
"host_name": "DC01.acme.local",
"host_text": "DC01.acme.local (10.0.1.50)",
"proofs_count": 2,
"portal_url": "https://portal.yourorg.com/attack-paths/abcd1234-abcd-1234-abcd-1234abcd1234",
"business_risks": ["Data breach", "Operational disruption"]
}
AttackVector
Description
An AttackVector is a directed acyclic graph (DAG) of Nodes and Edges that represents the step-by-step attack path NodeZero took to reach a target entity.
The full graph structure can be retrieved via the attack_graph field as an AttackGraph.
NodeZero tracks AttackVectors for the following entity types:
- Impacts (via AttackPath)
- Weaknesses
- Credentials
- DataStores
- Relay events
- Privilege escalation events
Each Node in the attack graph has a found_by_module_instance field, which references the ModuleInstance used by NodeZero during that step of the attack path. The ModuleInstance can be used to retrieve further details about that step, including:
- Information about the module that was used (
ModuleInstance.module_meta) - How the module maps to the MITRE ATT&CK framework (
ModuleInstance.module_meta.mitre_mappings) - The commands it ran during the pentest (
ModuleInstance.action_logs)
When summarizing an AttackVector, it can be useful to break it down by:
- The hosts involved (
host_nodes) - The credentials used (
credential_nodes) - The weaknesses exploited (
weakness_nodes)
The complexity of an attack path is related to its length (number of nodes) and the types of nodes involved. The more credentials and weaknesses involved, the more complex the path. This complexity is relevant when assessing the likelihood that a real-world attacker could replicate the attack path.
Fields
uuid - String!
target_node - Node!
algorithm - AttackVectorAlgorithm!
attack_graph - AttackGraph
op_id - String!
credentials_count - Int
credential_nodes - [Node]
weaknesses_count - Int
weakness_nodes - [Node]
host_nodes - [Node]
narrative - [Node]
has_phished_cred - Boolean
true if this attack vector includes credentials obtained through a phishing simulation. has_injected_cred - Boolean
true if this attack vector includes credentials that were injected as inputs to the pentest. fragment AttackVectorFragment on AttackVector {
uuid
algorithm
target_node {
uuid
label_line1
label_line2
score
severity
}
total_score
max_score
attack_graph {
nodes {
uuid
label_line1
score
severity
}
edges {
from_uuid
to_uuid
}
}
op_id
nodes_count
credentials_count
weaknesses_count
hosts_count
narrative {
uuid
label_line1
description
icon_label
}
has_phished_cred
has_injected_cred
}
Examples may not include all available fields for a type.
{
"uuid": "av-1234abcd-1234-abcd-1234-abcd1234abcd",
"algorithm": "FULL",
"target_node": {
"uuid": "node-target-1234",
"label_line1": "Ransomware Exposure",
"label_line2": "DC01.acme.local",
"score": 9.5,
"severity": "CRITICAL"
},
"total_score": 22.3,
"max_score": 9.5,
"attack_graph": {
"nodes": [
{
"uuid": "node-0001",
"label_line1": "Found Host",
"score": 0.0,
"severity": "INFO"
},
{
"uuid": "node-0002",
"label_line1": "Exploited Weakness",
"score": 6.5,
"severity": "MEDIUM"
}
],
"edges": [
{
"from_uuid": "node-0001",
"to_uuid": "node-0002"
}
]
},
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"nodes_count": 5,
"credentials_count": 1,
"weaknesses_count": 2,
"hosts_count": 3,
"narrative": [
{
"uuid": "node-0001",
"label_line1": "Found Host",
"description": "NodeZero discovered host 10.0.1.25.",
"icon_label": "Found Host"
},
{
"uuid": "node-0002",
"label_line1": "Exploited Weakness",
"description": "NodeZero exploited SMB Signing Not Required on 10.0.1.25.",
"icon_label": "Exploited Weakness"
}
],
"has_phished_cred": false,
"has_injected_cred": false
}
AttackGraph
Description
An AttackGraph is the directed acyclic graph (DAG) structure within an AttackVector, comprising the set of Nodes and Edges that represent the attack path.
The Nodes represent the hosts, services, Weaknesses, Credentials, and other entities that NodeZero discovered and exploited as part of the attack path.
The Edges define the sequence of steps from one node to the next that NodeZero took along the path.
The attack path can be organized into layers, where each layer represents a distinct time step. Each node is associated with a layer via Node.layer_label. All nodes in the same layer were discovered or exploited at the same time. The layers can be used to render the graph as a timeline showing the progression of the attack.
Fields
nodes - [Node]
fragment AttackGraphFragment on AttackGraph {
nodes {
uuid
label_line1
label_line2
label_line3
icon_label
score
severity
description
time_to_finding
}
edges {
from_uuid
to_uuid
}
}
Examples may not include all available fields for a type.
{
"nodes": [
{
"uuid": "node-0001",
"label_line1": "Found Host",
"label_line2": "10.0.1.25",
"label_line3": null,
"icon_label": "Found Host",
"score": 0.0,
"severity": "INFO",
"description": "NodeZero discovered host 10.0.1.25.",
"time_to_finding": "00:15:30"
},
{
"uuid": "node-0002",
"label_line1": "Exploited Weakness",
"label_line2": "SMB Signing Not Required",
"label_line3": "10.0.1.25",
"icon_label": "Exploited Weakness",
"score": 6.5,
"severity": "MEDIUM",
"description": "NodeZero exploited SMB Signing Not Required on 10.0.1.25.",
"time_to_finding": "01:23:45"
}
],
"edges": [
{
"from_uuid": "node-0001",
"to_uuid": "node-0002"
}
]
}
Node
Description
A node in an AttackVector graph.
A Node wraps attack-vector context around a target entity such as a Host, Weakness, Credential, or service that NodeZero discovered or exploited during its attack path.
The icon_label, label_line1, label_line2, and label_line3 fields are useful for rendering the node in a visual representation of the attack graph.
Fields
uuid - String!
attack_vector_node_uuid - String!
found_by_module_meta - ModuleMeta
found_by_module_instance - ModuleInstance
score - Float
proofs - [Proof]
time_to_finding - String
HH:MM:SS. label_line1 - String
v3 and v4 attack vector renderings. label_line2 - String
v3 and v4 attack vector renderings. label_line3 - String
v3 and v4 attack vector renderings. icon_label - String
Found Host, Exploited Weakness). description - String
subflow_nodes - [Node]
v3 and v4 attack vector visualizations. weakness - Weakness
credential - Credential
fragment NodeFragment on Node {
uuid
attack_vector_node_uuid
score
severity
label_line1
label_line2
label_line3
icon_label
description
time_to_finding
found_by_module_meta {
id
name
}
proofs {
uuid
}
subflow_nodes {
uuid
label_line1
score
}
}
Examples may not include all available fields for a type.
{
"uuid": "node-0002",
"attack_vector_node_uuid": "avn-0002-1234",
"score": 6.5,
"severity": "MEDIUM",
"label_line1": "Exploited Weakness",
"label_line2": "SMB Signing Not Required",
"label_line3": "10.0.1.25",
"icon_label": "Exploited Weakness",
"description": "NodeZero exploited SMB Signing Not Required on 10.0.1.25.",
"time_to_finding": "01:23:45",
"found_by_module_meta": {
"id": "smb_signing_check",
"name": "SMB Signing Check"
},
"proofs": [
{
"uuid": "proof-0001-1234"
}
],
"subflow_nodes": []
}
Edge
Description
An edge in an AttackVector graph. Connects two Nodes in the directed acyclic graph (DAG): the source (from) node and the target (to) node. Each edge represents a single step in the attack path that NodeZero traversed.
Fields
from_uuid - String!
Node.uuid in the AttackGraph. to_uuid - String!
Node.uuid in the AttackGraph. fragment EdgeFragment on Edge {
from_uuid
to_uuid
}
Examples may not include all available fields for a type.
{
"from_uuid": "node-0001",
"to_uuid": "node-0002"
}
AttackPathsPage
Description
A paginated list of AttackPath records. Returned by Query.attack_paths_page.
Fields
page_info - PageInfo
attack_paths - [AttackPath!]!
fragment AttackPathsPageFragment on AttackPathsPage {
page_info {
page_num
page_size
}
attack_paths {
uuid
impact_type
impact_title
name
score
severity
op_id
portal_url
}
}
Examples may not include all available fields for a type.
{
"page_info": {
"page_num": 1,
"page_size": 10
},
"attack_paths": [
{
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"impact_type": "RansomwareExposure",
"impact_title": "Ransomware Exposure",
"name": "Ransomware exposure via SMB signing weakness on 10.0.1.25",
"score": 9.5,
"severity": "CRITICAL",
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"portal_url": "https://portal.yourorg.com/attack-paths/abcd1234-abcd-1234-abcd-1234abcd1234"
},
{
"uuid": "efgh5678-efgh-5678-efgh-5678efgh5678",
"impact_type": "SensitiveDataExposure",
"impact_title": "Sensitive Data Exposure",
"name": "Sensitive data exposure via compromised credentials on FileServer01",
"score": 7.2,
"severity": "HIGH",
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"portal_url": "https://portal.yourorg.com/attack-paths/efgh5678-efgh-5678-efgh-5678efgh5678"
}
]
}
AttackVectorAlgorithm
Description
The available algorithms for generating AttackVector graphs. Each algorithm produces a different level of detail and graph structure.
Values
POC
v1. The base algorithm that produces the most detailed graph. No nodes are pruned or consolidated. v2
v3
A streamlined version of the POC graph with the following modifications:
- Impact and proof nodes are removed and surfaced as labels on their connected nodes.
- AWS Connection nodes are removed.
- The graph is structured chronologically by timestep "layers". All nodes created at the same time are grouped into the same layer. The first node in each layer remains in the main graph; subsequent nodes are stored as
subflow_nodesof that first node. This structure facilitates rendering the graph on a timeline, as it appears in the Portal.
v4
v3 graph, providing the most compact representation of the attack path. Example
"POC"
AttackVectorAlgorithmInput
Description
The available algorithms for generating AttackVector graphs, as an input type. Accepts the same values as AttackVectorAlgorithm.
Values
POC
v1. The base algorithm that produces the most detailed graph. No nodes are pruned or consolidated. v2
v3
A streamlined version of the POC graph with the following modifications:
- Impact and proof nodes are removed and surfaced as labels on their connected nodes.
- AWS Connection nodes are removed.
- The graph is structured chronologically by "layers". All nodes created at the same time are grouped into the same layer. The first node in each layer remains in the main graph; subsequent nodes are stored as
subflow_nodesof that first node. This structure facilitates rendering the graph on a timeline, as it appears in the Portal.
v4
v3 graph, providing the most compact representation of the attack path. Example
"POC"
ImpactType
Description
The categories of business impact that NodeZero can demonstrate during a pentest. Each AttackPath targets one of these impact types, representing the real-world consequence that NodeZero was able to achieve by chaining together exploited Weaknesses and compromised Credentials.
Values
AWSUserRoleCompromise
AWSAccountCompromise
AzureADUserCompromise
MicrosoftEntraUserCompromise
MicrosoftEntraAccountCompromise
MicrosoftEntraFullTenantCompromise
BrandCompromise
BusinessEmailCompromise
CloudCompromise
CloudServiceCompromise
CriticalInfrastructureCompromise
DomainCompromise
DomainUserCompromise
HostCompromise
PerimeterBreach
RansomwareExposure
SensitiveDataExposure
ThirdPartySaaSUserCompromise
KubernetesIdentityCompromise
KubernetesClusterCompromise
WebSessionCompromise
WebApplicationUserCompromise
Example
"AWSUserRoleCompromise"
Pentesting: Weaknesses
Query discovered vulnerabilities and security weaknesses including CVE details, severity ratings, affected assets, threat actor intelligence, and remediation guidance. Weaknesses represent exploitable security flaws found during pentesting.
weaknesses_page
Description
Returns a paginated list of Weaknesses discovered during the specified pentest.
Each Weakness record represents a specific vulnerability found on a specific asset -- there is one record per unique vuln_id + affected asset combination.
Use the Weakness.uuid field to fetch full details about a specific Weakness via Query.weakness.
Response
Returns a WeaknessesPage!
query WeaknessesPage($input: OpInput, $page_input: PageInput) {
weaknesses_page(input: $input, page_input: $page_input) {
weaknesses {
...WeaknessFragment
}
}
}
fragment WeaknessFragment on Weakness {
uuid
vuln_id
vuln_name
vuln_short_name
vuln_category
vuln_cisa_kev
op_id
ip
has_proof
score
severity
base_score
context_score
time_to_finding_hms
affected_asset_display_name
attack_paths_count
portal_url
weakness_ref
}
Examples may not include all available fields for a type.
{
"data": {
"weaknesses_page": {
"weaknesses": [
{
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"vuln_id": "h3-2024-0001",
"vuln_name": "SMB Signing Not Required",
"vuln_short_name": "SMBSigningNotRequired",
"vuln_category": "SECURITY_MISCONFIGURATION",
"vuln_cisa_kev": false,
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"ip": "10.0.1.25",
"has_proof": true,
"score": 6.5,
"severity": "MEDIUM",
"base_score": 5.0,
"context_score": 6.5,
"time_to_finding_hms": "01:23:45",
"affected_asset_display_name": "10.0.1.25",
"attack_paths_count": 3,
"portal_url": "https://portal.yourorg.com/weaknesses/abcd1234-abcd-1234-abcd-1234abcd1234",
"weakness_ref": "abcd1234-abcd-1234-abcd-1234abcd1234,SMBSigningNotRequired,10.0.1.25"
},
{
"uuid": "efgh5678-efgh-5678-efgh-5678efgh5678",
"vuln_id": "CVE-2021-34527",
"vuln_name": "PrintNightmare - Windows Print Spooler RCE",
"vuln_short_name": "PrintNightmare",
"vuln_category": "VULNERABILITY",
"vuln_cisa_kev": true,
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"ip": "10.0.1.50",
"has_proof": true,
"score": 9.8,
"severity": "CRITICAL",
"base_score": 9.8,
"context_score": null,
"time_to_finding_hms": "02:10:30",
"affected_asset_display_name": "DC01.acme.local (10.0.1.50)",
"attack_paths_count": 5,
"portal_url": "https://portal.yourorg.com/weaknesses/efgh5678-efgh-5678-efgh-5678efgh5678",
"weakness_ref": "efgh5678-efgh-5678-efgh-5678efgh5678,PrintNightmare,DC01.acme.local"
}
]
}
}
}
python h3_gql.py ./weaknesses_page.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
},
"page_input": {
"page_size": 10
}
}'
Save the example request as ./weaknesses_page.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./weaknesses_page.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
},
"page_input": {
"page_size": 10
}
}'
Save the example request as ./weaknesses_page.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./weaknesses_page.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
},
"page_input": {
"page_size": 10
}
}'
Save the example request as ./weaknesses_page.graphql.
See h3-cli Examples for installation and usage.
weaknesses_count
Description
Returns the total count of Weaknesses discovered during the specified pentest. Supports the same filtering options as Query.weaknesses_page via page_input.
Response
Returns an Int!
query WeaknessesCount($input: OpInput, $page_input: PageInput) {
weaknesses_count(input: $input, page_input: $page_input)
}
Examples may not include all available fields for a type.
{
"data": {
"weaknesses_count": 23
}
}
python h3_gql.py ./weaknesses_count.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}
}'
Save the example request as ./weaknesses_count.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./weaknesses_count.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}
}'
Save the example request as ./weaknesses_count.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./weaknesses_count.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}
}'
Save the example request as ./weaknesses_count.graphql.
See h3-cli Examples for installation and usage.
weakness
Description
Returns a single Weakness by its UUID, including its risk scores, affected asset, vulnerability details, and related AttackPaths.
Response
Returns a Weakness
Arguments
uuid - String!
query Weakness($uuid: String!) {
weakness(uuid: $uuid) {
...WeaknessFragment
}
}
fragment WeaknessFragment on Weakness {
uuid
vuln_id
vuln_name
vuln_short_name
vuln_category
vuln_cisa_kev
op_id
ip
has_proof
score
severity
base_score
context_score
time_to_finding_hms
affected_asset_display_name
attack_paths_count
portal_url
weakness_ref
}
Examples may not include all available fields for a type.
{
"data": {
"weakness": {
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"vuln_id": "h3-2024-0001",
"vuln_name": "SMB Signing Not Required",
"vuln_short_name": "SMBSigningNotRequired",
"vuln_category": "SECURITY_MISCONFIGURATION",
"vuln_cisa_kev": false,
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"ip": "10.0.1.25",
"has_proof": true,
"score": 6.5,
"severity": "MEDIUM",
"base_score": 5.0,
"context_score": 6.5,
"time_to_finding_hms": "01:23:45",
"affected_asset_display_name": "10.0.1.25",
"attack_paths_count": 3,
"portal_url": "https://portal.yourorg.com/weaknesses/abcd1234-abcd-1234-abcd-1234abcd1234",
"weakness_ref": "abcd1234-abcd-1234-abcd-1234abcd1234,SMBSigningNotRequired,10.0.1.25"
}
}
}
python h3_gql.py ./weakness.graphql '{
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234"
}'
Save the example request as ./weakness.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./weakness.graphql '{
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234"
}'
Save the example request as ./weakness.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./weakness.graphql '{
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234"
}'
Save the example request as ./weakness.graphql.
See h3-cli Examples for installation and usage.
weaknesses_csv_url
Description
Returns a temporary presigned URL to a CSV file containing all Weaknesses discovered during the specified pentest.
Each row in the CSV represents one Weakness (one vulnerability on one asset). The CSV format is documented under WeaknessCSV.
Response
Returns a String
Arguments
input - OpInput!
query WeaknessesCsvUrl($input: OpInput!) {
weaknesses_csv_url(input: $input)
}
Examples may not include all available fields for a type.
{
"data": {
"weaknesses_csv_url": "https://s3.amazonaws.com/weaknesses/1234abcd-1234-abcd-1234-abcd1234abcd.csv?X-Amz-Expires=3600"
}
}
python h3_gql.py ./weaknesses_csv_url.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}
}'
Save the example request as ./weaknesses_csv_url.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./weaknesses_csv_url.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}
}'
Save the example request as ./weaknesses_csv_url.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./weaknesses_csv_url.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}
}'
Save the example request as ./weaknesses_csv_url.graphql.
See h3-cli Examples for installation and usage.
Weakness
Description
A Weakness represents a specific vulnerability found on a specific asset by NodeZero during a pentest. One Weakness record is created for each unique combination of vulnerability ID (vuln_id) + affected asset + pentest (op_id).
The vuln_id field identifies the vulnerability type (e.g., a CVE or an H3-defined vulnerability), while the Vuln field provides static catalog information about that vulnerability, including its name, description, recommended mitigations, and CISA KEV status.
Weaknesses have three levels of risk scoring:
base_score: The statically assigned risk score for the vulnerability type.context_score: An environment-adjusted score that accounts for downstream impacts this weakness enables.score: The effective risk score (equalscontext_scoreif set, otherwisebase_score).
Use Query.weaknesses_page to list weaknesses for a pentest, or Query.weakness to fetch a single weakness by UUID.
To track how a weakness evolves across pentests, see WeaknessSeries.
Fields
uuid - String!
created_at - Datetime!
vuln_id - String!
vuln - Vuln!
vuln_aliases - [String!]
vuln_category - VulnCategory
vuln_name - String
vuln_short_name - String
vuln_cisa_kev - Boolean
true if the vulnerability is listed in the CISA Known Exploited Vulnerabilities (KEV) catalog. vuln_known_ransomware_campaign_use - Boolean
true if the vulnerability is known to be used in ransomware campaigns, according to CISA. op_id - String!
ip - String
has_proof - Boolean
true if NodeZero captured proof of successful exploitation for this Weakness. See also the proofs field. proof_failure_code - String
exploit_failed, not_configured, no_exploit, timeout. proof_failure_reason - String
score - Float
context_score if available, otherwise base_score. Higher values indicate greater risk. base_score - Float
context_score - Float
base_score when the weakness contributes to significant downstream impacts. context_score_description_md - String
context_score_description - String
time_to_finding_hms - String
HH:MM:SS. time_to_finding_s - Int
affected_asset_display_name - String
affected_asset_short_name - String
downstream_impact_types - [ImpactType!]
DomainCompromise, RansomwareExposure). attack_paths_count - Int!
Arguments
page_input - PageInput
attack_paths_page - AttackPathsPage!
Arguments
page_input - PageInput
proofs - [Proof]
diff_status - DiffStatus
Populated only when performing a diff between pentests, for example via Query.weaknesses_diff_page.
If a weakness was present in the first pentest but not the second, its diff_status will be REMOVED.
If a weakness was present in the second pentest but not the first, its diff_status will be ADDED.
mitre_mappings - [MitreMapping!]
affected_credentials_count - Int!
Arguments
page_input - PageInput
affected_credentials_page - CredentialsPage!
Arguments
page_input - PageInput
affected_application - Application
affected_cloud_resource - CloudResource
affected_external_domain - ExternalDomain
affected_interesting_resource - InterestingResource
affected_ldap_domain - LDAPDomain
portal_url - String
weakness_ref - String
{weakness_uuid},{vuln_short_name},{affected_asset_short_name}. Used for filtering in various APIs, such as Query.attack_paths_page. See also AttackPath.weakness_refs. fragment WeaknessFragment on Weakness {
uuid
created_at
vuln_id
vuln_aliases
vuln_category
vuln_name
vuln_short_name
vuln_cisa_kev
vuln_known_ransomware_campaign_use
op_id
ip
has_proof
proof_failure_code
proof_failure_reason
score
severity
base_score
base_severity
context_score
context_severity
context_score_description_md
context_score_description
time_to_finding_hms
time_to_finding_s
affected_asset_display_name
affected_asset_short_name
downstream_impact_types
attack_paths_count
diff_status
affected_credentials_count
portal_url
weakness_ref
}
Examples may not include all available fields for a type.
{
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"created_at": "2024-01-15T10:28:45Z",
"vuln_id": "h3-2024-0001",
"vuln_aliases": ["CVE-2020-1472"],
"vuln_category": "SECURITY_MISCONFIGURATION",
"vuln_name": "SMB Signing Not Required",
"vuln_short_name": "SMBSigningNotRequired",
"vuln_cisa_kev": false,
"vuln_known_ransomware_campaign_use": false,
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"ip": "10.0.1.25",
"has_proof": true,
"proof_failure_code": null,
"proof_failure_reason": null,
"score": 6.5,
"severity": "MEDIUM",
"base_score": 5.0,
"base_severity": "MEDIUM",
"context_score": 6.5,
"context_severity": "MEDIUM",
"context_score_description_md": "This weakness led to **3 downstream impacts**.",
"context_score_description": "This weakness led to 3 downstream impacts.",
"time_to_finding_hms": "01:23:45",
"time_to_finding_s": 5025,
"affected_asset_display_name": "10.0.1.25",
"affected_asset_short_name": "10.0.1.25",
"downstream_impact_types": ["RansomwareExposure", "SensitiveDataExposure"],
"attack_paths_count": 3,
"diff_status": null,
"affected_credentials_count": 1,
"portal_url": "https://portal.yourorg.com/weaknesses/abcd1234-abcd-1234-abcd-1234abcd1234",
"weakness_ref": "abcd1234-abcd-1234-abcd-1234abcd1234,SMBSigningNotRequired,10.0.1.25"
}
Severity
Description
Severity levels derived from a finding's cyber risk score (0-10 scale). Used throughout the API to classify the risk level of Weaknesses, AttackPaths, and Nodes.
score <= 0 : INFO
0 < score < 4.0: LOW
4.0 <= score < 7.0: MEDIUM
7.0 <= score < 9.0: HIGH
9.0 <= score : CRITICAL
Values
INFO
LOW
MEDIUM
HIGH
CRITICAL
Example
"INFO"
ThreatActor
Description
Information about a known threat actor group that is associated with specific vulnerabilities. Threat actors are linked to Vulns via the Vuln.threat_actors field, enabling you to assess whether vulnerabilities in your environment are being actively targeted by known adversaries.
Fields
name - String!
short_description - String
description - String!
origin_country - String!
remediation_urgency - String!
aliases - [String!]!
references - [ThreatActorReference!]!
fragment ThreatActorFragment on ThreatActor {
name
short_description
description
origin_country
remediation_urgency
aliases
references {
display_name
url
}
}
Examples may not include all available fields for a type.
{
"name": "APT28",
"short_description": "Russian state-sponsored cyber espionage group.",
"description": "APT28, also known as Fancy Bear, is a Russian military intelligence cyber unit associated with the GRU. The group has been active since at least 2004 and targets government, military, and security organizations.",
"origin_country": "Russia",
"remediation_urgency": "Immediate patching recommended due to active exploitation by this threat actor.",
"aliases": ["Fancy Bear", "Sofacy", "Pawn Storm", "STRONTIUM"],
"references": [
{
"display_name": "MITRE ATT&CK - APT28",
"url": "https://attack.mitre.org/groups/G0007/"
}
]
}
ThreatActorReference
Description
A reference to external documentation or resources related to a ThreatActor.
fragment ThreatActorReferenceFragment on ThreatActorReference {
display_name
url
}
Examples may not include all available fields for a type.
{
"display_name": "MITRE ATT&CK - APT28",
"url": "https://attack.mitre.org/groups/G0007/"
}
Vuln
Description
Static catalog information about a vulnerability type. Each Weakness references a Vuln via the vuln_id field to provide details about the vulnerability, including its name, description, base risk score, recommended mitigations, CISA KEV status, and associated ThreatActors.
Fields
id - String!
CVE-2021-44228 or an H3-defined ID). base_score - Float!
name - String!
short_name - String!
description - String!
impact - String
category - VulnCategory!
aliases - [String]!
mitigations - [VulnMitigation]!
references - [VulnReference]!
impact_categories - [VulnImpactCategory]!
one_click_verify - Boolean!
true if this Vuln supports one-click verification, allowing you to quickly re-test whether the vulnerability has been remediated. Most Vulns are one-click verifiable. Vulns that require complex multi-step attack paths may not be one-click verifiable. cisa_kev - Boolean!
true if this Vuln is listed in the CISA Known Exploited Vulnerabilities (KEV) catalog, indicating active exploitation in the wild. known_ransomware_campaign_use - Boolean
true if this Vuln is known to be used in ransomware campaigns, according to CISA. threat_actors - [ThreatActor!]!
fragment VulnFragment on Vuln {
id
name
short_name
description
base_score
base_severity
category
impact
aliases
mitigations {
description
}
references {
name
url
}
impact_categories
one_click_verify
cisa_kev
known_ransomware_campaign_use
threat_actors {
name
short_description
}
}
Examples may not include all available fields for a type.
{
"id": "h3-2024-0001",
"name": "SMB Signing Not Required",
"short_name": "SMBSigningNotRequired",
"description": "SMB signing is not required on the target host, allowing potential man-in-the-middle attacks.",
"base_score": 5.0,
"base_severity": "MEDIUM",
"category": "SECURITY_MISCONFIGURATION",
"impact": "An attacker could intercept and modify SMB traffic between the client and server.",
"aliases": [],
"mitigations": [
{
"description": "Enable SMB signing on all hosts via Group Policy."
}
],
"references": [
{
"name": "Microsoft - Overview of SMB Signing",
"url": "https://learn.microsoft.com/en-us/troubleshoot/windows-server/networking/overview-server-message-block-signing"
}
],
"impact_categories": ["UNAUTHORIZED_ACCESS"],
"one_click_verify": true,
"cisa_kev": false,
"known_ransomware_campaign_use": false,
"threat_actors": []
}
VulnCategory
Description
High-level categories for classifying vulnerabilities.
Values
SECURITY_MISCONFIGURATION
VULNERABILITY
SECURITY_CONTROLS
CREDENTIALS
Example
"SECURITY_MISCONFIGURATION"
VulnImpactCategory
Description
Categories describing the potential impact if a vulnerability is exploited.
Values
FILE_UPLOAD
DENIAL_OF_SERVICE
REMOTE_CODE_EXECUTION
INFORMATION_DISCLOSURE
PRIVILEGE_ESCALATION
DEFACEMENT
IMPERSONATION
UNAUTHORIZED_ACCESS
Example
"FILE_UPLOAD"
VulnMitigation
Description
A recommended remediation action to mitigate a Vuln.
Fields
description - String!
fragment VulnMitigationFragment on VulnMitigation {
description
}
Examples may not include all available fields for a type.
{
"description": "Enable SMB signing on all hosts via Group Policy."
}
VulnReference
Description
A reference to external documentation or resources related to a Vuln.
fragment VulnReferenceFragment on VulnReference {
name
url
}
Examples may not include all available fields for a type.
{
"name": "Microsoft - Overview of SMB Signing",
"url": "https://learn.microsoft.com/en-us/troubleshoot/windows-server/networking/overview-server-message-block-signing"
}
WeaknessesPage
Description
A paginated list of Weakness records. Returned by Query.weaknesses_page.
Fields
page_info - PageInfo
weaknesses - [Weakness!]!
fragment WeaknessesPageFragment on WeaknessesPage {
page_info {
page_num
page_size
}
weaknesses {
uuid
vuln_id
vuln_name
score
severity
ip
op_id
portal_url
}
}
Examples may not include all available fields for a type.
{
"page_info": {
"page_num": 1,
"page_size": 10
},
"weaknesses": [
{
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"vuln_id": "h3-2024-0001",
"vuln_name": "SMB Signing Not Required",
"score": 6.5,
"severity": "MEDIUM",
"ip": "10.0.1.25",
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"portal_url": "https://portal.yourorg.com/weaknesses/abcd1234-abcd-1234-abcd-1234abcd1234"
},
{
"uuid": "efgh5678-efgh-5678-efgh-5678efgh5678",
"vuln_id": "CVE-2021-34527",
"vuln_name": "PrintNightmare - Windows Print Spooler RCE",
"score": 9.8,
"severity": "CRITICAL",
"ip": "10.0.1.50",
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"portal_url": "https://portal.yourorg.com/weaknesses/efgh5678-efgh-5678-efgh-5678efgh5678"
}
]
}
Pentesting: Proofs
Access proof artifacts demonstrating successful exploitation including command outputs, screenshots, and enumeration results. Proof provides forensic evidence validating each finding discovered during pentesting.
Proof
Description
A Proof represents evidence captured by NodeZero during a pentest that demonstrates a specific finding, such as a compromised credential, an exploited weakness, or a discovered resource.
Each Proof is one of three types, as indicated by the proof_type field:
- ScreenshotProofResource -- A screenshot image. Use the
presigned_urlfield to download it. Presigned URLs are generated on demand and expire after a short period. - CommandOutputProofResource -- Output from one or more shell commands executed by NodeZero. Retrieve the data via the
command_outputsfield, which returns a list of CommandOutput objects. - EnumerationProofResource -- Structured enumeration data (e.g., processes, programs, or users discovered on a host). Retrieve the data via the
enumeration_outputsfield, which returns a list of EnumerationProofOutput objects.
A single Proof may apply to more than one entity (e.g., a Weakness, a Credential, or a web resource). The proven_entity_labels field lists labels for all associated entities.
Fields
uuid - String!
created_at - Datetime!
collected_at, which indicates when the proof was actually captured during the pentest. proof_type - String!
CommandOutputProofResource, ScreenshotProofResource, or EnumerationProofResource. collected_at - Datetime
created_at which is the record creation time. annotation - String
url - String
presigned_url - String
command_outputs - [CommandOutput]
enumeration_type - String
Process, Program, and User. Only populated for enumeration-type proofs. enumeration_outputs - [EnumerationProofOutput]
proven_entity_labels - [String]
found_by_module_meta - ModuleMeta
fragment ProofFragment on Proof {
uuid
created_at
proof_type
collected_at
annotation
url
presigned_url
command_outputs {
command
output
}
enumeration_type
enumeration_outputs {
name
metadata
}
proven_entity_labels
found_by_module_meta {
id
name
description
mitre_mappings {
mitre_tactic_id
mitre_technique_id
mitre_subtechnique_id
}
}
op_id
}
Examples may not include all available fields for a type.
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"created_at": "2024-01-15T14:32:18Z",
"proof_type": "CommandOutputProofResource",
"collected_at": "2024-01-15T14:32:15Z",
"annotation": "Successfully executed command as privileged user on target system",
"url": null,
"presigned_url": null,
"command_outputs": [
{
"command": "whoami /priv",
"output": "PRIVILEGES INFORMATION\n----------------------\n\nPrivilege Name Description State\n============================= =================================== ========\nSeShutdownPrivilege Shut down the system Disabled\nSeChangeNotifyPrivilege Bypass traverse checking Enabled\nSeUndockPrivilege Remove computer from docking station Disabled\nSeIncreaseWorkingSetPrivilege Increase a process working set Disabled\nSeTimeZonePrivilege Change the time zone Disabled"
}
],
"enumeration_type": null,
"enumeration_outputs": null,
"proven_entity_labels": ["weakness", "credential", "host"],
"found_by_module_meta": {
"id": "credential_extraction",
"name": "Credential Extraction",
"description": "Extracts credentials from memory and credential stores on compromised systems",
"mitre_mappings": [
{
"mitre_tactic_id": "TA0006",
"mitre_technique_id": "T1003",
"mitre_subtechnique_id": "T1003.001"
},
{
"mitre_tactic_id": "TA0004",
"mitre_technique_id": "T1078",
"mitre_subtechnique_id": null
}
]
},
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}
CommandOutput
Description
Output from a shell command executed by NodeZero during a pentest. Each CommandOutput contains the command that was run and the resulting output. A single Proof of type CommandOutputProofResource may contain multiple CommandOutput entries.
fragment CommandOutputFragment on CommandOutput {
command
output
}
Examples may not include all available fields for a type.
{
"command": "cat /etc/passwd",
"output": "root:x:0:0:root:/root:/bin/bash\ndaemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin\nbin:x:2:2:bin:/bin:/usr/sbin/nologin\nsys:x:3:3:sys:/dev:/usr/sbin/nologin\nsync:x:4:65534:sync:/bin:/bin/sync\ngames:x:5:60:games:/usr/games:/usr/sbin/nologin\nman:x:6:12:man:/var/cache/man:/usr/sbin/nologin\nlp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin\nmail:x:8:8:mail:/var/mail:/usr/sbin/nologin\nnews:x:9:9:news:/var/spool/news:/usr/sbin/nologin\nuucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin\nproxy:x:13:13:proxy:/bin:/usr/sbin/nologin\nwww-data:x:33:33:www-data:/var/www:/usr/sbin/nologin\nbackup:x:34:34:backup:/var/backups:/usr/sbin/nologin\nlist:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin\nirc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin\ngnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin\nnobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin"
}
EnumerationProofOutput
Description
A structured enumeration item captured during host discovery. Enumeration proofs contain lists of items such as running processes, installed programs, or user accounts found on a compromised host. Each item has a display name and a set of metadata key-value pairs with additional detail.
Fields
name - String!
metadata - JSONObject!
fragment EnumerationProofOutputFragment on EnumerationProofOutput {
name
metadata
}
Examples may not include all available fields for a type.
{
"name": "Local Administrator",
"metadata": {
"sid": "S-1-5-21-1234567890-1234567890-1234567890-500",
"enabled": true,
"last_logon": "2024-01-14T09:15:32Z",
"password_last_set": "2023-11-20T16:45:00Z",
"password_expires": null,
"account_type": "Administrator",
"groups": ["Administrators", "Remote Desktop Users", "Users"],
"privileges": ["SeDebugPrivilege", "SeBackupPrivilege", "SeRestorePrivilege"],
"description": "Built-in account for administering the computer/domain"
}
}
Pentesting: Credentials
View credentials compromised during pentesting including usernames, password hashes, cloud roles, and their usage in attacks. Track credential exposure across your environment and identify weak password patterns in Active Directory.
credentials_page
Description
Returns a paginated list of Credential records for the given pentest. Anonymous credentials are excluded unless they were used in an AttackPath and have a high risk score.
Response
Returns a CredentialsPage!
query CredentialsPage($input: OpInput!, $page_input: PageInput) {
credentials_page(input: $input, page_input: $page_input) {
credentials {
...CredentialPageFragment
}
}
}
fragment CredentialPageFragment on Credential {
uuid
created_at
cred_type
user_name
ip
product
cleartext
has_proof
is_validated
score
severity
weaknesses_count
attack_paths_count
display_name
portal_url
}
Examples may not include all available fields for a type.
{
"data": {
"credentials_page": {
"credentials": [
{
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"created_at": "2024-01-15T09:15:33Z",
"cred_type": "STANDARD",
"user_name": "jsmith",
"ip": "10.0.1.25",
"product": "Windows",
"cleartext": "P***d",
"has_proof": true,
"is_validated": true,
"score": 7.5,
"severity": "HIGH",
"weaknesses_count": 3,
"attack_paths_count": 5,
"display_name": "jsmith@10.0.1.25",
"portal_url": "https://portal.yourorg.com/credentials/abcd1234-abcd-1234-abcd-1234abcd1234"
},
{
"uuid": "efgh5678-efgh-5678-efgh-5678efgh5678",
"created_at": "2024-01-15T10:45:22Z",
"cred_type": "AWS",
"user_name": "svc-deploy",
"ip": null,
"product": "AWS",
"cleartext": null,
"has_proof": true,
"is_validated": true,
"score": 6.2,
"severity": "MEDIUM",
"weaknesses_count": 2,
"attack_paths_count": 3,
"display_name": "svc-deploy",
"portal_url": "https://portal.yourorg.com/credentials/efgh5678-efgh-5678-efgh-5678efgh5678"
}
]
}
}
}
python h3_gql.py ./credentials_page.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
},
"page_input": {
"page_size": 10
}
}'
Save the example request as ./credentials_page.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./credentials_page.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
},
"page_input": {
"page_size": 10
}
}'
Save the example request as ./credentials_page.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./credentials_page.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
},
"page_input": {
"page_size": 10
}
}'
Save the example request as ./credentials_page.graphql.
See h3-cli Examples for installation and usage.
credentials_count
Description
Returns the total number of Credential records for the given pentest. Anonymous credentials are excluded unless they were used in an AttackPath and have a high risk score. Uses the same filtering logic as Query.credentials_page.
Response
Returns an Int!
query CredentialsCount($input: OpInput!, $page_input: PageInput) {
credentials_count(input: $input, page_input: $page_input)
}
Examples may not include all available fields for a type.
{
"data": {
"credentials_count": 47
}
}
python h3_gql.py ./credentials_count.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
},
"page_input": null
}'
Save the example request as ./credentials_count.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./credentials_count.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
},
"page_input": null
}'
Save the example request as ./credentials_count.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./credentials_count.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
},
"page_input": null
}'
Save the example request as ./credentials_count.graphql.
See h3-cli Examples for installation and usage.
credential
Description
Retrieves a single Credential by its unique identifier.
Response
Returns a Credential
Arguments
uuid - String!
query Credential($uuid: String!) {
credential(uuid: $uuid) {
...CredentialFragment
}
}
fragment CredentialFragment on Credential {
uuid
created_at
cred_type
user_name
ip
product
cleartext
hash
has_proof
is_validated
role
role_name
score
severity
weaknesses_count
attack_paths_count
display_name
portal_url
}
Examples may not include all available fields for a type.
{
"data": {
"credential": {
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"created_at": "2024-01-15T09:15:33Z",
"cred_type": "STANDARD",
"user_name": "jsmith",
"ip": "10.0.1.25",
"product": "Windows",
"cleartext": "P***d",
"hash": null,
"has_proof": true,
"is_validated": true,
"role": "LOCAL_ADMIN",
"role_name": "Local Admin",
"score": 7.5,
"severity": "HIGH",
"weaknesses_count": 3,
"attack_paths_count": 5,
"display_name": "jsmith@10.0.1.25",
"portal_url": "https://portal.yourorg.com/credentials/abcd1234-abcd-1234-abcd-1234abcd1234"
}
}
}
python h3_gql.py ./credential.graphql '{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./credential.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./credential.graphql '{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./credential.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./credential.graphql '{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./credential.graphql.
See h3-cli Examples for installation and usage.
credentials_csv_url
Description
Returns a presigned URL to download all Credential records for the given pentest as a CSV file. The presigned URL is generated on demand and expires after a short period.
The CSV format is documented under CredentialCSV.
Response
Returns a String
Arguments
input - OpInput!
query CredentialsCsvUrl($input: OpInput!) {
credentials_csv_url(input: $input)
}
Examples may not include all available fields for a type.
{
"data": {
"credentials_csv_url": "https://s3.amazonaws.com/h3-exports/credentials/1234abcd-1234-abcd-1234-abcd1234abcd.csv?X-Amz-Algorithm=AWS4-HMAC-SHA256&..."
}
}
python h3_gql.py ./credentials_csv_url.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}
}'
Save the example request as ./credentials_csv_url.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./credentials_csv_url.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}
}'
Save the example request as ./credentials_csv_url.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./credentials_csv_url.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}
}'
Save the example request as ./credentials_csv_url.graphql.
See h3-cli Examples for installation and usage.
activedir_passwords_csv_url
Description
Returns a presigned URL to download Active Directory password audit results as a CSV file. The presigned URL is generated on demand and expires after a short period. The CSV format is documented under ActiveDirPasswordCSV.
Response
Returns a String
Arguments
input - OpInput!
query ActivedirPasswordsCsvUrl($input: OpInput!) {
activedir_passwords_csv_url(input: $input)
}
Examples may not include all available fields for a type.
{
"data": {
"activedir_passwords_csv_url": "https://s3.amazonaws.com/h3-exports/ad-passwords/1234abcd-1234-abcd-1234-abcd1234abcd.csv?X-Amz-Algorithm=AWS4-HMAC-SHA256&..."
}
}
python h3_gql.py ./activedir_passwords_csv_url.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}
}'
Save the example request as ./activedir_passwords_csv_url.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./activedir_passwords_csv_url.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}
}'
Save the example request as ./activedir_passwords_csv_url.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./activedir_passwords_csv_url.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}
}'
Save the example request as ./activedir_passwords_csv_url.graphql.
See h3-cli Examples for installation and usage.
Credential
Description
A Credential represents a user account, password, hash, API key, or other secret discovered or validated by NodeZero during a pentest.
Credentials encompass a range of access types, from traditional username/password pairs to cloud IAM roles, SNMP community strings, Kubernetes service accounts, and more. The cred_type field indicates the category of the credential, and the role field indicates the privilege level (e.g., Domain Admin, Local User).
Use Query.credentials_page to list credentials for a pentest, Query.credential to fetch a single credential by UUID, or Query.credentials_csv_url to export credentials as CSV.
Fields
uuid - String!
created_at - Datetime!
cred_type - String
STANDARD (username/password), AWS, SNMP_COMMUNITY_STRING, PUBLIC_WEB, SMB_NULL_BIND, LDAP_NULL_BIND, NFS_NULL_BIND, API_ANONYMOUS, and AWS_CROSS_ACCOUNT_USER. user_name - String
(anonymous) if none are available. k8s_identity_name - String
cloud_role_name - String
cloud_account_id - String
ip - String
ips for the complete list. ips - [String]
sockets - [String]
{ip}:{port}. product - String
ssh, smb, rdp) that this Credential was used to authenticate against. permissions_list - [String]
read, write, delete) associated with this Credential, indicating what access it grants. api_key_id - String
api_secret_key - String
api_session_token - String
cleartext - String
hash - String
has_proof - Boolean
is_validated - Boolean
true if NodeZero successfully used and validated this Credential during the pentest, confirming it grants access. is_injected - Boolean
true if this Credential was injected (i.e., provided as an input to the pentest) rather than discovered autonomously by NodeZero. is_cracked - Boolean
true if NodeZero successfully cracked the password hash for this Credential during the pentest. is_local_admin - Boolean
true if this Credential has local administrator privileges on a host. is_domain_admin - Boolean
true if this Credential has Domain Admin privileges in Active Directory. is_entra_global_admin - Boolean
true if this Credential has Global Admin privileges in Microsoft Entra (formerly Azure AD). role_name - String
role (e.g., Domain User, Local Admin, AWS Role). context_score_description - String
score - Float
severity - Severity
weaknesses_page - WeaknessesPage!
Arguments
page_input - PageInput
data_stores_count - Int!
data_stores_page - DataStoresPage!
Arguments
page_input - PageInput
downstream_impact_types - [ImpactType!]
attack_paths_page. attack_paths_count - Int!
Arguments
page_input - PageInput
attack_paths_page - AttackPathsPage!
Arguments
page_input - PageInput
time_to_finding_hms - String
hh:mm:ss. time_to_finding_s - Int
display_name - String
username@ip, or the AWS access key ID. portal_url - String
fragment CredentialFragment on Credential {
uuid
created_at
cred_type
user_name
cloud_role_name
cloud_account_id
ip
ips
sockets
product
permissions_list
cleartext
hash
has_proof
is_validated
is_injected
is_cracked
is_local_admin
is_domain_admin
role
role_name
score
severity
weaknesses_count
services_count
data_stores_count
attack_paths_count
time_to_finding_hms
display_name
op_id
portal_url
}
Examples may not include all available fields for a type.
{
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"created_at": "2024-01-15T09:15:33Z",
"cred_type": "STANDARD",
"user_name": "jsmith",
"cloud_role_name": null,
"cloud_account_id": null,
"ip": "10.0.1.25",
"ips": ["10.0.1.25", "10.0.1.50"],
"sockets": ["10.0.1.25:445", "10.0.1.50:445"],
"product": "Windows",
"permissions_list": ["read", "write"],
"cleartext": "P***d",
"hash": null,
"has_proof": true,
"is_validated": true,
"is_injected": false,
"is_cracked": false,
"is_local_admin": true,
"is_domain_admin": false,
"role": "LOCAL_ADMIN",
"role_name": "Local Admin",
"score": 7.5,
"severity": "HIGH",
"weaknesses_count": 3,
"services_count": 4,
"data_stores_count": 2,
"attack_paths_count": 5,
"time_to_finding_hms": "00:45:12",
"display_name": "jsmith@10.0.1.25",
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"portal_url": "https://portal.yourorg.com/credentials/abcd1234-abcd-1234-abcd-1234abcd1234"
}
CloudRole
Description
Represents a security role in a cloud environment, such as an AWS IAM role, an Azure role, or another cloud provider role. CloudRoles are discovered when NodeZero enumerates cloud infrastructure during a pentest and may be associated with one or more Credential records.
Fields
uuid - String!
created_at - Datetime!
name - String!
cloud_account_id - String
cloud_provider_name - String
AWS, Azure). fragment CloudRoleFragment on CloudRole {
uuid
created_at
name
cloud_account_id
cloud_provider_name
op_id
}
Examples may not include all available fields for a type.
{
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"created_at": "2024-01-15T08:12:00Z",
"name": "EC2-Admin-Role",
"cloud_account_id": "123456789012",
"cloud_provider_name": "AMAZON",
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}
CredentialsPage
Description
A paginated list of Credential records. Returned by Query.credentials_page.
Fields
page_info - PageInfo
credentials - [Credential!]!
fragment CredentialsPageFragment on CredentialsPage {
page_info {
page_num
page_size
}
credentials {
uuid
cred_type
user_name
ip
product
role_name
score
severity
display_name
op_id
portal_url
}
}
Examples may not include all available fields for a type.
{
"page_info": {
"page_num": 1,
"page_size": 10
},
"credentials": [
{
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"cred_type": "STANDARD",
"user_name": "jsmith",
"ip": "10.0.1.25",
"product": "Windows",
"role_name": "Local Admin",
"score": 7.5,
"severity": "HIGH",
"display_name": "jsmith@10.0.1.25",
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"portal_url": "https://portal.yourorg.com/credentials/abcd1234-abcd-1234-abcd-1234abcd1234"
},
{
"uuid": "efgh5678-efgh-5678-efgh-5678efgh5678",
"cred_type": "AWS",
"user_name": "svc-deploy",
"ip": null,
"product": "AWS",
"role_name": "Domain User",
"score": 6.2,
"severity": "MEDIUM",
"display_name": "svc-deploy",
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"portal_url": "https://portal.yourorg.com/credentials/efgh5678-efgh-5678-efgh-5678efgh5678"
}
]
}
Pentesting: Data Stores
Query discovered data stores and databases identified during pentesting including file shares, databases, cloud storage, and sensitive resources. View accessibility, permissions, and interesting files or data discovered.
data_stores_page
Description
Returns a paginated list of DataStores discovered during the specified pentest. Supports filtering (e.g., by data_store_type, severity, downstream_impact_types), sorting, and text search via page_input.
Response
Returns a DataStoresPage!
query DataStoresPage($input: OpInput!, $page_input: PageInput) {
data_stores_page(input: $input, page_input: $page_input) {
data_stores {
...DataStoreFragment
}
}
}
fragment DataStoreFragment on DataStore {
uuid
data_store_type
name
title
ip
port
service_type
data_resources_count
data_resources_label
sensitive_resources_count
is_authenticated
score
severity
}
Examples may not include all available fields for a type.
{
"data": {
"data_stores_page": {
"data_stores": [
{
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"data_store_type": "FileShare",
"name": "SYSVOL",
"title": "File Share SYSVOL on 192.168.1.100 Port 445",
"ip": "192.168.1.100",
"port": 445,
"service_type": "SMB",
"data_resources_count": 523,
"data_resources_label": "FILES",
"sensitive_resources_count": 8,
"is_authenticated": true,
"score": 6.5,
"severity": "MEDIUM"
},
{
"uuid": "5678efgh-5678-efgh-5678-efgh5678efgh",
"data_store_type": "S3Bucket",
"name": "company-backups",
"title": "S3 Bucket company-backups",
"ip": null,
"port": null,
"service_type": "S3",
"data_resources_count": 2341,
"data_resources_label": "OBJECTS",
"sensitive_resources_count": 45,
"is_authenticated": false,
"score": 8.2,
"severity": "HIGH"
}
]
}
}
}
python h3_gql.py ./data_stores_page.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
},
"page_input": {
"page_size": 10
}
}'
Save the example request as ./data_stores_page.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./data_stores_page.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
},
"page_input": {
"page_size": 10
}
}'
Save the example request as ./data_stores_page.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./data_stores_page.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
},
"page_input": {
"page_size": 10
}
}'
Save the example request as ./data_stores_page.graphql.
See h3-cli Examples for installation and usage.
data_stores_count
Description
Returns the count of DataStores discovered during the specified pentest. Supports filtering via page_input (e.g., by data_store_type, severity, or text search).
Response
Returns an Int!
query DataStoresCount($input: OpInput!, $page_input: PageInput) {
data_stores_count(input: $input, page_input: $page_input)
}
Examples may not include all available fields for a type.
{
"data": {
"data_stores_count": 23
}
}
python h3_gql.py ./data_stores_count.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
},
"page_input": null
}'
Save the example request as ./data_stores_count.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./data_stores_count.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
},
"page_input": null
}'
Save the example request as ./data_stores_count.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./data_stores_count.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
},
"page_input": null
}'
Save the example request as ./data_stores_count.graphql.
See h3-cli Examples for installation and usage.
data_store
Description
Returns the DataStore with the given uuid. A DataStore represents a data repository (file share, database, S3 bucket, etc.) discovered during a pentest.
Response
Returns a DataStore
Arguments
uuid - String!
query DataStore($uuid: String!) {
data_store(uuid: $uuid) {
...DataStoreFragment
}
}
fragment DataStoreFragment on DataStore {
uuid
data_store_type
created_at
name
title
ip
port
host_name
service_type
address
data_resources_count
data_resources_label
sensitive_resources_count
is_authenticated
permissions_list
score
severity
op_id
portal_url
}
Examples may not include all available fields for a type.
{
"data": {
"data_store": {
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"data_store_type": "FileShare",
"created_at": "2024-03-15T14:23:45Z",
"name": "ADMIN$",
"title": "File Share ADMIN$ on 192.168.1.100 Port 445",
"ip": "192.168.1.100",
"port": 445,
"host_name": "DC01.contoso.local",
"service_type": "SMB",
"address": "192.168.1.100",
"data_resources_count": 1847,
"data_resources_label": "FILES",
"sensitive_resources_count": 23,
"is_authenticated": true,
"permissions_list": ["read", "list"],
"score": 7.8,
"severity": "HIGH",
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"portal_url": "https://portal.yourorg.com/data-stores/1234abcd-1234-abcd-1234-abcd1234abcd"
}
}
}
python h3_gql.py ./data_store.graphql '{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./data_store.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./data_store.graphql '{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./data_store.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./data_store.graphql '{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./data_store.graphql.
See h3-cli Examples for installation and usage.
data_stores_csv_url
Description
Returns a temporary presigned URL to a CSV export of all DataStores discovered during the specified pentest. The URL expires after a short time.
The CSV format is documented under ShareCSV.
Response
Returns a String
Arguments
input - OpInput!
query DataStoresCSVUrl($input: OpInput!) {
data_stores_csv_url(input: $input)
}
Examples may not include all available fields for a type.
{
"data": {
"data_stores_csv_url": "https://s3.amazonaws.com/h3-exports/data-stores/1234abcd-1234-abcd-1234-abcd1234abcd.csv?X-Amz-Algorithm=AWS4-HMAC-SHA256&..."
}
}
python h3_gql.py ./data_stores_csv_url.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}
}'
Save the example request as ./data_stores_csv_url.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./data_stores_csv_url.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}
}'
Save the example request as ./data_stores_csv_url.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./data_stores_csv_url.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}
}'
Save the example request as ./data_stores_csv_url.graphql.
See h3-cli Examples for installation and usage.
DataStore
Description
A DataStore represents a data repository discovered by NodeZero during a pentest. DataStores include file shares (SMB, NFS), databases (PostgreSQL, MySQL, DynamoDB), AWS S3 buckets, Azure Storage accounts, Docker registries, Git repositories (GitHub, GitLab), and Microsoft 365 resources (Outlook, OneDrive, SharePoint).
The data_store_type field indicates which category of data store this record represents. Each DataStore is scored based on the sensitivity of the data it contains and the weaknesses that expose it.
Use Query.data_stores_page to list DataStores for a pentest, Query.data_store to fetch a single DataStore by UUID, or Query.data_stores_csv_url to export DataStores as CSV.
Fields
uuid - String!
created_at - Datetime!
name - String
name_and_account - String
<account_name> : <data_store_name>. For Git repositories, this includes the Git account name. title - String
File Share ADMIN$ on 123.4.5.6 Port 445. ip - String
port - Int
host_name - String
service_type - String
The protocol or service name associated with this DataStore. The value varies by data_store_type:
- FileShare: The SMB/NFS service name (e.g.,
SMB,NFS) - DockerRegistry:
Docker Registry - DatabaseRepo: The database engine name (e.g.,
PostgreSQL,MySQL,AWS DynamoDB) - S3Bucket / AzureStorage: The cloud service name
- GitRepo: The Git hosting provider (e.g.,
GitHub,GitLab) - Microsoft365:
Microsoft Outlook,Microsoft OneDrive, orMicrosoft SharePoint
account - String
The account or owner associated with this DataStore. The value varies by data_store_type:
- S3Bucket / AzureStorage / Microsoft365: The cloud account ID
- GitRepo: The Git account name (e.g., the GitHub or GitLab organization)
- Other types:
null
address - String
The network address or URL used to access this DataStore. The value varies by data_store_type:
- FileShare / DockerRegistry / DatabaseRepo: The IP address or DNS FQDN of the hosting service
- S3Bucket: The S3 URI (e.g.,
s3://bucket-name) - GitRepo: The Git clone URL
- Microsoft365 / AzureStorage: The resource name or URL
data_resources_count - Long
The total number of data resources discovered in this DataStore. The meaning varies by data_store_type:
- FileShare / S3Bucket: Total file count
- DockerRegistry: Total image count
- DatabaseRepo: Total record count
- GitRepo: Sensitive findings count
- Microsoft365 (Outlook): Total email count
data_resources_label - String
A human-readable label describing the unit of data_resources_count. Possible values:
Files(FileShare, OneDrive, SharePoint)Objects(S3Bucket, AzureStorage)Emails(Outlook)Sensitive Findings(GitRepo)Records(DatabaseRepo)Images(DockerRegistry)
sensitive_resources_count - Int!
is_authenticated - Boolean
true if the DataStore was accessed using a non-anonymous credential during the pentest. cloud_resource_arn - String
cloud_service_name - String
Amazon S3, Azure Blob Storage). Applies to S3Buckets, AzureStorage, and cloud-hosted resources. cloud_provider_name - String
Amazon, Google, Microsoft). Applies to S3Buckets, AzureStorage, and cloud-hosted resources. permissions_list - [String]
read, write, and list. aws_anonymous_user_permissions_list - [String]
S3Bucket. aws_cross_account_user_permissions_list - [String]
S3Bucket. score - Float
context_score when available, otherwise base_score. severity - Severity
base_score - Float
context_score - Float
sensitive_data_item_count - Int
sensitive_data_item_types_and_counts - [String!]
SensitiveDataType,count, e.g. ["CREDIT_CARD,2", ...]. sensitive_data_item_titles_and_counts - [String!]
title,count, e.g. ["Credit Card Number,2", ...]. downstream_impact_types - [ImpactType!]
downstream_impact_types_and_counts - [String!]
ImpactType,count, e.g. ["RansomwareExposure,2", "SensitiveDataExposure,2"]. impact_paths_count - Int!
attack_paths_count. attack_paths_count - Int!
impact_paths_count. weaknesses_count - Int!
portal_url - String
fragment DataStoreFragment on DataStore {
uuid
data_store_type
created_at
name
name_and_account
title
ip
port
host_name
service_type
account
address
data_resources_count
data_resources_label
sensitive_resources_count
is_authenticated
permissions_list
score
severity
base_score
context_score
sensitive_data_item_count
downstream_impact_types
attack_paths_count
weaknesses_count
op_id
portal_url
}
Examples may not include all available fields for a type.
{
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"data_store_type": "FileShare",
"created_at": "2024-01-15T10:05:22Z",
"name": "ADMIN$",
"name_and_account": "ADMIN$",
"title": "File Share ADMIN$ on 10.0.1.25 Port 445",
"ip": "10.0.1.25",
"port": 445,
"host_name": "DC01.acme.local",
"service_type": "SMB",
"account": null,
"address": "10.0.1.25",
"data_resources_count": 1247,
"data_resources_label": "FILES",
"sensitive_resources_count": 12,
"is_authenticated": true,
"permissions_list": ["read", "write", "list"],
"score": 7.8,
"severity": "HIGH",
"base_score": 5.0,
"context_score": 7.8,
"sensitive_data_item_count": 34,
"downstream_impact_types": ["RansomwareExposure", "SensitiveDataExposure"],
"attack_paths_count": 4,
"weaknesses_count": 2,
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"portal_url": "https://portal.yourorg.com/data-stores/abcd1234-abcd-1234-abcd-1234abcd1234"
}
DataStoresPage
Description
A paginated list of DataStore records. Returned by Query.data_stores_page.
Fields
page_info - PageInfo
data_stores - [DataStore!]!
fragment DataStoresPageFragment on DataStoresPage {
page_info {
page_num
page_size
}
data_stores {
uuid
data_store_type
name
title
ip
port
service_type
data_resources_count
sensitive_resources_count
score
severity
op_id
portal_url
}
}
Examples may not include all available fields for a type.
{
"page_info": {
"page_num": 1,
"page_size": 10
},
"data_stores": [
{
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"data_store_type": "FileShare",
"name": "SYSVOL",
"title": "File Share SYSVOL on 10.0.1.25 Port 445",
"ip": "10.0.1.25",
"port": 445,
"service_type": "SMB",
"data_resources_count": 523,
"sensitive_resources_count": 8,
"score": 6.5,
"severity": "MEDIUM",
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"portal_url": "https://portal.yourorg.com/data-stores/abcd1234-abcd-1234-abcd-1234abcd1234"
},
{
"uuid": "efgh5678-efgh-5678-efgh-5678efgh5678",
"data_store_type": "S3Bucket",
"name": "company-backups",
"title": "S3 Bucket company-backups",
"ip": null,
"port": null,
"service_type": "S3",
"data_resources_count": 2341,
"sensitive_resources_count": 45,
"score": 8.2,
"severity": "HIGH",
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"portal_url": "https://portal.yourorg.com/data-stores/efgh5678-efgh-5678-efgh-5678efgh5678"
}
]
}
InterestingResource
Description
An InterestingResource represents a file or web page flagged by NodeZero as potentially containing sensitive information during a pentest. Examples include configuration files with embedded credentials (AWS keys, SSH keys), exposed admin panels, and files containing PII or PCI data.
InterestingResources are typically found within a DataStore and may have associated Proof records (screenshots or command output) that document the finding.
fragment InterestingResourceFragment on InterestingResource {
uuid
created_at
uri
service_uuid
data_store_uuid
op_id
}
Examples may not include all available fields for a type.
{
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"created_at": "2024-01-15T11:32:18Z",
"uri": "\\\\10.0.1.25\\ADMIN$\\Temp\\sensitive_config.xml",
"service_uuid": "5678efgh-5678-efgh-5678-efgh5678efgh",
"data_store_uuid": "9012ijkl-9012-ijkl-9012-ijkl9012ijkl",
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}
Pentesting: Hosts
Access information about discovered hosts including IP addresses, hostnames, operating systems, open ports, and their role in attack paths. Query the complete inventory of systems identified during pentesting.
hosts_page
Description
Returns a paginated list of in-scope Hosts discovered during the specified pentest. Supports filtering, sorting, and text search via page_input.
Response
Returns a HostsPage!
query HostsPage($input: OpInput!, $page_input: PageInput) {
hosts_page(input: $input, page_input: $page_input) {
hosts {
...HostPageFragment
}
}
}
fragment HostPageFragment on Host {
uuid
ip
host_name
is_in_scope
is_domain_controller
os_fingerprints
score
severity
subnet
is_public
display_name
weaknesses_count
credentials_count
services_count
portal_url
}
Examples may not include all available fields for a type.
{
"data": {
"hosts_page": {
"hosts": [
{
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"ip": "10.0.1.25",
"host_name": "DC01.acme.local",
"is_in_scope": true,
"is_domain_controller": true,
"os_fingerprints": ["Windows Server 2019"],
"score": 8.5,
"severity": "HIGH",
"subnet": "10.0.1.0/24",
"is_public": false,
"display_name": "DC01.acme.local (10.0.1.25)",
"weaknesses_count": 5,
"credentials_count": 3,
"services_count": 8,
"portal_url": "https://portal.yourorg.com/hosts/abcd1234-abcd-1234-abcd-1234abcd1234"
},
{
"uuid": "efgh5678-efgh-5678-efgh-5678efgh5678",
"ip": "10.0.1.50",
"host_name": "WEB01.acme.local",
"is_in_scope": true,
"is_domain_controller": false,
"os_fingerprints": ["Ubuntu 22.04"],
"score": 5.2,
"severity": "MEDIUM",
"subnet": "10.0.1.0/24",
"is_public": true,
"display_name": "WEB01.acme.local (10.0.1.50)",
"weaknesses_count": 2,
"credentials_count": 1,
"services_count": 4,
"portal_url": "https://portal.yourorg.com/hosts/efgh5678-efgh-5678-efgh-5678efgh5678"
}
]
}
}
}
python h3_gql.py ./hosts_page.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
},
"page_input": {
"page_size": 10
}
}'
Save the example request as ./hosts_page.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./hosts_page.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
},
"page_input": {
"page_size": 10
}
}'
Save the example request as ./hosts_page.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./hosts_page.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
},
"page_input": {
"page_size": 10
}
}'
Save the example request as ./hosts_page.graphql.
See h3-cli Examples for installation and usage.
hosts_count
Description
Returns the number of in-scope Hosts discovered during the specified pentest. Supports filtering via page_input (e.g., by severity, is_domain_controller, or text search).
Response
Returns an Int!
query HostsCount($input: OpInput!, $page_input: PageInput) {
hosts_count(input: $input, page_input: $page_input)
}
Examples may not include all available fields for a type.
{
"data": {
"hosts_count": 156
}
}
python h3_gql.py ./hosts_count.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
},
"page_input": null
}'
Save the example request as ./hosts_count.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./hosts_count.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
},
"page_input": null
}'
Save the example request as ./hosts_count.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./hosts_count.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
},
"page_input": null
}'
Save the example request as ./hosts_count.graphql.
See h3-cli Examples for installation and usage.
host
Description
Returns the Host with the given uuid. A Host represents a unique IP address (network endpoint) discovered during a pentest.
Response
Returns a Host
Arguments
uuid - String!
query Host($uuid: String!) {
host(uuid: $uuid) {
...HostFragment
}
}
fragment HostFragment on Host {
uuid
created_at
ip
mac
host_name
host_names
is_in_scope
is_domain_controller
os_fingerprints
op_id
score
severity
subnet
cloud_provider
is_public
display_name
weaknesses_count
credentials_count
services_count
attack_paths_count
portal_url
}
Examples may not include all available fields for a type.
{
"data": {
"host": {
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"created_at": "2024-01-15T08:05:12Z",
"ip": "10.0.1.25",
"mac": "00:1A:2B:3C:4D:5E",
"host_name": "DC01.acme.local",
"host_names": ["DC01.acme.local", "dc01"],
"is_in_scope": true,
"is_domain_controller": true,
"os_fingerprints": ["Windows Server 2019"],
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"score": 8.5,
"severity": "HIGH",
"subnet": "10.0.1.0/24",
"cloud_provider": null,
"is_public": false,
"display_name": "DC01.acme.local (10.0.1.25)",
"weaknesses_count": 5,
"credentials_count": 3,
"services_count": 8,
"attack_paths_count": 7,
"portal_url": "https://portal.yourorg.com/hosts/abcd1234-abcd-1234-abcd-1234abcd1234"
}
}
}
python h3_gql.py ./host.graphql '{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./host.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./host.graphql '{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./host.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./host.graphql '{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./host.graphql.
See h3-cli Examples for installation and usage.
hosts_csv_url
Description
Returns a temporary presigned URL to a CSV export of all Hosts discovered during the specified pentest. The URL expires after a short time. The CSV format is documented under HostCSV.
Response
Returns a String
Arguments
input - OpInput!
query HostsCsvUrl($input: OpInput!) {
hosts_csv_url(input: $input)
}
Examples may not include all available fields for a type.
{
"data": {
"hosts_csv_url": "https://s3.amazonaws.com/h3-exports/hosts/1234abcd-1234-abcd-1234-abcd1234abcd.csv?X-Amz-Algorithm=AWS4-HMAC-SHA256&..."
}
}
python h3_gql.py ./hosts_csv_url.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}
}'
Save the example request as ./hosts_csv_url.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./hosts_csv_url.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}
}'
Save the example request as ./hosts_csv_url.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./hosts_csv_url.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}
}'
Save the example request as ./hosts_csv_url.graphql.
See h3-cli Examples for installation and usage.
Host
Description
A Host represents a unique IP address discovered by NodeZero during a pentest. Each Host corresponds to a network endpoint such as a server, workstation, domain controller, cloud instance, printer, or IoT device.
Hosts serve as a central point for understanding the security posture of an individual machine -- including the Services it exposes, the Credentials that can access it, the DataStores it contains, and the Weaknesses that affect it.
Use Query.hosts_page to list Hosts for a pentest, Query.host to fetch a single Host by UUID, or Query.hosts_csv_url to export Hosts as CSV.
Fields
uuid - String!
created_at - Datetime!
ip - String
mac - String
cname_chains - [String]
host_name - String
host_names - [String]
All hostnames associated with this Host's IP address, aggregated from multiple sources:
- Internal and external DNS hostnames
- LDAP hostname
- Virtual host (VHost) names
is_in_scope - Boolean
true if this Host was included in the configured pentest scope. is_domain_controller - Boolean
true if this Host is an Active Directory domain controller. is_database_server - Boolean
true if this Host is a database server. is_load_balancer - Boolean
true if this Host is a load balancer. is_mail_server - Boolean
true if this Host is a mail server. is_vpn - Boolean
true if this Host is a VPN gateway. is_waf - Boolean
true if this Host is a Web Application Firewall (WAF). os_fingerprints - [String]
Windows Server 2019, Ubuntu 22.04). hardware_fingerprints - [String]
device_fingerprints - [String]
data_stores_count - Int!
data_stores_page - DataStoresPage!
Arguments
page_input - PageInput
credentials_count - Int!
credentials_page - CredentialsPage!
Arguments
page_input - PageInput
data_resources_count - Long
web_resources_count for web page counts. web_resources_count - Long
context_score_description - String
score - Float
severity - Severity
subnet - String
192.168.1.0/24). cloud_provider - String
aws, gcp, azure), if applicable. cloud_region - String
us-east-1, us-central1), if applicable. cloud_arns - [String!]
is_public - Boolean
true if this Host has a publicly routable IP address. action_logs_count - Int!
Arguments
page_input - PageInput
action_logs_page - ActionLogsPage!
Arguments
page_input - PageInput
action_logs_csv_url - String
downstream_impact_types - [ImpactType!]
os_names - [String!]
Windows, Linux, macOS). Derived from os_fingerprints. attack_paths_count - Int!
attack_paths_page - AttackPathsPage!
Arguments
page_input - PageInput
display_name - String
weaknesses_count - Int!
Arguments
page_input - PageInput
weaknesses_page - WeaknessesPage!
Arguments
page_input - PageInput
portal_url - String
fragment HostFragment on Host {
uuid
created_at
ip
mac
cname_chains
host_name
host_names
is_in_scope
is_domain_controller
is_database_server
is_mail_server
is_vpn
is_waf
os_fingerprints
hardware_fingerprints
device_fingerprints
op_id
data_stores_count
credentials_count
data_resources_count
web_resources_count
services_count
context_score_description
score
severity
subnet
cloud_provider
cloud_region
cloud_arns
is_public
downstream_impact_types
os_names
attack_paths_count
display_name
weaknesses_count
portal_url
}
Examples may not include all available fields for a type.
{
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"created_at": "2024-01-15T08:05:12Z",
"ip": "10.0.1.25",
"mac": "00:1A:2B:3C:4D:5E",
"cname_chains": [],
"host_name": "DC01.acme.local",
"host_names": ["DC01.acme.local", "dc01"],
"is_in_scope": true,
"is_domain_controller": true,
"is_database_server": false,
"is_mail_server": false,
"is_vpn": false,
"is_waf": false,
"os_fingerprints": ["Windows Server 2019 Standard"],
"hardware_fingerprints": ["Dell PowerEdge R640"],
"device_fingerprints": [],
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"data_stores_count": 3,
"credentials_count": 5,
"data_resources_count": 4521,
"web_resources_count": 12,
"services_count": 8,
"context_score_description": "This host has 5 downstream impacts including ransomware exposure.",
"score": 8.5,
"severity": "HIGH",
"subnet": "10.0.1.0/24",
"cloud_provider": null,
"cloud_region": null,
"cloud_arns": [],
"is_public": false,
"downstream_impact_types": ["RansomwareExposure", "SensitiveDataExposure"],
"os_names": ["Windows Server 2019"],
"attack_paths_count": 7,
"display_name": "DC01.acme.local (10.0.1.25)",
"weaknesses_count": 5,
"portal_url": "https://portal.yourorg.com/hosts/abcd1234-abcd-1234-abcd-1234abcd1234"
}
HostsPage
Description
A paginated list of Host records. Returned by Query.hosts_page.
fragment HostsPageFragment on HostsPage {
page_info {
page_num
page_size
}
hosts {
uuid
ip
host_name
is_in_scope
is_domain_controller
os_fingerprints
score
severity
subnet
is_public
display_name
op_id
portal_url
}
}
Examples may not include all available fields for a type.
{
"page_info": {
"page_num": 1,
"page_size": 10
},
"hosts": [
{
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"ip": "10.0.1.25",
"host_name": "DC01.acme.local",
"is_in_scope": true,
"is_domain_controller": true,
"os_fingerprints": ["Windows Server 2019"],
"score": 8.5,
"severity": "HIGH",
"subnet": "10.0.1.0/24",
"is_public": false,
"display_name": "DC01.acme.local (10.0.1.25)",
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"portal_url": "https://portal.yourorg.com/hosts/abcd1234-abcd-1234-abcd-1234abcd1234"
},
{
"uuid": "efgh5678-efgh-5678-efgh-5678efgh5678",
"ip": "10.0.1.50",
"host_name": "WEB01.acme.local",
"is_in_scope": true,
"is_domain_controller": false,
"os_fingerprints": ["Ubuntu 22.04"],
"score": 5.2,
"severity": "MEDIUM",
"subnet": "10.0.1.0/24",
"is_public": true,
"display_name": "WEB01.acme.local (10.0.1.50)",
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"portal_url": "https://portal.yourorg.com/hosts/efgh5678-efgh-5678-efgh-5678efgh5678"
}
]
}
Pentesting: EDR
View EDR (Endpoint Detection and Response) events triggered during pentesting. Track which security controls detected NodeZero's activities to measure detection coverage and response effectiveness.
edr_overview_hosts_csv_presigned_url
Description
Generates a CSV export of hosts with endpoint detection and response (EDR) data from a pentest and returns a temporary presigned URL for downloading the file. Each row includes the host's risk score, IP address, detected EDR vendors, count of unblocked security control events, MITRE ATT&CK tactics observed, downstream impacts, and host classification flags (e.g., domain controller, database server, public-facing).
Use page_input to filter the exported hosts by any supported host field. Each unique filter combination produces a separately cached CSV file. The presigned URL expires after a short time.
The CSV format is documented under EDROverviewHostCSV.
Response
Returns a String
query EDROverviewHostsCSVPresignedUrl(
$input: OpInput!
$page_input: PageInput
) {
edr_overview_hosts_csv_presigned_url(
input: $input
page_input: $page_input
)
}
Examples may not include all available fields for a type.
{
"data": {
"edr_overview_hosts_csv_presigned_url": "https://s3.amazonaws.com/bucket/edr-overview-hosts.csv?X-Amz-Expires=3600&..."
}
}
python h3_gql.py ./edr_overview_hosts_csv_presigned_url.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}
}'
Save the example request as ./edr_overview_hosts_csv_presigned_url.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./edr_overview_hosts_csv_presigned_url.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}
}'
Save the example request as ./edr_overview_hosts_csv_presigned_url.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./edr_overview_hosts_csv_presigned_url.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}
}'
Save the example request as ./edr_overview_hosts_csv_presigned_url.graphql.
See h3-cli Examples for installation and usage.
Pentesting: External Domains
Query external domains discovered during pentesting including subdomains, DNS records, and associated IPs and services.
ExternalDomain
Description
Represents a DNS domain name discovered during an external attack surface assessment. Each ExternalDomain is associated with a pentest and captures the domain's DNS resolution data (IP addresses, CNAME records), cloud infrastructure details, certificate information, and relationships to hosts and web resources found during the operation. Domains are organized hierarchically: top-level domains are specified in the pentest configuration, and subdomains are discovered through DNS enumeration.
Fields
uuid - String!
created_at - Datetime!
name - String!
app.example.com. cnames - [String]
ips - [String]
op_id - String!
fragment ExternalDomainFragment on ExternalDomain {
uuid
created_at
name
cnames
ips
op_id
}
Examples may not include all available fields for a type.
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"created_at": "2024-01-15T09:15:00Z",
"name": "app.example.com",
"cnames": ["app.example.com.cdn.cloudflare.net"],
"ips": ["198.51.100.10", "198.51.100.11"],
"op_id": "5678efab-5678-efab-5678-efab5678efab"
}
Pentesting: LDAP Domains
Access Active Directory and LDAP domain information discovered during pentesting including domain controllers and configuration details.
LDAPDomain
Description
Represents an Active Directory LDAP domain discovered by NodeZero during a pentest. An LDAPDomain corresponds to a Windows Active Directory domain identified through LDAP enumeration. These domains are central to Active Directory attack paths -- they appear as affected entities on Weaknesses, are associated with Credentials and Users, and provide context for Active Directory password audit results.
LDAPDomains are not queryable directly. They are accessible as related objects on types such as Weakness (affected_ldap_domain) and User (ldap_domain).
Fields
uuid - String!
created_at - Datetime!
name - String!
corp.example.com). op_id - String!
fragment LDAPDomainFragment on LDAPDomain {
uuid
created_at
name
op_id
}
Examples may not include all available fields for a type.
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"created_at": "2024-01-15T09:20:00Z",
"name": "corp.example.com",
"op_id": "5678efab-5678-efab-5678-efab5678efab"
}
Pentesting: Cloud Resources
Query cloud resources discovered during pentesting including AWS, Azure, and GCP assets. View cloud infrastructure, permissions, misconfigurations, and their role in attack paths.
CloudResource
Description
Represents a cloud resource instance discovered by NodeZero during a pentest. A CloudResource is a specific infrastructure component within a cloud account, such as an AWS EC2 instance, an AWS RDS database, an AWS Lambda function, an Azure Virtual Machine, or a Google Cloud Compute Engine instance.
Each CloudResource belongs to a CloudAccount (the owning account) and is associated with a cloud service type (e.g., aws_ec2, aws_rds). CloudResources link to the underlying network Endpoint when an IP address is available, and may have associated data resources such as database records and files tracked via data_resources_count.
CloudResources are not queryable directly. They are accessible as related objects on Host (cloud_resources) and Weakness (affected_cloud_resource).
Fields
uuid - String!
cloud_service_name - String
aws_ec2, aws_lambda, aws_rds). See cloud_service_h3_service_name for the human-readable equivalent. ip - String
arn - String
data_resources_count - Long
op_id - String!
created_at - Datetime
cloud_account_id - String
cloud_provider_name - String
AWS, AZURE, and GCP. Resolved from the associated CloudAccount record. fragment CloudResourceFragment on CloudResource {
uuid
cloud_service_name
ip
arn
data_resources_count
created_at
cloud_account_id
cloud_provider_name
op_id
}
Examples may not include all available fields for a type.
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"cloud_service_name": "aws_ec2",
"ip": "10.0.2.100",
"arn": "arn:aws:ec2:us-east-1:123456789012:instance/i-0abcdef1234567890",
"data_resources_count": 5,
"created_at": "2024-01-15T10:00:00Z",
"cloud_account_id": "123456789012",
"cloud_provider_name": "AWS",
"op_id": "5678efab-5678-efab-5678-efab5678efab"
}
Pentesting: Applications
Access information about applications discovered during pentesting including web applications, services, and software versions. View application vulnerabilities and exposure.
Application
Description
An Application represents a software application discovered by NodeZero running on a Service. Examples include web servers, Active Directory Certificate Services, database management interfaces, and other network-accessible applications.
Each Application is associated with a single Service and inherits the Service's IP address and port. The name field identifies the application type based on fingerprint data collected during the pentest.
fragment ApplicationFragment on Application {
uuid
created_at
service_uuid
ip
port
name
op_id
}
Examples may not include all available fields for a type.
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"created_at": "2024-01-15T09:30:00Z",
"service_uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"ip": "10.0.1.50",
"port": 443,
"name": "Apache HTTP Server 2.4.51",
"op_id": "5678efab-5678-efab-5678-efab5678efab"
}
Pentesting: Services
Query network services discovered during pentesting including service types, ports, protocols, banners, and versions. Understand the service landscape of your tested environment.
Service
Description
A Service represents a listening network port discovered on a Host during a pentest. Each Service record corresponds to a unique combination of IP address and port.
Services expose the entry points that NodeZero probes during a pentest. Use the fingerprints field to identify what software is running on the port, and navigate to related Applications, DataStores, Credentials, and Weaknesses to understand the full security posture of each listening port.
Fields
uuid - String!
created_at - Datetime!
ip - String!
port - Int!
protocol - String
tcp, udp). fingerprints - [String]
iana_service_name - String
http, ssh, ms-sql-s). data_resources_count - Long
web_resources_count for web page counts. web_resources_count - Long
context_score_description - String
score - Float
fragment ServiceFragment on Service {
uuid
created_at
ip
port
protocol
fingerprints
iana_service_name
data_resources_count
web_resources_count
score
severity
context_score_description
op_id
}
Examples may not include all available fields for a type.
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"created_at": "2024-01-15T09:25:00Z",
"ip": "10.0.1.50",
"port": 443,
"protocol": "tcp",
"fingerprints": ["Apache/2.4.51", "OpenSSL/1.1.1"],
"iana_service_name": "https",
"data_resources_count": 12,
"web_resources_count": 85,
"score": 7.5,
"severity": "HIGH",
"context_score_description": "Hosts critical web application",
"op_id": "5678efab-5678-efab-5678-efab5678efab"
}
Pentesting: Action Logs
Access detailed logs of every action NodeZero performed during pentesting including MITRE ATT&CK mappings, module execution details, timestamps, and outcomes. Action logs provide complete forensic traceability of all pentest activities.
action_logs_page
Description
Returns a paginated list of ActionLog records for a given pentest.
The action log is the complete record of all commands executed by NodeZero across all hosts during the pentest. Results are sorted by start_time in ascending order by default. Supports filtering by module_id, endpoint_ip, exit_code, start_time, and end_time via the page_input argument.
Response
Returns an ActionLogsPage!
query ActionLogsPage($input: OpInput!, $page_input: PageInput) {
action_logs_page(input: $input, page_input: $page_input) {
action_logs {
...ActionLogPageFragment
}
}
}
fragment ActionLogPageFragment on ActionLog {
uuid
start_time
end_time
endpoint_ip
cmd
module_id
module_name
exit_code
target_h3_names
op_id
}
Examples may not include all available fields for a type.
{
"data": {
"action_logs_page": {
"action_logs": [
{
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"start_time": "2024-01-15T10:05:33Z",
"end_time": "2024-01-15T10:05:34Z",
"endpoint_ip": "10.0.1.25",
"cmd": "nmap -sV -p 445 10.0.1.25",
"module_id": "smb_scanning",
"module_name": "SMB Scanning",
"exit_code": "0",
"target_h3_names": ["10.0.1.25:445"],
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
},
{
"uuid": "efgh5678-efgh-5678-efgh-5678efgh5678",
"start_time": "2024-01-15T10:06:12Z",
"end_time": "2024-01-15T10:06:14Z",
"endpoint_ip": "10.0.1.50",
"cmd": "ldapsearch -x -H ldap://10.0.1.50 -b dc=acme,dc=local",
"module_id": "ldap_enumeration",
"module_name": "LDAP Enumeration",
"exit_code": "0",
"target_h3_names": ["10.0.1.50:389", "DC01.acme.local"],
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}
]
}
}
}
python h3_gql.py ./action_logs_page.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
},
"page_input": {
"page_size": 10
}
}'
Save the example request as ./action_logs_page.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./action_logs_page.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
},
"page_input": {
"page_size": 10
}
}'
Save the example request as ./action_logs_page.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./action_logs_page.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
},
"page_input": {
"page_size": 10
}
}'
Save the example request as ./action_logs_page.graphql.
See h3-cli Examples for installation and usage.
action_logs_count
Description
Returns the total number of ActionLog records for a given pentest.
The action log is the complete record of all commands executed by NodeZero across all hosts during the pentest. Use the page_input argument to apply filters (e.g., by module_id, endpoint_ip, or time range) before counting.
Response
Returns an Int!
query ActionLogsCount($input: OpInput!, $page_input: PageInput) {
action_logs_count(input: $input, page_input: $page_input)
}
Examples may not include all available fields for a type.
{
"data": {
"action_logs_count": 1247
}
}
python h3_gql.py ./action_logs_count.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
},
"page_input": null
}'
Save the example request as ./action_logs_count.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./action_logs_count.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
},
"page_input": null
}'
Save the example request as ./action_logs_count.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./action_logs_count.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
},
"page_input": null
}'
Save the example request as ./action_logs_count.graphql.
See h3-cli Examples for installation and usage.
action_logs_csv_presigned_url
Description
Returns a temporary, presigned URL for downloading the action log as a CSV file.
The action log is the complete record of all commands executed by NodeZero across all hosts during the pentest. The CSV is generated on demand and stored in S3. The presigned URL expires after a short time.
Response
Returns a String
Arguments
input - OpInput!
query ActionLogsCsvPresignedUrl($input: OpInput!) {
action_logs_csv_presigned_url(input: $input)
}
Examples may not include all available fields for a type.
{
"data": {
"action_logs_csv_presigned_url": "https://s3.amazonaws.com/h3-exports/action-logs/1234abcd-1234-abcd-1234-abcd1234abcd.csv?X-Amz-Algorithm=AWS4-HMAC-SHA256&..."
}
}
python h3_gql.py ./action_logs_csv_presigned_url.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}
}'
Save the example request as ./action_logs_csv_presigned_url.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./action_logs_csv_presigned_url.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}
}'
Save the example request as ./action_logs_csv_presigned_url.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./action_logs_csv_presigned_url.graphql '{
"input": {
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}
}'
Save the example request as ./action_logs_csv_presigned_url.graphql.
See h3-cli Examples for installation and usage.
ActionLog
Description
Represents a single action or command executed by NodeZero during a pentest. Each ActionLog entry records a specific command that was run against a target host, including timing information, the attack module that generated the command, and the associated MITRE ATT&CK mappings.
Use action_logs_page to retrieve a paginated list of action logs for a given pentest.
Fields
uuid - String!
start_time - Datetime!
endpoint_uuid - String
endpoint_ip - String
end_time - Datetime!
cmd - String!
module_id - String
module_name - String
module_description - String
module_meta - ModuleMeta
mitre_mappings - [MitreMapping]
target_h3_names - [String]
exit_code - String!
0 typically indicates success; non-zero values indicate an error or alternative outcome. op_id - String!
fragment ActionLogFragment on ActionLog {
uuid
start_time
end_time
endpoint_uuid
endpoint_ip
cmd
module_id
module_name
module_description
module_meta {
id
name
description
}
mitre_mappings {
mitre_tactic_id
mitre_technique_id
mitre_subtechnique_id
}
target_h3_names
exit_code
op_id
}
Examples may not include all available fields for a type.
{
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"start_time": "2024-01-15T10:05:33Z",
"end_time": "2024-01-15T10:05:34Z",
"endpoint_uuid": "efgh5678-efgh-5678-efgh-5678efgh5678",
"endpoint_ip": "10.0.1.25",
"cmd": "nmap -sV -p 445 10.0.1.25",
"module_id": "smb_scanning",
"module_name": "SMB Scanning",
"module_description": "Scans for SMB services and enumerates shares.",
"module_meta": {
"id": "smb_scanning",
"name": "SMB Scanning",
"description": "Scans for SMB services and enumerates shares."
},
"mitre_mappings": [
{
"mitre_tactic_id": "TA0007",
"mitre_technique_id": "T1046",
"mitre_subtechnique_id": null
}
],
"target_h3_names": ["10.0.1.25:445"],
"exit_code": "0",
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}
ActionLogsPage
Description
A paginated list of ActionLog records. Returned by action_logs_page.
Fields
page_info - PageInfo
action_logs - [ActionLog!]!
fragment ActionLogsPageFragment on ActionLogsPage {
page_info {
page_num
page_size
}
action_logs {
uuid
start_time
end_time
endpoint_ip
cmd
module_id
module_name
exit_code
target_h3_names
op_id
}
}
Examples may not include all available fields for a type.
{
"page_info": {
"page_num": 1,
"page_size": 10
},
"action_logs": [
{
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"start_time": "2024-01-15T10:05:33Z",
"end_time": "2024-01-15T10:05:34Z",
"endpoint_ip": "10.0.1.25",
"cmd": "nmap -sV -p 445 10.0.1.25",
"module_id": "smb_scanning",
"module_name": "SMB Scanning",
"exit_code": "0",
"target_h3_names": ["10.0.1.25:445"],
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd"
}
]
}
MitreMapping
Description
Represents a specific combination of a MITRE ATT&CK Tactic, Technique, and optionally a Subtechnique. Each MitreMapping links a NodeZero attack module to the adversary behaviors it emulates, as defined by the MITRE ATT&CK framework. MitreMappings are associated with attack modules via ModuleMeta.
Fields
mitre_tactic_id - String!
TA0043). mitre_tactic - MitreTactic
mitre_technique_id - String!
T1595). mitre_technique - MitreTechnique
mitre_subtechnique_id - String
T1595.001), if applicable. Null when the mapping is at the technique level only. mitre_subtechnique - MitreSubtechnique
fragment MitreMappingFragment on MitreMapping {
mitre_tactic_id
mitre_tactic {
id
name
url
}
mitre_technique_id
mitre_technique {
id
name
url
}
mitre_subtechnique_id
mitre_subtechnique {
id
name
url
}
}
Examples may not include all available fields for a type.
{
"mitre_tactic_id": "TA0007",
"mitre_tactic": {
"id": "TA0007",
"name": "Discovery",
"url": "https://attack.mitre.org/tactics/TA0007/"
},
"mitre_technique_id": "T1046",
"mitre_technique": {
"id": "T1046",
"name": "Network Service Discovery",
"url": "https://attack.mitre.org/techniques/T1046/"
},
"mitre_subtechnique_id": null,
"mitre_subtechnique": null
}
MitreSubtechnique
Description
Represents a MITRE ATT&CK Subtechnique. Subtechniques provide a more granular description of adversary behavior within a parent MitreTechnique. For example, "Scanning IP Blocks" is a subtechnique of "Active Scanning."
Fields
id - String!
mitre_technique_id - String
name - String
description - String
url - String
fragment MitreSubtechniqueFragment on MitreSubtechnique {
id
mitre_technique_id
name
description
url
}
Examples may not include all available fields for a type.
{
"id": "T1595.001",
"mitre_technique_id": "T1595",
"name": "Scanning IP Blocks",
"description": "Adversaries may scan victim IP blocks to gather information that can be used during targeting.",
"url": "https://attack.mitre.org/techniques/T1595/001/"
}
MitreTactic
Description
Represents a MITRE ATT&CK Tactic. Tactics represent the adversary's tactical objective -- the reason for performing an action (e.g., Reconnaissance, Initial Access, Lateral Movement). Tactics are the columns in the MITRE ATT&CK Matrix.
fragment MitreTacticFragment on MitreTactic {
id
name
description
url
}
Examples may not include all available fields for a type.
{
"id": "TA0043",
"name": "Reconnaissance",
"description": "The adversary is trying to gather information they can use to plan future operations.",
"url": "https://attack.mitre.org/tactics/TA0043/"
}
MitreTechnique
Description
Represents a MITRE ATT&CK Technique. Techniques describe the specific method an adversary uses to achieve a tactical objective (e.g., Active Scanning, Brute Force). A technique belongs to one or more MitreTactics and may have more granular MitreSubtechniques.
Fields
fragment MitreTechniqueFragment on MitreTechnique {
id
name
description
url
}
Examples may not include all available fields for a type.
{
"id": "T1595",
"name": "Active Scanning",
"description": "Adversaries may execute active reconnaissance scans to gather information that can be used during targeting.",
"url": "https://attack.mitre.org/techniques/T1595/"
}
ModuleInstance
Description
Represents a specific execution of a NodeZero attack module during a pentest. Each ModuleInstance captures the lifecycle of one module run, including when it started and completed, whether it succeeded, and the commands it executed.
Use ModuleInstance.action_logs to retrieve the individual commands executed by this module instance.
Fields
uuid - String!
created_at - Datetime!
started_at for the actual execution start time. module_id - String!
options - String
started_at - Datetime!
ended_at - Datetime!
success_flag - Boolean
true if the module ran to completion without errors. error_msg - String
op_id - String!
name - String
description - String
action_logs_count - Int
action_logs - [ActionLog]
module_meta - ModuleMeta
fragment ModuleInstanceFragment on ModuleInstance {
uuid
module_id
name
description
created_at
started_at
ended_at
success_flag
error_msg
options
op_id
action_logs_count
module_meta {
id
name
description
}
}
Examples may not include all available fields for a type.
{
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"module_id": "smb_scanning",
"name": "SMB Scanning",
"description": "Scans for SMB services and enumerates shares.",
"created_at": "2024-01-15T10:00:00Z",
"started_at": "2024-01-15T10:05:00Z",
"ended_at": "2024-01-15T10:05:45Z",
"success_flag": true,
"error_msg": null,
"options": "--timeout 30",
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"action_logs_count": 12,
"module_meta": {
"id": "smb_scanning",
"name": "SMB Scanning",
"description": "Scans for SMB services and enumerates shares."
}
}
ModuleMeta
Description
Static metadata describing a NodeZero attack module. Each attack module performs a specific offensive technique (such as host discovery, credential brute-forcing, or privilege escalation) and is mapped to one or more MITRE ATT&CK tactics, techniques, and subtechniques.
ModuleMeta is referenced by ActionLog and ModuleInstance to provide context about which module generated a given action or execution.
Fields
id - String!
name - String
description - String
mitre_mappings - [MitreMapping]
fragment ModuleMetaFragment on ModuleMeta {
id
name
description
mitre_mappings {
mitre_tactic_id
mitre_technique_id
mitre_subtechnique_id
}
}
Examples may not include all available fields for a type.
{
"id": "host_discovery",
"name": "Host Discovery",
"description": "The Host Discovery module finds assets on the network by scanning for active hosts.",
"mitre_mappings": [
{
"mitre_tactic_id": "TA0007",
"mitre_technique_id": "T1046",
"mitre_subtechnique_id": null
},
{
"mitre_tactic_id": "TA0043",
"mitre_technique_id": "T1595",
"mitre_subtechnique_id": "T1595.001"
}
]
}
Pentesting: Op Compare
Compare weaknesses between two pentests to identify new, resolved, and persistent vulnerabilities. Track security posture changes over time and measure remediation effectiveness.
weaknesses_diff_page
Description
Returns a paginated list of Weakness records that differ between two pentests.
Only weaknesses that are present in one pentest but not the other are included. Each Weakness record in the result includes a diff_status field set to either ADDED or REMOVED.
A weakness with diff_status: REMOVED was present in the first pentest (OpDiffInput.op_id_1) but not the second. A weakness with diff_status: ADDED was present in the second pentest (OpDiffInput.op_id_2) but not the first.
If the diff data has not yet been computed for the given pair of pentests, it will be generated on demand before returning results.
Response
Returns a WeaknessesDiffPage!
Arguments
op_diff_input - OpDiffInput!
page_input - PageInput
query WeaknessesDiffPage(
$op_diff_input: OpDiffInput!,
$page_input: PageInput
) {
weaknesses_diff_page(
op_diff_input: $op_diff_input,
page_input: $page_input
) {
weaknesses {
...WeaknessDiffFragment
}
}
}
fragment WeaknessDiffFragment on Weakness {
uuid
vuln_id
vuln_name
vuln_short_name
op_id
ip
severity
score
diff_status
affected_asset_display_name
has_proof
portal_url
}
Examples may not include all available fields for a type.
{
"data": {
"weaknesses_diff_page": {
"weaknesses": [
{
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"vuln_id": "h3-2024-0001",
"vuln_name": "SMB Signing Not Required",
"vuln_short_name": "SMBSigningNotRequired",
"op_id": "5678efgh-5678-efgh-5678-efgh5678efgh",
"ip": "10.0.1.25",
"severity": "MEDIUM",
"score": 6.5,
"diff_status": "ADDED",
"affected_asset_display_name": "10.0.1.25",
"has_proof": true,
"portal_url": "https://portal.yourorg.com/weaknesses/abcd1234-abcd-1234-abcd-1234abcd1234"
},
{
"uuid": "efgh5678-efgh-5678-efgh-5678efgh5678",
"vuln_id": "CVE-2021-34527",
"vuln_name": "PrintNightmare - Windows Print Spooler RCE",
"vuln_short_name": "PrintNightmare",
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"ip": "10.0.1.50",
"severity": "CRITICAL",
"score": 9.8,
"diff_status": "REMOVED",
"affected_asset_display_name": "DC01.acme.local (10.0.1.50)",
"has_proof": true,
"portal_url": "https://portal.yourorg.com/weaknesses/efgh5678-efgh-5678-efgh-5678efgh5678"
}
]
}
}
}
python h3_gql.py ./weaknesses_diff_page.graphql '{
"op_diff_input": {
"op_id_1": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_id_2": "5678abcd-5678-abcd-5678-abcd5678abcd"
},
"page_input": {
"page_size": 10
}
}'
Save the example request as ./weaknesses_diff_page.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./weaknesses_diff_page.graphql '{
"op_diff_input": {
"op_id_1": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_id_2": "5678abcd-5678-abcd-5678-abcd5678abcd"
},
"page_input": {
"page_size": 10
}
}'
Save the example request as ./weaknesses_diff_page.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./weaknesses_diff_page.graphql '{
"op_diff_input": {
"op_id_1": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_id_2": "5678abcd-5678-abcd-5678-abcd5678abcd"
},
"page_input": {
"page_size": 10
}
}'
Save the example request as ./weaknesses_diff_page.graphql.
See h3-cli Examples for installation and usage.
weaknesses_diff_stats
Description
Returns aggregate statistics summarizing the differences in weaknesses between two pentests, including the count of added, removed, and unchanged weaknesses. See weaknesses_diff_page for the full paginated diff.
If the diff data has not yet been computed for the given pair of pentests, it will be generated on demand before returning results.
Response
Returns a DiffStats!
Arguments
op_diff_input - OpDiffInput!
page_input - PageInput
query WeaknessesDiffStats(
$op_diff_input: OpDiffInput!,
$page_input: PageInput
) {
weaknesses_diff_stats(
op_diff_input: $op_diff_input,
page_input: $page_input
) {
added_count
removed_count
unchanged_count
}
}
Examples may not include all available fields for a type.
{
"data": {
"weaknesses_diff_stats": {
"added_count": 8,
"removed_count": 3,
"unchanged_count": 42
}
}
}
python h3_gql.py ./weaknesses_diff_stats.graphql '{
"op_diff_input": {
"op_id_1": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_id_2": "5678abcd-5678-abcd-5678-abcd5678abcd"
},
"page_input": null
}'
Save the example request as ./weaknesses_diff_stats.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./weaknesses_diff_stats.graphql '{
"op_diff_input": {
"op_id_1": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_id_2": "5678abcd-5678-abcd-5678-abcd5678abcd"
},
"page_input": null
}'
Save the example request as ./weaknesses_diff_stats.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./weaknesses_diff_stats.graphql '{
"op_diff_input": {
"op_id_1": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_id_2": "5678abcd-5678-abcd-5678-abcd5678abcd"
},
"page_input": null
}'
Save the example request as ./weaknesses_diff_stats.graphql.
See h3-cli Examples for installation and usage.
weaknesses_diff_csv_url
Description
Returns a temporary, presigned URL for downloading a CSV file containing the diff of weaknesses between two pentests. The CSV is generated on demand and the presigned URL expires after a short time. See weaknesses_diff_page for more details on how the diff is computed.
Response
Returns a String
Arguments
op_diff_input - OpDiffInput!
query WeaknessesDiffCsvUrl($op_diff_input: OpDiffInput!) {
weaknesses_diff_csv_url(op_diff_input: $op_diff_input)
}
Examples may not include all available fields for a type.
{
"data": {
"weaknesses_diff_csv_url": "https://s3.amazonaws.com/h3-exports/weaknesses-diff/1234abcd-1234-abcd-1234-abcd1234abcd.csv?X-Amz-Algorithm=AWS4-HMAC-SHA256&..."
}
}
python h3_gql.py ./weaknesses_diff_csv_url.graphql '{
"op_diff_input": {
"op_id_1": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_id_2": "5678abcd-5678-abcd-5678-abcd5678abcd"
}
}'
Save the example request as ./weaknesses_diff_csv_url.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./weaknesses_diff_csv_url.graphql '{
"op_diff_input": {
"op_id_1": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_id_2": "5678abcd-5678-abcd-5678-abcd5678abcd"
}
}'
Save the example request as ./weaknesses_diff_csv_url.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./weaknesses_diff_csv_url.graphql '{
"op_diff_input": {
"op_id_1": "1234abcd-1234-abcd-1234-abcd1234abcd",
"op_id_2": "5678abcd-5678-abcd-5678-abcd5678abcd"
}
}'
Save the example request as ./weaknesses_diff_csv_url.graphql.
See h3-cli Examples for installation and usage.
DiffStats
Description
Aggregate statistics summarizing the differences between two pentests. Returned by weaknesses_diff_stats.
Fields
added_count - Int
op_id_2 but not in op_id_1). removed_count - Int
op_id_1 but not in op_id_2). unchanged_count - Int
fragment DiffStatsFragment on DiffStats {
added_count
removed_count
unchanged_count
}
Examples may not include all available fields for a type.
{
"added_count": 8,
"removed_count": 3,
"unchanged_count": 42
}
DiffStatus
Description
Indicates whether a record was added or removed when comparing two pentests. Used in the weaknesses_diff_page results where each Weakness record includes a diff_status field set to one of these values.
Values
ADDED
op_id_1) but IS present in the second pentest (op_id_2), indicating it is a newly discovered weakness. REMOVED
op_id_1) but is NOT present in the second pentest (op_id_2), indicating it has been resolved or is no longer detected. Example
"ADDED"
OpDiffInput
Description
Input type specifying the two pentests to compare. Used by weaknesses_diff_page, weaknesses_diff_stats, weaknesses_diff_csv_url, and other diff-related APIs.
Fields
op_id_1 - String!
REMOVED. op_id_2 - String!
ADDED. # Example 1: Compare weaknesses between two pentests
query WeaknessesDiff($op_diff_input: OpDiffInput! = {
op_id_1: "1234abcd-1234-abcd-1234-abcd1234abcd",
op_id_2: "5678abcd-5678-abcd-5678-abcd5678abcd"
}, $page_input: PageInput) {
weaknesses_diff_page(
op_diff_input: $op_diff_input,
page_input: $page_input
) {
weaknesses {
uuid
vuln_id
vuln_name
diff_status
severity
score
}
}
}
# Example 2: Get diff stats between two pentests
query WeaknessesDiffStats($op_diff_input: OpDiffInput! = {
op_id_1: "1234abcd-1234-abcd-1234-abcd1234abcd",
op_id_2: "5678abcd-5678-abcd-5678-abcd5678abcd"
}) {
weaknesses_diff_stats(op_diff_input: $op_diff_input) {
added_count
removed_count
unchanged_count
}
}
Examples may not include all available fields for a type.
WeaknessesDiffPage
Description
A paginated list of Weakness records representing differences between two pentests. Returned by weaknesses_diff_page. Only weaknesses that differ between the two pentests are included; weaknesses common to both are excluded.
Fields
page_info - PageInfo
weaknesses - [Weakness!]!
fragment WeaknessesDiffPageFragment on WeaknessesDiffPage {
page_info {
page_num
page_size
}
weaknesses {
uuid
vuln_id
vuln_name
vuln_short_name
op_id
ip
severity
score
diff_status
affected_asset_display_name
has_proof
portal_url
}
}
Examples may not include all available fields for a type.
{
"page_info": {
"page_num": 1,
"page_size": 10
},
"weaknesses": [
{
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"vuln_id": "h3-2024-0001",
"vuln_name": "SMB Signing Not Required",
"vuln_short_name": "SMBSigningNotRequired",
"op_id": "5678efgh-5678-efgh-5678-efgh5678efgh",
"ip": "10.0.1.25",
"severity": "MEDIUM",
"score": 6.5,
"diff_status": "ADDED",
"affected_asset_display_name": "10.0.1.25",
"has_proof": true,
"portal_url": "https://portal.yourorg.com/weaknesses/abcd1234-abcd-1234-abcd-1234abcd1234"
},
{
"uuid": "efgh5678-efgh-5678-efgh-5678efgh5678",
"vuln_id": "CVE-2021-34527",
"vuln_name": "PrintNightmare - Windows Print Spooler RCE",
"vuln_short_name": "PrintNightmare",
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"ip": "10.0.1.50",
"severity": "CRITICAL",
"score": 9.8,
"diff_status": "REMOVED",
"affected_asset_display_name": "DC01.acme.local (10.0.1.50)",
"has_proof": true,
"portal_url": "https://portal.yourorg.com/weaknesses/efgh5678-efgh-5678-efgh-5678efgh5678"
}
]
}
Vuln Management Hub
Track vulnerability trends and manage remediation over time. Access weakness series for historical vulnerability data, query assets across your environment, organize findings through custom perspectives, and run focused validation campaigns. The Vuln Management Hub provides a comprehensive view of your security posture evolution.
Vuln Management Hub: Weakness Series
Track vulnerability trends over time with weakness series that aggregate findings across multiple pentests. View historical data, apply annotations and tags for tracking, manage tickets, and analyze remediation progress for persistent vulnerabilities.
weakness_series_page
Description
Returns a paginated list of WeaknessSeries records for the current client account.
A weakness series tracks a single weakness on a single asset across multiple pentests over time, enabling vulnerability management workflows such as tracking remediation progress and identifying regressions.
Use page_input to filter by severity, status, vulnerability type, and other fields. Use as_of_date to view the state of weakness series as of a specific date.
Response
Returns a WeaknessSeriesPage!
Arguments
page_input - PageInput!
as_of_date - Date
query WeaknessSeriesPage($page_input: PageInput!, $as_of_date: Date) {
weakness_series_page(
page_input: $page_input
as_of_date: $as_of_date
) {
weakness_series {
...WeaknessSeriesFragment
}
}
}
fragment WeaknessSeriesFragment on WeaknessSeries {
name
vuln_id
vuln_name
vuln_short_name
vuln_category
severity
status
score
annotation_status
is_one_click_verify
affected_asset_name
ip
first_seen_date
last_seen_date
weakness_series_found_count
attack_paths_count
total_impacts_count
business_risks
last_found_op_types
}
Examples may not include all available fields for a type.
{
"data": {
"weakness_series_page": {
"weakness_series": [
{
"name": "SMB Signing Not Required on 10.0.1.25:445",
"vuln_id": "h3-2024-0001",
"vuln_name": "SMB Signing Not Required",
"vuln_short_name": "SMBSigningNotRequired",
"vuln_category": "SECURITY_MISCONFIGURATION",
"severity": "MEDIUM",
"status": "OPEN",
"score": 6.5,
"annotation_status": null,
"is_one_click_verify": true,
"affected_asset_name": "10.0.1.25:445",
"ip": "10.0.1.25",
"first_seen_date": "2024-01-15",
"last_seen_date": "2024-06-15",
"weakness_series_found_count": 5,
"attack_paths_count": 3,
"total_impacts_count": 4,
"business_risks": ["Credential Exposure", "Lateral Movement"],
"last_found_op_types": ["NodeZero"]
},
{
"name": "PrintNightmare on DC01.acme.local:135",
"vuln_id": "CVE-2021-34527",
"vuln_name": "PrintNightmare - Windows Print Spooler RCE",
"vuln_short_name": "PrintNightmare",
"vuln_category": "VULNERABILITY",
"severity": "CRITICAL",
"status": "MITIGATED",
"score": 9.8,
"annotation_status": "FIXED",
"is_one_click_verify": true,
"affected_asset_name": "DC01.acme.local:135",
"ip": "10.0.1.50",
"first_seen_date": "2024-02-10",
"last_seen_date": "2024-05-20",
"weakness_series_found_count": 3,
"attack_paths_count": 5,
"total_impacts_count": 7,
"business_risks": ["Ransomware Exposure"],
"last_found_op_types": ["NodeZero"]
}
]
}
}
}
python h3_gql.py ./weakness_series_page.graphql '{
"page_input": {
"page_size": 10
},
"as_of_date": "2024-06-15"
}'
Save the example request as ./weakness_series_page.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./weakness_series_page.graphql '{
"page_input": {
"page_size": 10
},
"as_of_date": "2024-06-15"
}'
Save the example request as ./weakness_series_page.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./weakness_series_page.graphql '{
"page_input": {
"page_size": 10
},
"as_of_date": "2024-06-15"
}'
Save the example request as ./weakness_series_page.graphql.
See h3-cli Examples for installation and usage.
weakness_series_count
Description
Returns the total number of WeaknessSeries records matching the given filters for the current client account.
Use page_input to apply filters before counting.
Response
Returns an Int!
Arguments
page_input - PageInput!
as_of_date - Date
query WeaknessSeriesCount($page_input: PageInput!, $as_of_date: Date) {
weakness_series_count(
page_input: $page_input
as_of_date: $as_of_date
)
}
Examples may not include all available fields for a type.
{
"data": {
"weakness_series_count": 150
}
}
python h3_gql.py ./weakness_series_count.graphql '{
"page_input": {
"page_size": 10
},
"as_of_date": "2024-06-15"
}'
Save the example request as ./weakness_series_count.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./weakness_series_count.graphql '{
"page_input": {
"page_size": 10
},
"as_of_date": "2024-06-15"
}'
Save the example request as ./weakness_series_count.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./weakness_series_count.graphql '{
"page_input": {
"page_size": 10
},
"as_of_date": "2024-06-15"
}'
Save the example request as ./weakness_series_count.graphql.
See h3-cli Examples for installation and usage.
weakness_series_annotations_page
Description
Returns a paginated list of WeaknessSeriesAnnotations for the current client account. Annotations capture user-applied status updates, notes, and tags on weakness series records.
Response
Returns a WeaknessSeriesAnnotationsPage!
Arguments
page_input - PageInput!
query WeaknessSeriesAnnotationsPage($page_input: PageInput!) {
weakness_series_annotations_page(page_input: $page_input) {
annotations {
...WeaknessSeriesAnnotationFragment
}
}
}
fragment WeaknessSeriesAnnotationFragment on WeaknessSeriesAnnotation {
uuid
row_created_at
row_updated_at
weakness_series_uuid
annotation_uuid
annotation_status
annotation_text
affected_asset_short_name
}
Examples may not include all available fields for a type.
{
"data": {
"weakness_series_annotations_page": {
"annotations": [
{
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"row_created_at": "2024-03-15T10:30:00Z",
"row_updated_at": "2024-03-16T14:22:00Z",
"weakness_series_uuid": "a1b2c3d4-a1b2-c3d4-a1b2-c3d4a1b2c3d4",
"annotation_uuid": "b2c3d4e5-b2c3-d4e5-b2c3-d4e5b2c3d4e5",
"annotation_status": "FIXED",
"annotation_text": "Patched in maintenance window 2024-03-15",
"affected_asset_short_name": "10.0.1.25:445"
},
{
"uuid": "efgh5678-efgh-5678-efgh-5678efgh5678",
"row_created_at": "2024-04-01T08:00:00Z",
"row_updated_at": null,
"weakness_series_uuid": "c3d4e5f6-c3d4-e5f6-c3d4-e5f6c3d4e5f6",
"annotation_uuid": "d4e5f6a7-d4e5-f6a7-d4e5-f6a7d4e5f6a7",
"annotation_status": "RISK_ACCEPTED",
"annotation_text": "Risk accepted per security review",
"affected_asset_short_name": "DC01.acme.local:135"
}
]
}
}
}
python h3_gql.py ./weakness_series_annotations_page.graphql '{
"page_input": {
"page_size": 10
}
}'
Save the example request as ./weakness_series_annotations_page.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./weakness_series_annotations_page.graphql '{
"page_input": {
"page_size": 10
}
}'
Save the example request as ./weakness_series_annotations_page.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./weakness_series_annotations_page.graphql '{
"page_input": {
"page_size": 10
}
}'
Save the example request as ./weakness_series_annotations_page.graphql.
See h3-cli Examples for installation and usage.
weakness_series_annotations_count
Description
Returns the total number of WeaknessSeriesAnnotations for the current client account.
Response
Returns an Int!
Arguments
page_input - PageInput!
query WeaknessSeriesAnnotationsCount($page_input: PageInput!) {
weakness_series_annotations_count(page_input: $page_input)
}
Examples may not include all available fields for a type.
{
"data": {
"weakness_series_annotations_count": 42
}
}
python h3_gql.py ./weakness_series_annotations_count.graphql '{
"page_input": {
"page_size": 10
}
}'
Save the example request as ./weakness_series_annotations_count.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./weakness_series_annotations_count.graphql '{
"page_input": {
"page_size": 10
}
}'
Save the example request as ./weakness_series_annotations_count.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./weakness_series_annotations_count.graphql '{
"page_input": {
"page_size": 10
}
}'
Save the example request as ./weakness_series_annotations_count.graphql.
See h3-cli Examples for installation and usage.
apply_annotations_to_weakness_series
Description
Applies one or more Annotations to WeaknessSeries records. Each AnnotationInput specifies the target weakness series UUID, status, text, and optional tags.
If an annotation_uuid is provided in the input, the existing annotation is updated; otherwise, a new annotation is created. Each weakness series can have at most one annotation. Returns the count and list of annotations that were applied.
Response
Returns an ApplyAnnotationOutput!
Arguments
inputs - [AnnotationInput!]!
mutation ApplyAnnotationsToWeaknessSeries(
$inputs: [AnnotationInput!]!
) {
apply_annotations_to_weakness_series(inputs: $inputs) {
annotations_count
annotations {
uuid
target_entity_uuid
target_entity_type
text
status
risk_accepted
is_suppressed
}
}
}
Examples may not include all available fields for a type.
{
"data": {
"apply_annotations_to_weakness_series": {
"annotations_count": 1,
"annotations": [
{
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"target_entity_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"target_entity_type": "WeaknessSeries",
"text": "Patched in maintenance window",
"status": "FIXED",
"risk_accepted": false,
"is_suppressed": false
}
]
}
}
}
python h3_gql.py ./apply_annotations_to_weakness_series.graphql '{
"inputs": [
{
"target_entity_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"target_entity_type": "WeaknessSeries",
"text": "Patched in maintenance window",
"status": "FIXED"
}
]
}'
Save the example request as ./apply_annotations_to_weakness_series.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./apply_annotations_to_weakness_series.graphql '{
"inputs": [
{
"target_entity_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"target_entity_type": "WeaknessSeries",
"text": "Patched in maintenance window",
"status": "FIXED"
}
]
}'
Save the example request as ./apply_annotations_to_weakness_series.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./apply_annotations_to_weakness_series.graphql '{
"inputs": [
{
"target_entity_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"target_entity_type": "WeaknessSeries",
"text": "Patched in maintenance window",
"status": "FIXED"
}
]
}'
Save the example request as ./apply_annotations_to_weakness_series.graphql.
See h3-cli Examples for installation and usage.
remove_annotations_from_weakness_series
Description
Removes all annotations from the specified WeaknessSeries records. Returns true if at least one annotation was successfully removed, false if no annotations were found for the given UUIDs.
Response
Returns a Boolean!
Arguments
weakness_series_uuids - [String!]!
mutation RemoveAnnotationsFromWeaknessSeries(
$weakness_series_uuids: [String!]!
) {
remove_annotations_from_weakness_series(
weakness_series_uuids: $weakness_series_uuids
)
}
Examples may not include all available fields for a type.
{
"data": {
"remove_annotations_from_weakness_series": true
}
}
python h3_gql.py ./remove_annotations_from_weakness_series.graphql '{
"weakness_series_uuids": [
"1234abcd-1234-abcd-1234-abcd1234abcd"
]
}'
Save the example request as ./remove_annotations_from_weakness_series.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./remove_annotations_from_weakness_series.graphql '{
"weakness_series_uuids": [
"1234abcd-1234-abcd-1234-abcd1234abcd"
]
}'
Save the example request as ./remove_annotations_from_weakness_series.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./remove_annotations_from_weakness_series.graphql '{
"weakness_series_uuids": [
"1234abcd-1234-abcd-1234-abcd1234abcd"
]
}'
Save the example request as ./remove_annotations_from_weakness_series.graphql.
See h3-cli Examples for installation and usage.
tickets_csv_presigned_url
Description
Returns a temporary, presigned URL for downloading a CSV file containing all tickets for the current client account across all pentests. The presigned URL expires after a short time.
The CSV format is documented under TicketCSV.
Response
Returns a String
Arguments
page_input - PageInput
query TicketsCsvPresignedUrl($page_input: PageInput) {
tickets_csv_presigned_url(page_input: $page_input)
}
Examples may not include all available fields for a type.
{
"data": {
"tickets_csv_presigned_url": "https://s3.amazonaws.com/tickets/1234abcd-1234-abcd-1234-abcd1234abcd.csv?X-Amz-Expires=3600"
}
}
python h3_gql.py ./tickets_csv_presigned_url.graphql '{
"page_input": {
"page_size": 100
}
}'
Save the example request as ./tickets_csv_presigned_url.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./tickets_csv_presigned_url.graphql '{
"page_input": {
"page_size": 100
}
}'
Save the example request as ./tickets_csv_presigned_url.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./tickets_csv_presigned_url.graphql '{
"page_input": {
"page_size": 100
}
}'
Save the example request as ./tickets_csv_presigned_url.graphql.
See h3-cli Examples for installation and usage.
weakness_series_facets
Description
Returns the available filter facets for WeaknessSeries queries. Each facet provides a list of distinct values and their counts in the current dataset, enabling construction of filtered list UIs.
Response
Returns a WeaknessSeriesFacets!
query WeaknessSeriesFacets($page_input: PageInput, $as_of_date: Date) {
weakness_series_facets(
page_input: $page_input
as_of_date: $as_of_date
) {
vuln_short_name {
label
value
value_count
}
op_template_name {
label
value
value_count
}
business_risks {
label
value
value_count
}
vuln_threat_actor_names {
label
value
value_count
}
downstream_impact_types {
label
value
value_count
}
}
}
Examples may not include all available fields for a type.
{
"data": {
"weakness_series_facets": {
"vuln_short_name": [
{ "label": "SMB Signing Not Required", "value": "SMBSigningNotRequired", "value_count": 12 },
{ "label": "PrintNightmare", "value": "PrintNightmare", "value_count": 3 }
],
"op_template_name": [
{ "label": "Weekly Internal Pentest", "value": "Weekly Internal Pentest", "value_count": 15 }
],
"business_risks": [
{ "label": "Credential Exposure", "value": "Credential Exposure", "value_count": 8 },
{ "label": "Lateral Movement", "value": "Lateral Movement", "value_count": 5 }
],
"vuln_threat_actor_names": [
{ "label": "APT29", "value": "APT29", "value_count": 2 }
],
"downstream_impact_types": [
{ "label": "Ransomware Exposure", "value": "RansomwareExposure", "value_count": 4 }
]
}
}
}
python h3_gql.py ./weakness_series_facets.graphql '{
"page_input": {
"page_size": 10
},
"as_of_date": "2024-06-15"
}'
Save the example request as ./weakness_series_facets.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./weakness_series_facets.graphql '{
"page_input": {
"page_size": 10
},
"as_of_date": "2024-06-15"
}'
Save the example request as ./weakness_series_facets.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./weakness_series_facets.graphql '{
"page_input": {
"page_size": 10
},
"as_of_date": "2024-06-15"
}'
Save the example request as ./weakness_series_facets.graphql.
See h3-cli Examples for installation and usage.
weakness_series_csv_presigned_url
Description
Returns a temporary, presigned URL for downloading the WeaknessSeries data as a CSV file. The CSV is generated on demand and the presigned URL expires after a short time. Use page_input to apply filters to the exported data.
Response
Returns a String
Arguments
page_input - PageInput!
as_of_date - Date
query WeaknessSeriesCsvPresignedUrl(
$page_input: PageInput!
$as_of_date: Date
) {
weakness_series_csv_presigned_url(
page_input: $page_input
as_of_date: $as_of_date
)
}
Examples may not include all available fields for a type.
{
"data": {
"weakness_series_csv_presigned_url": "https://s3.amazonaws.com/weakness-series/1234abcd-1234-abcd-1234-abcd1234abcd.csv?X-Amz-Expires=3600"
}
}
python h3_gql.py ./weakness_series_csv_presigned_url.graphql '{
"page_input": {
"page_size": 100
},
"as_of_date": "2024-06-15"
}'
Save the example request as ./weakness_series_csv_presigned_url.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./weakness_series_csv_presigned_url.graphql '{
"page_input": {
"page_size": 100
},
"as_of_date": "2024-06-15"
}'
Save the example request as ./weakness_series_csv_presigned_url.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./weakness_series_csv_presigned_url.graphql '{
"page_input": {
"page_size": 100
},
"as_of_date": "2024-06-15"
}'
Save the example request as ./weakness_series_csv_presigned_url.graphql.
See h3-cli Examples for installation and usage.
weakness_series_downstream_impacts_count
Description
Returns the total number of downstream impacts for a given set of WeaknessSeries UUIDs. Downstream impacts represent the systems and data that could be compromised if this weakness is exploited.
Response
Returns an Int!
Arguments
page_input - PageInput!
weakness_series_uuids - [String!]
query WeaknessSeriesDownstreamImpactsCount(
$page_input: PageInput!
$weakness_series_uuids: [String!]
) {
weakness_series_downstream_impacts_count(
page_input: $page_input
weakness_series_uuids: $weakness_series_uuids
)
}
Examples may not include all available fields for a type.
{
"data": {
"weakness_series_downstream_impacts_count": 7
}
}
python h3_gql.py ./weakness_series_downstream_impacts_count.graphql '{
"page_input": {
"page_size": 10
},
"weakness_series_uuids": [
"1234abcd-1234-abcd-1234-abcd1234abcd"
]
}'
Save the example request as ./weakness_series_downstream_impacts_count.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./weakness_series_downstream_impacts_count.graphql '{
"page_input": {
"page_size": 10
},
"weakness_series_uuids": [
"1234abcd-1234-abcd-1234-abcd1234abcd"
]
}'
Save the example request as ./weakness_series_downstream_impacts_count.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./weakness_series_downstream_impacts_count.graphql '{
"page_input": {
"page_size": 10
},
"weakness_series_uuids": [
"1234abcd-1234-abcd-1234-abcd1234abcd"
]
}'
Save the example request as ./weakness_series_downstream_impacts_count.graphql.
See h3-cli Examples for installation and usage.
WeaknessSeries
Description
A WeaknessSeries tracks a single weakness on a single asset across multiple pentests over time.
It aggregates weakness findings across an entire series of pentests (an OpSeries), enabling vulnerability management workflows such as monitoring remediation progress, identifying regressions, and applying Annotations to track status.
Use weakness_series_page to retrieve a paginated list of weakness series records.
Fields
name - String!
last_weakness_uuid - String!
first_found_at - Date!
first_seen_at. Use first_seen_at.
first_seen_at - Datetime!
first_seen_date - Date!
first_found_op_id - String!
first_found_op_type - String!
last_found_at - Date!
last_seen_at. Use last_seen_at.
last_seen_at - Datetime!
last_seen_date - Date!
vuln_id - String
vuln_name - String
vuln_short_name - String
vuln_category - String
weakness_series_found_count - Int!
status - WeaknessSeriesOpStatus
severity - Severity
is_one_click_verify - Boolean
affected_asset_name - String
ip - String
port - Int
protocol - String
tcp, udp), if available. last_found_op_id - String!
last_pentested_op_id - String!
annotation - Annotation
annotation_status - AnnotationStatus
min_time_to_finding_s - Int
min_time_to_finding_hms - String
HH:MM:SS. attack_paths_count - Int!
credentials_count - Int!
impacts_count - Int!
critical_impacts_count - Int!
critical_impacts_percentage - Float!
total_impacts_count - Int!
severity_ranking - Int!
status_ranking - Int!
annotation_status_ranking - Int
score - Float
vuln_threat_actor_names - [String!]!
business_risks - [String!]!
Data Breach, Ransomware). downstream_impact_types_and_counts - [String!]
ImpactType,count (e.g., ["RansomwareExposure,2", "SensitiveDataExposure,2"]). The downstream impacts and counts are from the most recent pentest containing this weakness. last_found_op_types - [OpType!]
fragment WeaknessSeriesFragment on WeaknessSeries {
name
vuln_id
vuln_name
vuln_short_name
vuln_category
severity
status
score
annotation_status
is_one_click_verify
affected_asset_name
ip
first_found_at
last_found_at
first_seen_date
last_seen_date
first_found_op_id
first_found_op_type
last_found_op_id
last_pentested_op_id
last_weakness_uuid
weakness_series_found_count
attack_paths_count
credentials_count
total_impacts_count
critical_impacts_count
critical_impacts_percentage
min_time_to_finding_hms
business_risks
last_found_op_types
}
Examples may not include all available fields for a type.
{
"name": "SMB Signing Not Required on 10.0.1.25:445",
"vuln_id": "h3-2024-0001",
"vuln_name": "SMB Signing Not Required",
"vuln_short_name": "SMBSigningNotRequired",
"vuln_category": "SECURITY_MISCONFIGURATION",
"severity": "MEDIUM",
"status": "OPEN",
"score": 6.5,
"annotation_status": null,
"is_one_click_verify": true,
"affected_asset_name": "10.0.1.25:445",
"ip": "10.0.1.25",
"first_found_at": "2024-01-15T14:30:00Z",
"last_found_at": "2024-06-15T09:15:33Z",
"first_seen_date": "2024-01-15",
"last_seen_date": "2024-06-15",
"first_found_op_id": "a1b2c3d4-a1b2-c3d4-a1b2-c3d4a1b2c3d4",
"first_found_op_type": "NodeZero",
"last_found_op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"last_pentested_op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"last_weakness_uuid": "d4e5f6a7-d4e5-f6a7-d4e5-f6a7d4e5f6a7",
"weakness_series_found_count": 5,
"attack_paths_count": 3,
"credentials_count": 2,
"total_impacts_count": 4,
"critical_impacts_count": 1,
"critical_impacts_percentage": 25.0,
"min_time_to_finding_hms": "01:23:45",
"business_risks": ["Credential Exposure", "Lateral Movement"],
"last_found_op_types": ["NodeZero"]
}
Annotation
Description
Represents a user-applied annotation on a WeaknessSeries record. Annotations track the remediation lifecycle of a weakness, including status (e.g., FIXED, TO_DO, RISK_ACCEPTED), free-text notes, risk suppression dates, and user-defined Tags.
Use apply_annotations_to_weakness_series to create or update annotations.
Fields
uuid - ID!
target_entity_uuid - StringNotEmpty!
text - StringNotEmpty
status - AnnotationStatus
risk_accepted - Boolean!
suppress_until - Date
is_suppressed - Boolean!
suppress_until date. fragment AnnotationFragment on Annotation {
uuid
target_entity_uuid
target_entity_type
text
status
risk_accepted
suppress_until
is_suppressed
}
Examples may not include all available fields for a type.
{
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"target_entity_uuid": "a1b2c3d4-a1b2-c3d4-a1b2-c3d4a1b2c3d4",
"target_entity_type": "WeaknessSeries",
"text": "Patched in maintenance window 2024-03-15",
"status": "FIXED",
"risk_accepted": false,
"suppress_until": null,
"is_suppressed": false
}
AnnotationInput
Fields
annotation_uuid - StringNotEmpty
target_entity_uuid - StringNotEmpty!
text - StringNotEmpty
status is RISK_ACCEPTED. status - AnnotationStatus
suppress_until_epoch - Float
remove_suppression - Boolean
true to clear any existing risk suppression on this annotation. tag_uuids - [StringNotEmpty]
# Example 1: Create a new annotation
mutation CreateAnnotation($inputs: [AnnotationInput!]! = [
{
target_entity_uuid: "1234abcd-1234-abcd-1234-abcd1234abcd",
target_entity_type: "WeaknessSeries",
text: "Patched in maintenance window",
status: "FIXED"
}
]) {
apply_annotations_to_weakness_series(inputs: $inputs) {
annotations_count
annotations {
uuid
target_entity_uuid
target_entity_type
text
status
risk_accepted
is_suppressed
}
}
}
# Example 2: Suppress a weakness series with tags
mutation SuppressWithTags($inputs: [AnnotationInput!]! = [
{
target_entity_uuid: "1234abcd-1234-abcd-1234-abcd1234abcd",
target_entity_type: "WeaknessSeries",
status: "RISK_ACCEPTED",
tag_uuids: ["b2c3d4e5-b2c3-d4e5-b2c3-d4e5b2c3d4e5"]
}
]) {
apply_annotations_to_weakness_series(inputs: $inputs) {
annotations_count
annotations {
uuid
status
risk_accepted
is_suppressed
}
}
}
Examples may not include all available fields for a type.
AnnotationStatus
Description
Represents the user-assigned remediation or review status for a WeaknessSeries. Used to track the lifecycle of weakness management from discovery through resolution.
Values
FIXED
POTENTIAL_FALSE_POSITIVE
TO_DO
RISK_ACCEPTED
COMPENSATING_CONTROL
VERIFY_COMPENSATING_CONTROL
MUTE
CLOSED
Example
"FIXED"
ApplyAnnotationOutput
Description
Output returned by apply_annotations_to_weakness_series.
Fields
annotations_count - Int!
annotations - [Annotation!]
fragment ApplyAnnotationOutputFragment on ApplyAnnotationOutput {
annotations_count
annotations {
uuid
target_entity_uuid
target_entity_type
text
status
risk_accepted
is_suppressed
}
}
Examples may not include all available fields for a type.
{
"annotations_count": 1,
"annotations": [
{
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"target_entity_uuid": "a1b2c3d4-a1b2-c3d4-a1b2-c3d4a1b2c3d4",
"target_entity_type": "WeaknessSeries",
"text": "Patched in maintenance window",
"status": "FIXED",
"risk_accepted": false,
"suppress_until": null,
"is_suppressed": false,
"tags": []
}
]
}
Tag
Description
A user-defined or system-defined label that can be applied to Annotations for categorization and filtering. Tags support a hierarchical structure through the parent_tag relationship.
Fields
uuid - ID!
text - String!
Network, Critical Infrastructure). parent_tag_uuid - String
client_account_uuid - String
fragment TagFragment on Tag {
uuid
text
parent_tag_uuid
client_account_uuid
}
Examples may not include all available fields for a type.
{
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"text": "remediated",
"parent_tag_uuid": null,
"client_account_uuid": "a1b2c3d4-a1b2-c3d4-a1b2-c3d4a1b2c3d4"
}
WeaknessSeriesAnnotation
Description
Represents the association between an Annotation and a WeaknessSeries. This bridge record links user-applied annotations (status, notes, tags) to their corresponding weakness series records. Returned by weakness_series_annotations_page.
Fields
uuid - String!
row_created_at - Datetime!
row_updated_at - Datetime
weakness_series_uuid - String!
annotation_uuid - String!
annotation_status - AnnotationStatus!
annotation_text - String
affected_asset_short_name - String!
fragment WeaknessSeriesAnnotationFragment on WeaknessSeriesAnnotation {
uuid
row_created_at
row_updated_at
weakness_series_uuid
annotation_uuid
annotation_status
annotation_text
affected_asset_short_name
}
Examples may not include all available fields for a type.
{
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"row_created_at": "2024-03-15T10:30:00Z",
"row_updated_at": "2024-03-16T14:22:00Z",
"weakness_series_uuid": "a1b2c3d4-a1b2-c3d4-a1b2-c3d4a1b2c3d4",
"annotation_uuid": "b2c3d4e5-b2c3-d4e5-b2c3-d4e5b2c3d4e5",
"annotation_status": "FIXED",
"annotation_text": "Patched in maintenance window 2024-03-15",
"affected_asset_short_name": "10.0.1.25:445"
}
WeaknessSeriesAnnotationsPage
Description
A paginated list of WeaknessSeriesAnnotation records. Returned by weakness_series_annotations_page.
Fields
page_info - PageInfo
annotations - [WeaknessSeriesAnnotation!]!
fragment WeaknessSeriesAnnotationsPageFragment on WeaknessSeriesAnnotationsPage {
annotations {
uuid
row_created_at
row_updated_at
weakness_series_uuid
annotation_uuid
annotation_status
annotation_text
affected_asset_short_name
}
}
Examples may not include all available fields for a type.
{
"annotations": [
{
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"row_created_at": "2024-03-15T10:30:00Z",
"row_updated_at": "2024-03-16T14:22:00Z",
"weakness_series_uuid": "a1b2c3d4-a1b2-c3d4-a1b2-c3d4a1b2c3d4",
"annotation_uuid": "b2c3d4e5-b2c3-d4e5-b2c3-d4e5b2c3d4e5",
"annotation_status": "FIXED",
"annotation_text": "Patched in maintenance window",
"affected_asset_short_name": "10.0.1.25:445"
}
]
}
WeaknessSeriesFacets
Description
Available filter facets for WeaknessSeries queries. Each facet provides a list of unique values and their counts in the current dataset, enabling construction of filtered list UIs. Returned by weakness_series_facets.
Fields
page_info - PageInfo
vuln_short_name - [FacetValue]
op_template_name - [FacetValue]
business_risks - [FacetValue]
vuln_threat_actor_names - [FacetValue]
downstream_impact_types - [FacetValue]
fragment WeaknessSeriesFacetsFragment on WeaknessSeriesFacets {
vuln_short_name {
label
value
value_count
}
op_template_name {
label
value
value_count
}
business_risks {
label
value
value_count
}
vuln_threat_actor_names {
label
value
value_count
}
downstream_impact_types {
label
value
value_count
}
}
Examples may not include all available fields for a type.
{
"vuln_short_name": [
{ "label": "SMB Signing Not Required", "value": "SMBSigningNotRequired", "value_count": 12 },
{ "label": "PrintNightmare", "value": "PrintNightmare", "value_count": 3 }
],
"op_template_name": [
{ "label": "Weekly Internal Pentest", "value": "Weekly Internal Pentest", "value_count": 15 }
],
"business_risks": [
{ "label": "Credential Exposure", "value": "Credential Exposure", "value_count": 8 },
{ "label": "Lateral Movement", "value": "Lateral Movement", "value_count": 5 }
],
"vuln_threat_actor_names": [
{ "label": "APT29", "value": "APT29", "value_count": 2 }
],
"downstream_impact_types": [
{ "label": "Ransomware Exposure", "value": "RansomwareExposure", "value_count": 4 },
{ "label": "Sensitive Data Exposure", "value": "SensitiveDataExposure", "value_count": 3 }
]
}
WeaknessSeriesOpStatus
Description
Represents the lifecycle status of a WeaknessSeries as determined by pentest results over time.
Values
OPEN
MITIGATED
REGRESSED
NO_LONGER_FOUND
Example
"OPEN"
WeaknessSeriesPage
Description
A paginated list of WeaknessSeries records. Returned by weakness_series_page.
Fields
page_info - PageInfo
weakness_series - [WeaknessSeries!]!
fragment WeaknessSeriesPageFragment on WeaknessSeriesPage {
weakness_series {
name
vuln_id
vuln_name
vuln_short_name
severity
status
score
annotation_status
is_one_click_verify
affected_asset_name
ip
first_seen_date
last_seen_date
weakness_series_found_count
attack_paths_count
total_impacts_count
business_risks
last_found_op_types
}
}
Examples may not include all available fields for a type.
{
"weakness_series": [
{
"name": "SMB Signing Not Required on 10.0.1.25:445",
"severity": "MEDIUM",
"status": "OPEN",
"score": 6.5,
"affected_asset_name": "10.0.1.25:445"
},
{
"name": "PrintNightmare on DC01.acme.local:135",
"severity": "CRITICAL",
"status": "MITIGATED",
"score": 9.8,
"affected_asset_name": "DC01.acme.local:135"
}
]
}
Vuln Management Hub: Assets
Query your complete asset inventory across all pentests. An asset is a host discovered during pentesting and tracked over time, often identified by its domain name, IP address, cloud resource ID, and other attributes.
assets_page
Description
Returns a paginated list of unique Asset records discovered across all operations for the current client account. Assets are deduplicated across ops using a proprietary identification algorithm. Supports sorting by fields such as name, last_seen_at, first_seen_at, ops_count, and op_series_type. Supports filtering and text search across asset name, IPs, hostnames, OS names, cloud ARNs, and tags. For MSSP accounts, use client_account_uuid to query a subclient's assets.
Response
Returns an AssetsPage!
query AssetsPage($page_input: PageInput) {
assets_page(page_input: $page_input) {
assets {
...AssetPageFragment
}
}
}
fragment AssetPageFragment on Asset {
uuid
name
op_series_type
first_seen_at
last_seen_at
ops_count
last_op_id
first_op_scheduled_at
last_op_scheduled_at
finding_series_uuid
}
Examples may not include all available fields for a type.
{
"data": {
"assets_page": {
"assets": [
{
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"name": "DC01.acme.local (10.0.1.25)",
"op_series_type": "Internal",
"first_seen_at": "2024-01-10T14:30:00Z",
"last_seen_at": "2024-06-15T09:15:33Z",
"ops_count": 12,
"last_op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"first_op_scheduled_at": "2024-01-10T14:00:00Z",
"last_op_scheduled_at": "2024-06-15T09:00:00Z",
"finding_series_uuid": "a1b2c3d4-a1b2-c3d4-a1b2-c3d4a1b2c3d4"
},
{
"uuid": "efgh5678-efgh-5678-efgh-5678efgh5678",
"name": "WEB01.acme.local (10.0.1.50)",
"op_series_type": "External",
"first_seen_at": "2024-03-01T10:00:00Z",
"last_seen_at": "2024-06-15T09:15:33Z",
"ops_count": 5,
"last_op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"first_op_scheduled_at": "2024-03-01T10:00:00Z",
"last_op_scheduled_at": "2024-06-15T09:00:00Z",
"finding_series_uuid": "e5f6g7h8-e5f6-g7h8-e5f6-g7h8e5f6g7h8"
}
]
}
}
}
python h3_gql.py ./assets_page.graphql '{
"page_input": {
"page_size": 10
}
}'
Save the example request as ./assets_page.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./assets_page.graphql '{
"page_input": {
"page_size": 10
}
}'
Save the example request as ./assets_page.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./assets_page.graphql '{
"page_input": {
"page_size": 10
}
}'
Save the example request as ./assets_page.graphql.
See h3-cli Examples for installation and usage.
assets_count
Description
Returns the total number of unique Asset records discovered across all operations for the current client account. Accepts the same filtering and text search parameters as assets_page. For MSSP accounts, use client_account_uuid to count a subclient's assets.
Response
Returns an Int!
query AssetsCount($page_input: PageInput) {
assets_count(page_input: $page_input)
}
Examples may not include all available fields for a type.
{
"data": {
"assets_count": 247
}
}
python h3_gql.py ./assets_count.graphql '{
"page_input": null
}'
Save the example request as ./assets_count.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./assets_count.graphql '{
"page_input": null
}'
Save the example request as ./assets_count.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./assets_count.graphql '{
"page_input": null
}'
Save the example request as ./assets_count.graphql.
See h3-cli Examples for installation and usage.
assets_csv_url
Description
Returns a temporary presigned URL to download the full asset inventory as a CSV file. The CSV is pre-generated and stored in S3; this query returns a time-limited download link. Raises an error if no CSV has been generated for the account yet.
Response
Returns a String
Arguments
client_account_uuid - String
query AssetsCsvUrl {
assets_csv_url
}
Examples may not include all available fields for a type.
{
"data": {
"assets_csv_url": "https://s3.amazonaws.com/h3-exports/assets/1234abcd-1234-abcd-1234-abcd1234abcd.csv?X-Amz-Algorithm=AWS4-HMAC-SHA256&..."
}
}
python h3_gql.py ./assets_csv_url.graphql
Save the example request as ./assets_csv_url.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./assets_csv_url.graphql
Save the example request as ./assets_csv_url.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./assets_csv_url.graphql
Save the example request as ./assets_csv_url.graphql.
See h3-cli Examples for installation and usage.
Asset
Description
Represents a unique asset tracked across multiple penetration testing operations (e.g., a Host).
Assets are identified using a proprietary algorithm that correlates observed attributes such as IP addresses, hostnames, operating systems, and cloud resource ARNs. This cross-operation tracking enables you to see how an asset has been observed over time, including which operations discovered it and when it was first and last seen. Due to the inherent challenges of scan-based asset tracking in dynamic environments, 100% accuracy in asset identification cannot be guaranteed.
Fields
uuid - String!
finding_series_uuid - String!
host_tabs_count - Int!
Arguments
page_input - PageInput
last_op_id - String!
last_op - OpTab!
name - String!
first_seen_at - Datetime!
last_seen_at - Datetime!
ops_count - Int!
first_op_scheduled_at - Datetime!
last_op_scheduled_at - Datetime!
fragment AssetFragment on Asset {
uuid
finding_series_uuid
name
op_series_type
first_seen_at
last_seen_at
ops_count
last_op_id
first_op_scheduled_at
last_op_scheduled_at
host_tabs_count
}
Examples may not include all available fields for a type.
{
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"finding_series_uuid": "a1b2c3d4-a1b2-c3d4-a1b2-c3d4a1b2c3d4",
"name": "DC01.acme.local (10.0.1.25)",
"op_series_type": "Internal",
"first_seen_at": "2024-01-10T14:30:00Z",
"last_seen_at": "2024-06-15T09:15:33Z",
"ops_count": 12,
"last_op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"first_op_scheduled_at": "2024-01-10T14:00:00Z",
"last_op_scheduled_at": "2024-06-15T09:00:00Z",
"host_tabs_count": 12
}
AssetsPage
Description
A paginated list of Asset records. Returned by assets_page.
fragment AssetsPageFragment on AssetsPage {
page_info {
page_num
page_size
}
assets {
uuid
name
op_series_type
first_seen_at
last_seen_at
ops_count
last_op_id
first_op_scheduled_at
last_op_scheduled_at
}
}
Examples may not include all available fields for a type.
{
"page_info": {
"page_num": 1,
"page_size": 10
},
"assets": [
{
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"name": "DC01.acme.local (10.0.1.25)",
"op_series_type": "Internal",
"first_seen_at": "2024-01-10T14:30:00Z",
"last_seen_at": "2024-06-15T09:15:33Z",
"ops_count": 12,
"last_op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"first_op_scheduled_at": "2024-01-10T14:00:00Z",
"last_op_scheduled_at": "2024-06-15T09:00:00Z"
},
{
"uuid": "efgh5678-efgh-5678-efgh-5678efgh5678",
"name": "WEB01.acme.local (10.0.1.50)",
"op_series_type": "External",
"first_seen_at": "2024-03-01T10:00:00Z",
"last_seen_at": "2024-06-15T09:15:33Z",
"ops_count": 5,
"last_op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"first_op_scheduled_at": "2024-03-01T10:00:00Z",
"last_op_scheduled_at": "2024-06-15T09:00:00Z"
}
]
}
Vuln Management Hub: Perspectives
Create custom attacker perspectives and conduct continuous pentesting of specific segments of your network. Inject credentials to simulate insider threats and compromised accounts. Use perspectives to focus remediation efforts and continuously defend against real-world threat scenarios.
perspectives_page
Description
Returns a paginated list of Perspective records in the client's account. Only active (non-deleted) targeted perspectives are returned. Supports sorting by fields such as name, last_exposure_score, and last_op_scheduled_at. Supports filtering by last_exposure_severity, op_type, and scheduled status, as well as text search by perspective name and UUID. For MSSP accounts, use client_account_uuid to query a subclient's perspectives.
Response
Returns a PerspectivesPage!
query PerspectivesPage($page_input: PageInput = {
page_num: 1,
page_size: 5
}) {
perspectives_page(page_input: $page_input) {
perspectives {
...PerspectiveFragment
}
}
}
fragment PerspectiveFragment on Perspective {
uuid
name
op_template {
uuid
name
}
schedule {
uuid
name
}
ops_count
}
Examples may not include all available fields for a type.
{
"data": {
"perspectives_page": {
"perspectives": [
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"name": "Weekly Internal Pentest",
"op_template": {
"uuid": "5678efgh-5678-efgh-5678-efgh5678efgh",
"name": "Internal Network Assessment"
},
"schedule": {
"uuid": "9999aaaa-9999-aaaa-9999-aaaa9999aaaa",
"name": "Weekly Monday 2AM"
},
"ops_count": 12
},
{
"uuid": "2345bcde-2345-bcde-2345-bcde2345bcde",
"name": "Monthly External Scan",
"op_template": {
"uuid": "6789fghi-6789-fghi-6789-fghi6789fghi",
"name": "External Assessment"
},
"schedule": {
"uuid": "8888bbbb-8888-bbbb-8888-bbbb8888bbbb",
"name": "Monthly 1st 3AM"
},
"ops_count": 6
}
]
}
}
}
python h3_gql.py ./perspectives_page.graphql '{
"page_input": {
"page_num": 1,
"page_size": 5
}
}'
Save the example request as ./perspectives_page.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./perspectives_page.graphql '{
"page_input": {
"page_num": 1,
"page_size": 5
}
}'
Save the example request as ./perspectives_page.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./perspectives_page.graphql '{
"page_input": {
"page_num": 1,
"page_size": 5
}
}'
Save the example request as ./perspectives_page.graphql.
See h3-cli Examples for installation and usage.
perspectives_count
Description
Returns the total number of Perspective records in the client's account. Only active (non-deleted) targeted perspectives are counted. Accepts the same filtering parameters as perspectives_page. For MSSP accounts, use client_account_uuid to count a subclient's perspectives.
Response
Returns an Int!
query PerspectivesCount($page_input: PageInput) {
perspectives_count(page_input: $page_input)
}
Examples may not include all available fields for a type.
{
"data": {
"perspectives_count": 5
}
}
python h3_gql.py ./perspectives_count.graphql '{
"page_input": {
"page_size": 10
}
}'
Save the example request as ./perspectives_count.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./perspectives_count.graphql '{
"page_input": {
"page_size": 10
}
}'
Save the example request as ./perspectives_count.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./perspectives_count.graphql '{
"page_input": {
"page_size": 10
}
}'
Save the example request as ./perspectives_count.graphql.
See h3-cli Examples for installation and usage.
perspective
Description
Returns a single Perspective by its unique identifier. Returns null if the perspective does not exist or has been deleted.
Response
Returns a Perspective
Arguments
uuid - String!
query Perspective($uuid: String!) {
perspective(uuid: $uuid) {
uuid
name
op_template {
uuid
name
}
schedule {
uuid
name
}
ops_count
}
}
Examples may not include all available fields for a type.
{
"data": {
"perspective": {
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"name": "Weekly Internal Pentest",
"op_template": {
"uuid": "5678efgh-5678-efgh-5678-efgh5678efgh",
"name": "Internal Network Assessment"
},
"schedule": {
"uuid": "9999aaaa-9999-aaaa-9999-aaaa9999aaaa",
"name": "Weekly Monday 2AM"
},
"ops_count": 12
}
}
}
python h3_gql.py ./perspective.graphql '{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./perspective.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./perspective.graphql '{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./perspective.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./perspective.graphql '{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./perspective.graphql.
See h3-cli Examples for installation and usage.
org_perspective
Description
Returns the account-wide Org Perspective for the current client account.
The Org Perspective automatically aggregates data from all targeted perspectives in the account, covering operations from the past 12 months. This provides a holistic view of your organization's security posture trends without requiring manual perspective selection.
Response
Returns a Perspective
Arguments
client_account_uuid - String
query OrgPerspective {
org_perspective {
uuid
name
op_template {
uuid
name
}
schedule {
uuid
name
}
ops_count
}
}
Examples may not include all available fields for a type.
{
"data": {
"org_perspective": {
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"name": "Organization Perspective",
"op_template": null,
"schedule": null,
"ops_count": 24
}
}
}
python h3_gql.py ./org_perspective.graphql
Save the example request as ./org_perspective.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./org_perspective.graphql
Save the example request as ./org_perspective.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./org_perspective.graphql
Save the example request as ./org_perspective.graphql.
See h3-cli Examples for installation and usage.
perspectives_up_next
Description
Returns Perspective records ordered by their next scheduled execution time (soonest first). Only perspectives with an active schedule are included. Defaults to returning 3 perspectives. Also includes scheduled operations that are not yet associated with a Perspective.
Response
Returns a PerspectivesPage!
query PerspectivesUpNext($count: Int = 3) {
perspectives_up_next(count: $count) {
perspectives {
...PerspectiveFragment
}
}
}
fragment PerspectiveFragment on Perspective {
uuid
name
op_template {
uuid
name
}
schedule {
uuid
name
}
ops_count
}
Examples may not include all available fields for a type.
{
"data": {
"perspectives_up_next": {
"perspectives": [
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"name": "Weekly Internal Pentest",
"op_template": {
"uuid": "5678efgh-5678-efgh-5678-efgh5678efgh",
"name": "Internal Network Assessment"
},
"schedule": {
"uuid": "9999aaaa-9999-aaaa-9999-aaaa9999aaaa",
"name": "Weekly Monday 2AM"
},
"ops_count": 12
},
{
"uuid": "2345bcde-2345-bcde-2345-bcde2345bcde",
"name": "Monthly External Scan",
"op_template": {
"uuid": "6789fghi-6789-fghi-6789-fghi6789fghi",
"name": "External Assessment"
},
"schedule": {
"uuid": "8888bbbb-8888-bbbb-8888-bbbb8888bbbb",
"name": "Monthly 1st 3AM"
},
"ops_count": 6
},
{
"uuid": "3456cdef-3456-cdef-3456-cdef3456cdef",
"name": "Quarterly Compliance Check",
"op_template": {
"uuid": "7890ghij-7890-ghij-7890-ghij7890ghij",
"name": "Compliance Assessment"
},
"schedule": {
"uuid": "7777cccc-7777-cccc-7777-cccc7777cccc",
"name": "Quarterly 1st 4AM"
},
"ops_count": 4
}
]
}
}
}
python h3_gql.py ./perspectives_up_next.graphql '{
"count": 3
}'
Save the example request as ./perspectives_up_next.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./perspectives_up_next.graphql '{
"count": 3
}'
Save the example request as ./perspectives_up_next.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./perspectives_up_next.graphql '{
"count": 3
}'
Save the example request as ./perspectives_up_next.graphql.
See h3-cli Examples for installation and usage.
Perspective
Description
Represents a recurring pentesting configuration, also referred to as an attacker's perspective.
A Perspective groups together the key components of a repeatable pentest:
- An asset scope and attack profile defined by an OpTemplate.
- Optionally, injected credentials to simulate specific attack scenarios.
- A consistent NodeZero Docker host (runner) for executing the pentest.
- A Schedule for automated recurring execution.
By running multiple pentests under the same Perspective, you can track trends over time and measure the effectiveness of remediation efforts.
Fields
uuid - String!
name - String!
op_template - OpTemplate
schedule - Schedule
ops_count - Int!
fragment PerspectiveFragment on Perspective {
uuid
name
op_template {
uuid
name
}
schedule {
uuid
name
}
ops_count
}
Examples may not include all available fields for a type.
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"name": "Weekly Internal Pentest",
"op_template": {
"uuid": "5678efgh-5678-efgh-5678-efgh5678efgh",
"name": "Internal Network Assessment"
},
"schedule": {
"uuid": "9999aaaa-9999-aaaa-9999-aaaa9999aaaa",
"name": "Weekly Monday 2AM"
},
"ops_count": 12
}
PerspectivesPage
Description
A paginated list of Perspective records. Returned by queries such as perspectives_page and perspectives_up_next.
Fields
perspectives - [Perspective!]!
fragment PerspectivesPageFragment on PerspectivesPage {
perspectives {
uuid
name
op_template {
uuid
name
}
schedule {
uuid
name
}
ops_count
}
page_info {
page_num
page_size
}
}
Examples may not include all available fields for a type.
{
"perspectives": [
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"name": "Weekly Internal Pentest",
"op_template": {
"uuid": "5678efgh-5678-efgh-5678-efgh5678efgh",
"name": "Internal Network Assessment"
},
"schedule": {
"uuid": "9999aaaa-9999-aaaa-9999-aaaa9999aaaa",
"name": "Weekly Monday 2AM"
},
"ops_count": 12
},
{
"uuid": "2345bcde-2345-bcde-2345-bcde2345bcde",
"name": "Monthly External Scan",
"op_template": {
"uuid": "6789fghi-6789-fghi-6789-fghi6789fghi",
"name": "External Assessment"
},
"schedule": {
"uuid": "8888bbbb-8888-bbbb-8888-bbbb8888bbbb",
"name": "Monthly 1st 3AM"
},
"ops_count": 6
}
],
"page_info": {
"page_num": 1,
"page_size": 10
}
}
Vuln Management Hub: Campaigns
Create and manage focused cybersecurity campaigns across a set of perspectives. Use campaigns to coordinate large-scale pentesting efforts and track remediation progress across your network.
campaigns
Description
Returns all active (non-deleted) Campaigns for the authenticated user's client account. Results are ordered with the ORG-scoped default campaign first, followed by TARGETED campaigns sorted alphabetically by name.
Response
Returns [Campaign!]!
query Campaigns {
campaigns {
...CampaignFragment
}
}
fragment CampaignFragment on Campaign {
uuid
name
description
scope
client_account_uuid
is_deleted
deleted_at
row_created_at
row_updated_at
perspective_uuids
}
Examples may not include all available fields for a type.
{
"data": {
"campaigns": [
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"name": "Q1 Security Campaign",
"description": "Quarterly security assessment campaign",
"scope": "TARGETED",
"client_account_uuid": "5678efgh-5678-efgh-5678-efgh5678efgh",
"is_deleted": false,
"deleted_at": null,
"row_created_at": "2024-01-15T09:00:00Z",
"row_updated_at": "2024-01-20T14:30:00Z",
"perspective_uuids": [
"aaaa1111-aaaa-1111-aaaa-1111aaaa1111"
]
},
{
"uuid": "5678efgh-5678-efgh-5678-efgh5678efgh",
"name": "Organization Default",
"description": "Default organization-wide campaign",
"scope": "ORG",
"client_account_uuid": "5678efgh-5678-efgh-5678-efgh5678efgh",
"is_deleted": false,
"deleted_at": null,
"row_created_at": "2024-01-01T00:00:00Z",
"row_updated_at": "2024-01-15T12:00:00Z",
"perspective_uuids": []
}
]
}
}
python h3_gql.py ./campaigns.graphql
Save the example request as ./campaigns.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./campaigns.graphql
Save the example request as ./campaigns.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./campaigns.graphql
Save the example request as ./campaigns.graphql.
See h3-cli Examples for installation and usage.
campaign
Description
Retrieves a single Campaign by its UUID. Returns null if the campaign does not exist or has been soft-deleted. Only returns campaigns belonging to the authenticated user's client account.
Response
Returns a Campaign
Arguments
uuid - String!
query Campaign($uuid: String!) {
campaign(uuid: $uuid) {
...CampaignFragment
}
}
fragment CampaignFragment on Campaign {
uuid
name
description
scope
client_account_uuid
is_deleted
deleted_at
row_created_at
row_updated_at
perspective_uuids
}
Examples may not include all available fields for a type.
{
"data": {
"campaign": {
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"name": "Q1 Security Campaign",
"description": "Quarterly security assessment campaign",
"scope": "TARGETED",
"client_account_uuid": "5678efgh-5678-efgh-5678-efgh5678efgh",
"is_deleted": false,
"deleted_at": null,
"row_created_at": "2024-01-15T09:00:00Z",
"row_updated_at": "2024-01-20T14:30:00Z",
"perspective_uuids": [
"aaaa1111-aaaa-1111-aaaa-1111aaaa1111",
"bbbb2222-bbbb-2222-bbbb-2222bbbb2222"
]
}
}
}
python h3_gql.py ./campaign.graphql '{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./campaign.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./campaign.graphql '{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./campaign.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./campaign.graphql '{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./campaign.graphql.
See h3-cli Examples for installation and usage.
create_campaign
Description
Creates a new Campaign for the authenticated user's client account. Campaign names must be unique within a client account. Only one ORG-scoped campaign may exist per client account. Returns the newly created campaign, including system-generated fields such as uuid and row_created_at.
Response
Returns a Campaign!
Arguments
input - CreateCampaignInput!
mutation CreateCampaign($input: CreateCampaignInput!) {
create_campaign(input: $input) {
...CampaignFragment
}
}
fragment CampaignFragment on Campaign {
uuid
name
description
scope
client_account_uuid
is_deleted
row_created_at
row_updated_at
perspective_uuids
}
Examples may not include all available fields for a type.
{
"data": {
"create_campaign": {
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"name": "Q1 Security Campaign",
"description": "Quarterly security assessment campaign",
"scope": "TARGETED",
"client_account_uuid": "5678efgh-5678-efgh-5678-efgh5678efgh",
"is_deleted": false,
"row_created_at": "2024-01-15T09:00:00Z",
"row_updated_at": "2024-01-15T09:00:00Z",
"perspective_uuids": [
"aaaa1111-aaaa-1111-aaaa-1111aaaa1111"
]
}
}
}
python h3_gql.py ./create_campaign.graphql '{
"input": {
"name": "Q1 Security Campaign",
"description": "Quarterly security assessment campaign",
"scope": "TARGETED",
"perspective_uuids": [
"aaaa1111-aaaa-1111-aaaa-1111aaaa1111"
]
}
}'
Save the example request as ./create_campaign.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./create_campaign.graphql '{
"input": {
"name": "Q1 Security Campaign",
"description": "Quarterly security assessment campaign",
"scope": "TARGETED",
"perspective_uuids": [
"aaaa1111-aaaa-1111-aaaa-1111aaaa1111"
]
}
}'
Save the example request as ./create_campaign.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./create_campaign.graphql '{
"input": {
"name": "Q1 Security Campaign",
"description": "Quarterly security assessment campaign",
"scope": "TARGETED",
"perspective_uuids": [
"aaaa1111-aaaa-1111-aaaa-1111aaaa1111"
]
}
}'
Save the example request as ./create_campaign.graphql.
See h3-cli Examples for installation and usage.
update_campaign
Description
Updates an existing Campaign. Only provided fields in the UpdateCampaignInput are modified. Perspective associations cannot be modified on ORG-scoped campaigns. Returns the updated campaign with all current field values.
Response
Returns a Campaign!
Arguments
input - UpdateCampaignInput!
mutation UpdateCampaign($input: UpdateCampaignInput!) {
update_campaign(input: $input) {
...CampaignFragment
}
}
fragment CampaignFragment on Campaign {
uuid
name
description
scope
client_account_uuid
is_deleted
row_created_at
row_updated_at
perspective_uuids
}
Examples may not include all available fields for a type.
{
"data": {
"update_campaign": {
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"name": "Updated Campaign Name",
"description": "Updated campaign description",
"scope": "TARGETED",
"client_account_uuid": "5678efgh-5678-efgh-5678-efgh5678efgh",
"is_deleted": false,
"row_created_at": "2024-01-15T09:00:00Z",
"row_updated_at": "2024-01-22T10:15:00Z",
"perspective_uuids": [
"aaaa1111-aaaa-1111-aaaa-1111aaaa1111",
"5678efgh-5678-efgh-5678-efgh5678efgh"
]
}
}
}
python h3_gql.py ./update_campaign.graphql '{
"input": {
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"name": "Updated Campaign Name",
"description": "Updated campaign description",
"add_perspective_uuids": [
"5678abcd-5678-abcd-5678-abcd5678abcd"
]
}
}'
Save the example request as ./update_campaign.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./update_campaign.graphql '{
"input": {
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"name": "Updated Campaign Name",
"description": "Updated campaign description",
"add_perspective_uuids": [
"5678abcd-5678-abcd-5678-abcd5678abcd"
]
}
}'
Save the example request as ./update_campaign.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./update_campaign.graphql '{
"input": {
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"name": "Updated Campaign Name",
"description": "Updated campaign description",
"add_perspective_uuids": [
"5678abcd-5678-abcd-5678-abcd5678abcd"
]
}
}'
Save the example request as ./update_campaign.graphql.
See h3-cli Examples for installation and usage.
delete_campaign
Description
Soft-deletes a Campaign by UUID. The default ORG-scoped campaign cannot be deleted. Returns true on success.
Response
Returns a Boolean!
Arguments
uuid - String!
mutation DeleteCampaign($uuid: String!) {
delete_campaign(uuid: $uuid)
}
Examples may not include all available fields for a type.
{
"data": {
"delete_campaign": true
}
}
python h3_gql.py ./delete_campaign.graphql '{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./delete_campaign.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./delete_campaign.graphql '{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./delete_campaign.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./delete_campaign.graphql '{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./delete_campaign.graphql.
See h3-cli Examples for installation and usage.
campaign_available_perspectives_page
Description
Returns a paginated list of Perspectives that are available to be added to a campaign. When a campaign_uuid is provided, perspectives already associated with that campaign are excluded from the results.
Response
Returns a PerspectivesPage!
query CampaignAvailablePerspectivesPage(
$page_input: PageInput = { page_num: 1, page_size: 5 },
$campaign_uuid: String
) {
campaign_available_perspectives_page(
page_input: $page_input
campaign_uuid: $campaign_uuid
) {
perspectives {
...PerspectiveFragment
}
}
}
fragment PerspectiveFragment on Perspective {
uuid
name
op_template {
uuid
name
}
schedule {
uuid
name
}
ops_count
}
Examples may not include all available fields for a type.
{
"data": {
"campaign_available_perspectives_page": {
"perspectives": [
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"name": "Weekly Internal Pentest",
"op_template": {
"uuid": "5678efgh-5678-efgh-5678-efgh5678efgh",
"name": "Internal Network Assessment"
},
"schedule": {
"uuid": "9999aaaa-9999-aaaa-9999-aaaa9999aaaa",
"name": "Weekly Monday 2AM"
},
"ops_count": 12
},
{
"uuid": "2345bcde-2345-bcde-2345-bcde2345bcde",
"name": "Monthly External Scan",
"op_template": {
"uuid": "6789fghi-6789-fghi-6789-fghi6789fghi",
"name": "External Assessment"
},
"schedule": {
"uuid": "8888bbbb-8888-bbbb-8888-bbbb8888bbbb",
"name": "Monthly 1st 3AM"
},
"ops_count": 6
}
]
}
}
}
python h3_gql.py ./campaign_available_perspectives_page.graphql '{
"page_input": {
"page_num": 1,
"page_size": 5
},
"campaign_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./campaign_available_perspectives_page.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./campaign_available_perspectives_page.graphql '{
"page_input": {
"page_num": 1,
"page_size": 5
},
"campaign_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./campaign_available_perspectives_page.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./campaign_available_perspectives_page.graphql '{
"page_input": {
"page_num": 1,
"page_size": 5
},
"campaign_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./campaign_available_perspectives_page.graphql.
See h3-cli Examples for installation and usage.
campaign_available_perspectives_count
Description
Returns the total count of Perspectives available to be added to a campaign. When a campaign_uuid is provided, perspectives already associated with that campaign are excluded from the count.
Response
Returns an Int!
query CampaignAvailablePerspectivesCount(
$campaign_uuid: String
) {
campaign_available_perspectives_count(
campaign_uuid: $campaign_uuid
)
}
Examples may not include all available fields for a type.
{
"data": {
"campaign_available_perspectives_count": 8
}
}
python h3_gql.py ./campaign_available_perspectives_count.graphql '{
"campaign_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./campaign_available_perspectives_count.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./campaign_available_perspectives_count.graphql '{
"campaign_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./campaign_available_perspectives_count.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./campaign_available_perspectives_count.graphql '{
"campaign_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./campaign_available_perspectives_count.graphql.
See h3-cli Examples for installation and usage.
Campaign
Description
A Campaign is an organizational grouping of Perspectives that allows users to track and manage related pentesting configurations together. Each client account has one system-generated ORG-scoped campaign that automatically includes all perspectives, plus any number of user-created TARGETED campaigns containing curated subsets. Campaign names must be unique within a client account. Campaigns support soft deletion -- the default ORG campaign cannot be deleted.
Fields
uuid - String!
name - String!
description - String!
scope - CampaignScope!
client_account_uuid - String!
is_deleted - Boolean!
deleted_at - String
null if the campaign is active. row_created_at - String!
row_updated_at - String
null if the campaign has never been modified. perspective_uuids - [String!]
ORG campaigns, this includes all perspectives in the client account. perspectives_page - PerspectivesPage!
page_input. Arguments
page_input - PageInput
perspectives_count - Int!
page_input. Arguments
page_input - PageInput
up_next - PerspectivesPage!
ORG campaigns, this also includes standalone schedules not attached to any perspective. Arguments
count - Int
recommended_perspectives - [RecommendedPerspective!]!
fragment CampaignFragment on Campaign {
uuid
name
description
scope
client_account_uuid
is_deleted
deleted_at
row_created_at
row_updated_at
perspective_uuids
}
Examples may not include all available fields for a type.
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"name": "Q1 Security Campaign",
"description": "Quarterly security assessment campaign",
"scope": "TARGETED",
"client_account_uuid": "5678efgh-5678-efgh-5678-efgh5678efgh",
"is_deleted": false,
"deleted_at": null,
"row_created_at": "2024-01-15T09:00:00Z",
"row_updated_at": "2024-01-20T14:30:00Z",
"perspective_uuids": [
"aaaa1111-aaaa-1111-aaaa-1111aaaa1111",
"bbbb2222-bbbb-2222-bbbb-2222bbbb2222"
]
}
CampaignScope
Description
Defines the scope of a Campaign, distinguishing between the system-managed organization-wide default campaign and user-created targeted campaigns.
Values
ORG
TARGETED
Example
"ORG"
CreateCampaignInput
Description
Input for the create_campaign mutation. Defines the attributes of the new Campaign to create.
Fields
name - String!
description - String!
scope - CampaignScope
TARGETED if not specified. Only one ORG-scoped campaign may exist per client account. See CampaignScope for details. perspective_uuids - [String!]
TARGETED campaigns; ORG campaigns automatically include all perspectives. mutation CreateCampaignExample(
$input: CreateCampaignInput = {
name: "Q1 Security Campaign"
description: "Quarterly security assessment campaign"
scope: TARGETED
perspective_uuids: [
"1234abcd-1234-abcd-1234-abcd1234abcd"
]
}
) {
create_campaign(input: $input) {
uuid
name
description
scope
}
}
Examples may not include all available fields for a type.
RecommendedPerspective
Description
Represents a recommended operation type for a Campaign, along with counts of how many perspectives of that type are currently included. Results are sorted so that operation types with no perspectives appear first, making it easy to identify coverage gaps. The recommended operation types are: NodeZero, ExternalAttack, ADPasswordAudit, K8sPentest, Phishing, InsiderThreatAttack, AWSPentest, and AzurePentest.
Fields
id - String!
op_type value. op_type - OpType!
NodeZero, ExternalAttack, ADPasswordAudit). total_count - Int!
scheduled_count - Int!
fragment RecommendedPerspectiveFragment on RecommendedPerspective {
id
op_type
total_count
scheduled_count
}
Examples may not include all available fields for a type.
{
"id": "NodeZero",
"op_type": "NodeZero",
"total_count": 3,
"scheduled_count": 2
}
UpdateCampaignInput
Description
Input for the update_campaign mutation. All fields except uuid are optional; only provided fields will be modified. Perspective associations cannot be modified on ORG-scoped campaigns.
Fields
name - String
description - String
add_perspective_uuids - [String!]
ORG-scoped campaigns. delete_perspective_uuids - [String!]
ORG-scoped campaigns. mutation UpdateCampaignExample(
$input: UpdateCampaignInput = {
uuid: "1234abcd-1234-abcd-1234-abcd1234abcd"
name: "Updated Campaign Name"
description: "Updated campaign description"
add_perspective_uuids: [
"5678abcd-5678-abcd-5678-abcd5678abcd"
]
delete_perspective_uuids: [
"9999aaaa-9999-aaaa-9999-aaaa9999aaaa"
]
}
) {
update_campaign(input: $input) {
uuid
name
description
}
}
Examples may not include all available fields for a type.
Platform Features
Advanced platform capabilities to enhance your security testing. Leverage Rapid Response for immediate threat validation, deploy Tripwires for breach detection and monitoring, and integrate vulnerability scanner data with Vuln Risk Intelligence to prioritize findings based on NodeZero's exploitation validation.
Platform Features: Rapid Response
Be notified of emerging threats and zero-day vulnerabilities and launch targeted tests to assess if your environment is vulnerable to newly disclosed CVEs or attack techniques.
notifications_page
Description
Returns a paginated list of Notifications for the authenticated user. Includes notifications from both Rapid Response and Tripwire activity. Use the unread parameter to filter for unread notifications only.
Response
Returns a NotificationsPage!
query NotificationsPage($unread: Boolean, $page_input: PageInput) {
notifications_page(unread: $unread, page_input: $page_input) {
notifications {
type
data {
tripwire {
uuid
external_id
type
state
}
trip {
tripped_at
detected_at
is_test
}
}
}
}
}
Examples may not include all available fields for a type.
{
"data": {
"notifications_page": {
"notifications": [
{
"type": "EvidenceOfWeakness",
"data": {
"tripwire": null,
"trip": null
}
},
{
"type": "TripwireTripped",
"data": {
"tripwire": {
"uuid": "aaaa1111-aaaa-1111-aaaa-1111aaaa1111",
"external_id": "AKIAIOSFODNN7EXAMPLE",
"type": "AWS_ACCESS_KEY",
"state": "ACTIVE"
},
"trip": {
"tripped_at": "2024-06-10T14:23:45Z",
"detected_at": "2024-06-10T14:25:12Z",
"is_test": false
}
}
}
]
}
}
}
python h3_gql.py ./notifications_page.graphql '{
"unread": null,
"page_input": null
}'
Save the example request as ./notifications_page.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./notifications_page.graphql '{
"unread": null,
"page_input": null
}'
Save the example request as ./notifications_page.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./notifications_page.graphql '{
"unread": null,
"page_input": null
}'
Save the example request as ./notifications_page.graphql.
See h3-cli Examples for installation and usage.
notifications_count
Description
Returns the total count of Notifications for the authenticated user. Use the unread parameter to count only unread notifications.
Response
Returns an Int!
query NotificationsCount($unread: Boolean) {
notifications_count(unread: $unread)
}
Examples may not include all available fields for a type.
{
"data": {
"notifications_count": 12
}
}
python h3_gql.py ./notifications_count.graphql '{
"unread": true
}'
Save the example request as ./notifications_count.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./notifications_count.graphql '{
"unread": true
}'
Save the example request as ./notifications_count.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./notifications_count.graphql '{
"unread": true
}'
Save the example request as ./notifications_count.graphql.
See h3-cli Examples for installation and usage.
notification
Description
Retrieves a single Notification by its UUID. Returns null if the notification does not exist or does not belong to the authenticated user. For TripwireTripped notifications, accessing this query also records a view event.
Response
Returns a Notification
Arguments
notification_uuid - String!
query GetNotification($notification_uuid: String!) {
notification(notification_uuid: $notification_uuid) {
type
data {
tripwire {
uuid
external_id
type
state
}
trip {
tripped_at
detected_at
is_test
}
}
}
}
Examples may not include all available fields for a type.
{
"data": {
"notification": {
"type": "EvidenceOfWeakness",
"data": {
"tripwire": null,
"trip": null
}
}
}
}
python h3_gql.py ./notification.graphql '{
"notification_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./notification.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./notification.graphql '{
"notification_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./notification.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./notification.graphql '{
"notification_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./notification.graphql.
See h3-cli Examples for installation and usage.
Notification
Description
Represents an alert generated by Rapid Response exploit testing or Tripwire activity detection. Notifications are scoped to a specific user (by email) within a client account and can be queried via notifications_page.
Fields
data - NotificationData!
type. See NotificationData. type - NotificationType!
fragment NotificationFragment on Notification {
type
data {
tripwire {
uuid
external_id
type
state
}
trip {
tripped_at
detected_at
is_test
}
}
}
Examples may not include all available fields for a type.
{
"type": "TripwireTripped",
"data": {
"tripwire": {
"uuid": "aaaa1111-aaaa-1111-aaaa-1111aaaa1111",
"external_id": "AKIAIOSFODNN7EXAMPLE",
"type": "AWS_ACCESS_KEY",
"state": "ACTIVE"
},
"trip": {
"tripped_at": "2024-06-10T14:23:45Z",
"detected_at": "2024-06-10T14:25:12Z",
"is_test": false
}
}
}
NotificationData
Description
Contains the detailed payload of a Notification. The populated fields vary depending on the NotificationType: Rapid Response notifications include vulnerability context and affected entities, while Tripwire notifications include the associated tripwire and trip activity records.
Fields
fragment NotificationDataFragment on NotificationData {
tripwire {
uuid
external_id
type
state
deployment_asset_name
}
trip {
tripped_at
detected_at
is_test
}
}
Examples may not include all available fields for a type.
{
"tripwire": {
"uuid": "aaaa1111-aaaa-1111-aaaa-1111aaaa1111",
"external_id": "AKIAIOSFODNN7EXAMPLE",
"type": "AWS_ACCESS_KEY",
"state": "ACTIVE",
"deployment_asset_name": "dc01.acme.local"
},
"trip": {
"tripped_at": "2024-06-10T14:23:45Z",
"detected_at": "2024-06-10T14:25:12Z",
"is_test": false
}
}
NotificationType
Description
Classifies the type of a Notification, indicating the event category that triggered the alert. Public values cover confirmed Rapid Response findings and tripwire activity detections.
Values
EvidenceOfWeakness
PossibleEvidenceOfWeakness
NoEvidenceOfWeakness
TripwireTripped
Example
"EvidenceOfWeakness"
NotificationsPage
Description
Contains a page of Notification records returned by notifications_page.
Fields
page_info - PageInfo
notifications - [Notification!]!
fragment NotificationsPageFragment on NotificationsPage {
page_info {
page_num
page_size
}
notifications {
type
data {
tripwire {
uuid
external_id
type
state
}
trip {
tripped_at
detected_at
is_test
}
}
}
}
Examples may not include all available fields for a type.
{
"page_info": {
"page_num": 1,
"page_size": 10
},
"notifications": [
{
"type": "EvidenceOfWeakness",
"data": {
"tripwire": null,
"trip": null
}
},
{
"type": "TripwireTripped",
"data": {
"tripwire": {
"uuid": "aaaa1111-aaaa-1111-aaaa-1111aaaa1111",
"external_id": "AKIAIOSFODNN7EXAMPLE",
"type": "AWS_ACCESS_KEY",
"state": "ACTIVE"
},
"trip": {
"tripped_at": "2024-06-10T14:23:45Z",
"detected_at": "2024-06-10T14:25:12Z",
"is_test": false
}
}
}
]
}
Platform Features: Tripwires
Deploy honeypot credentials and deception assets (tripwires) to detect unauthorized access in your environment. Monitor tripwire triggers to identify active attackers and insider threats.
tripwires_page
Description
Returns a paginated list of Tripwires deployed for the authenticated user's client account. Includes tripwires in all lifecycle states (ACTIVE, PENDING, INACTIVE, ERROR). Supports standard pagination, filtering, and sorting via page_input.
Response
Returns a TripwiresPage!
Arguments
page_input - PageInput
query TripwiresPage($page_input: PageInput) {
tripwires_page(page_input: $page_input) {
tripwires {
...TripwireFragment
}
}
}
fragment TripwireFragment on Tripwire {
uuid
external_id
type
op_id
deployment_asset_name
file_attributes {
name
path
sha1
}
processes
state
active_at
inactive_at
last_tested_at
}
Examples may not include all available fields for a type.
{
"data": {
"tripwires_page": {
"tripwires": [
{
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"external_id": "AKIAIOSFODNN7EXAMPLE",
"type": "AWS_ACCESS_KEY",
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"deployment_asset_name": "DC01.acme.local",
"file_attributes": [
{
"name": "credentials.txt",
"path": "C:\\Users\\admin\\Documents\\credentials.txt",
"sha1": "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3"
}
],
"processes": null,
"state": "ACTIVE",
"active_at": "2024-01-15T09:00:00Z",
"inactive_at": null,
"last_tested_at": "2024-02-01T12:30:00Z"
},
{
"uuid": "efgh5678-efgh-5678-efgh-5678efgh5678",
"external_id": "AKIAI44QH8DHBEXAMPLE",
"type": "AWS_ACCESS_KEY",
"op_id": "5678efgh-5678-efgh-5678-efgh5678efgh",
"deployment_asset_name": "WEB01.acme.local",
"file_attributes": [
{
"name": "aws_keys.conf",
"path": "/etc/aws/aws_keys.conf",
"sha1": "b5c19ba61c4c0873d391e987982fbbd3a94a8fe5"
}
],
"processes": null,
"state": "INACTIVE",
"active_at": "2024-01-10T14:00:00Z",
"inactive_at": "2024-01-20T08:00:00Z",
"last_tested_at": "2024-01-20T08:00:00Z"
}
]
}
}
}
python h3_gql.py ./tripwires_page.graphql '{
"page_input": {
"page_size": 10
}
}'
Save the example request as ./tripwires_page.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./tripwires_page.graphql '{
"page_input": {
"page_size": 10
}
}'
Save the example request as ./tripwires_page.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./tripwires_page.graphql '{
"page_input": {
"page_size": 10
}
}'
Save the example request as ./tripwires_page.graphql.
See h3-cli Examples for installation and usage.
tripwires_count
Description
Returns the total count of Tripwires for the authenticated user's client account. Supports filtering via page_input to match the criteria used with tripwires_page.
Response
Returns an Int!
Arguments
page_input - PageInput
query TripwiresCount($page_input: PageInput) {
tripwires_count(page_input: $page_input)
}
Examples may not include all available fields for a type.
{
"data": {
"tripwires_count": 24
}
}
python h3_gql.py ./tripwires_count.graphql '{
"page_input": null
}'
Save the example request as ./tripwires_count.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./tripwires_count.graphql '{
"page_input": null
}'
Save the example request as ./tripwires_count.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./tripwires_count.graphql '{
"page_input": null
}'
Save the example request as ./tripwires_count.graphql.
See h3-cli Examples for installation and usage.
tripwire_jobs_page
Description
Returns a paginated list of tripwire jobs (TripwireInternal operations) for the authenticated user's client account. Each job represents an operation that deployed one or more Tripwires. Results are returned as OpTab records. Supports standard pagination, filtering, and sorting via page_input.
Response
Returns an OpTabsPage!
Arguments
page_input - PageInput
query TripwireJobsPage($page_input: PageInput) {
tripwire_jobs_page(page_input: $page_input) {
op_tabs {
uuid
op_id
op_name
op_state
portal_op_state
op_type
scheduled_at
launched_at
completed_at
duration_hms
tripwires_count
}
}
}
Examples may not include all available fields for a type.
{
"data": {
"tripwire_jobs_page": {
"op_tabs": [
{
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"op_id": "abcd1234-abcd-1234-abcd-1234abcd1234",
"op_name": "Tripwire Deployment - Jan 2024",
"op_state": "done",
"portal_op_state": "done",
"op_type": "TripwiresInternal",
"scheduled_at": "2024-01-15T08:00:00Z",
"launched_at": "2024-01-15T08:00:05Z",
"completed_at": "2024-01-15T08:35:12Z",
"duration_hms": "00:35:07",
"tripwires_count": 8
},
{
"uuid": "efgh5678-efgh-5678-efgh-5678efgh5678",
"op_id": "efgh5678-efgh-5678-efgh-5678efgh5678",
"op_name": "Tripwire Deployment - Feb 2024",
"op_state": "done",
"portal_op_state": "done",
"op_type": "TripwiresInternal",
"scheduled_at": "2024-02-01T08:00:00Z",
"launched_at": "2024-02-01T08:00:03Z",
"completed_at": "2024-02-01T08:22:45Z",
"duration_hms": "00:22:42",
"tripwires_count": 5
}
]
}
}
}
python h3_gql.py ./tripwire_jobs_page.graphql '{
"page_input": {
"page_size": 10
}
}'
Save the example request as ./tripwire_jobs_page.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./tripwire_jobs_page.graphql '{
"page_input": {
"page_size": 10
}
}'
Save the example request as ./tripwire_jobs_page.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./tripwire_jobs_page.graphql '{
"page_input": {
"page_size": 10
}
}'
Save the example request as ./tripwire_jobs_page.graphql.
See h3-cli Examples for installation and usage.
tripwire_jobs_count
Description
Returns the total count of tripwire jobs (TripwireInternal operations) for the authenticated user's client account. Supports filtering via page_input to match the criteria used with tripwire_jobs_page.
Response
Returns an Int!
Arguments
page_input - PageInput
query TripwireJobsCount($page_input: PageInput) {
tripwire_jobs_count(page_input: $page_input)
}
Examples may not include all available fields for a type.
{
"data": {
"tripwire_jobs_count": 12
}
}
python h3_gql.py ./tripwire_jobs_count.graphql '{
"page_input": null
}'
Save the example request as ./tripwire_jobs_count.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./tripwire_jobs_count.graphql '{
"page_input": null
}'
Save the example request as ./tripwire_jobs_count.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./tripwire_jobs_count.graphql '{
"page_input": null
}'
Save the example request as ./tripwire_jobs_count.graphql.
See h3-cli Examples for installation and usage.
test_tripwire
Description
Triggers an on-demand test of the specified Tripwire to verify that its detection mechanism is operational. The resulting Trip event will have is_test set to true. Returns the tested tripwire with updated state.
Response
Returns a Tripwire
Arguments
uuid - String!
mutation TestTripwire($uuid: String!) {
test_tripwire(uuid: $uuid) {
uuid
external_id
type
state
deployment_asset_name
last_tested_at
}
}
Examples may not include all available fields for a type.
{
"data": {
"test_tripwire": {
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"external_id": "AKIAIOSFODNN7EXAMPLE",
"type": "AWS_ACCESS_KEY",
"state": "ACTIVE",
"deployment_asset_name": "DC01.acme.local",
"last_tested_at": "2024-02-15T14:30:00Z"
}
}
}
python h3_gql.py ./test_tripwire.graphql '{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./test_tripwire.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./test_tripwire.graphql '{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./test_tripwire.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./test_tripwire.graphql '{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./test_tripwire.graphql.
See h3-cli Examples for installation and usage.
Tripwire
Description
A persistent detection mechanism deployed during a pentest or tripwire job to detect unauthorized access or lateral movement within the target environment. Tripwires are placed on hosts, data stores, or within Active Directory and generate Trip events when triggered. Each tripwire has a type that determines the detection channel (e.g., cloud credential monitoring, DNS callbacks, or Windows security events) and a lifecycle state tracking its operational status. Tripwires can be tested on demand via test_tripwire.
Fields
uuid - ID!
external_id - String!
AWS_ACCESS_KEY tripwires this is the AWS access key ID; for WINDOWS_SUSPICIOUS_PROCESS and MYSQL_DUMP tripwires this is the DNS subdomain embedded within the tripwire; and for Active Directory tripwires (KERBEROAST, AS_REP_ROAST, EXPOSED_PASSWORD) this is the fully qualified user name of the tripwire account. op_id - String
op - OpTab
deployment_asset_name - String!
file_attributes - [FileAttributes!]
processes - [String!]
WINDOWS_SUSPICIOUS_PROCESS tripwires. active_at - Date
ACTIVE state, or null if not yet activated. inactive_at - Date
INACTIVE state, or null if still active. last_tested_at - Date
null if never tested. fragment TripwireFragment on Tripwire {
uuid
external_id
type
op_id
deployment_asset_name
file_attributes {
name
path
sha1
}
processes
state
active_at
inactive_at
last_tested_at
}
Examples may not include all available fields for a type.
{
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"external_id": "AKIAIOSFODNN7EXAMPLE",
"type": "AWS_ACCESS_KEY",
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"deployment_asset_name": "DC01.acme.local",
"file_attributes": [
{
"name": "credentials.txt",
"path": "C:\\Users\\admin\\Documents\\credentials.txt",
"sha1": "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3"
}
],
"processes": null,
"state": "ACTIVE",
"active_at": "2024-01-15T09:00:00Z",
"inactive_at": null,
"last_tested_at": "2024-02-01T12:30:00Z"
}
FileAttributes
Description
Metadata about a file deployed as part of a Tripwire. Each entry describes one file placed on the target system during tripwire deployment, including its location and integrity hash.
fragment FileAttributesFragment on FileAttributes {
name
path
sha1
}
Examples may not include all available fields for a type.
{
"name": "credentials.txt",
"path": "C:\\Users\\admin\\Documents\\credentials.txt",
"sha1": "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3"
}
Trip
Description
Represents a single activity detection event recorded by a Tripwire. Each Trip captures when unauthorized or suspicious activity triggered the tripwire, when the event was detected, and detailed forensic attributes about the source of the activity.
Fields
tripped_at - Date!
detected_at - Date!
is_test - Boolean!
attributes - TripAttributes!
fragment TripFragment on Trip {
tripped_at
detected_at
is_test
attributes {
trip_time
geoip
source_hostname
source_ip_address
source_edns_client_subnet
source_process_name
source_username
event_id
source_ip_port
dc_hostname
}
}
Examples may not include all available fields for a type.
{
"tripped_at": "2024-02-10T03:45:22Z",
"detected_at": "2024-02-10T03:45:30Z",
"is_test": false,
"attributes": {
"trip_time": "2024-02-10T03:45:22Z",
"geoip": {
"country": "US",
"region": "California",
"city": "San Francisco"
},
"source_hostname": "WORKSTATION01",
"source_ip_address": "192.168.1.105",
"source_edns_client_subnet": "192.168.1.0/24",
"source_process_name": null,
"source_username": null,
"event_id": null,
"source_ip_port": null,
"dc_hostname": null
}
}
TripAttributes
Description
Detailed forensic attributes of a Trip event. The populated fields vary depending on the TripwireType: DNS callback-based tripwires (WINDOWS_SUSPICIOUS_PROCESS, MYSQL_DUMP) populate DNS and subnet fields; AWS_ACCESS_KEY tripwires populate CloudTrail-derived fields; and Active Directory tripwires (KERBEROAST, AS_REP_ROAST, EXPOSED_PASSWORD) populate Windows security event fields.
Fields
trip_time - String
geoip - JSONObject
source_hostname - String
source_ip_address - String
source_edns_client_subnet - String
source_ip_address for identifying the originating network. source_process_name - String
source_username - String
event_id - Int
source_ip_port - String
dc_hostname - String
fragment TripAttributesFragment on TripAttributes {
trip_time
geoip
source_hostname
source_ip_address
source_edns_client_subnet
source_process_name
source_username
event_id
source_ip_port
dc_hostname
}
Examples may not include all available fields for a type.
{
"trip_time": "2024-02-10T03:45:22Z",
"geoip": {
"country": "US",
"region": "California",
"city": "San Francisco"
},
"source_hostname": "WORKSTATION01",
"source_ip_address": "192.168.1.105",
"source_edns_client_subnet": "192.168.1.0/24",
"source_process_name": "mimikatz.exe",
"source_username": "jsmith",
"event_id": 4625,
"source_ip_port": "49152",
"dc_hostname": "DC01.acme.local"
}
TripwiresPage
Description
Contains a page of Tripwire records returned by tripwires_page.
Fields
page_info - PageInfo
tripwires - [Tripwire!]!
fragment TripwiresPageFragment on TripwiresPage {
tripwires {
uuid
external_id
type
state
deployment_asset_name
op_id
active_at
inactive_at
last_tested_at
file_attributes {
name
path
sha1
}
processes
}
page_info {
page_num
page_size
}
}
Examples may not include all available fields for a type.
{
"tripwires": [
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"external_id": "AKIAIOSFODNN7EXAMPLE",
"type": "AWS_ACCESS_KEY",
"state": "ACTIVE",
"deployment_asset_name": "fileserver01.corp.example.com",
"op_id": "5678efgh-5678-efgh-5678-efgh5678efgh",
"active_at": "2024-02-15T10:00:00Z",
"inactive_at": null,
"last_tested_at": "2024-03-01T08:00:00Z",
"file_attributes": [
{
"name": "credentials.txt",
"path": "C:\\Users\\admin\\Documents\\credentials.txt",
"sha1": "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3"
}
],
"processes": null
},
{
"uuid": "2345bcde-2345-bcde-2345-bcde2345bcde",
"external_id": "svc-tripwire.corp.example.com",
"type": "ACTIVE_DIRECTORY",
"state": "ACTIVE",
"deployment_asset_name": "dc01.corp.example.com",
"op_id": "6789fghi-6789-fghi-6789-fghi6789fghi",
"active_at": "2024-01-20T14:30:00Z",
"inactive_at": null,
"last_tested_at": "2024-03-05T12:00:00Z",
"file_attributes": null,
"processes": null
}
],
"page_info": {
"page_num": 1,
"page_size": 10
}
}
Platform Features: Vuln Risk Intelligence
Import vulnerability scan data from third-party scanners and enrich findings with NodeZero's exploit validation and risk intelligence. Prioritize scanner findings based on actual exploitability demonstrated by autonomous pentesting.
scanner_files_page
Description
Returns a paginated list of ScannerFile records for the current user's client account. Use PageInput to control pagination, sorting, and filtering.
Response
Returns a ScannerFilesPage!
Arguments
page_input - PageInput
query ScannerFilesPage($page_input: PageInput) {
scanner_files_page(page_input: $page_input) {
scanner_files {
...ScannerFileFragment
}
}
}
fragment ScannerFileFragment on ScannerFile {
uuid
vendor
file_name
file_size_bytes
file_size_formatted
format
status
status_message
status_progress
uploading_started_at
uploading_ended_at
processing_started_at
processing_ended_at
expires_at
}
Examples may not include all available fields for a type.
{
"data": {
"scanner_files_page": {
"scanner_files": [
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"vendor": "Qualys",
"file_name": "qualys-scan-2024-01.csv",
"file_size_bytes": 2048576,
"file_size_formatted": "2.0 MB",
"format": "CSV",
"status": "COMPLETED",
"status_message": "Processing completed successfully",
"status_progress": 100.0,
"uploading_started_at": "2024-01-15T09:00:00Z",
"uploading_ended_at": "2024-01-15T09:01:30Z",
"processing_started_at": "2024-01-15T09:02:00Z",
"processing_ended_at": "2024-01-15T09:10:45Z",
"expires_at": "2024-04-15T09:00:00Z"
},
{
"uuid": "5678efgh-5678-efgh-5678-efgh5678efgh",
"vendor": "Tenable",
"file_name": "tenable-export-jan.csv",
"file_size_bytes": 5120000,
"file_size_formatted": "5.1 MB",
"format": "CSV",
"status": "PENDING",
"status_message": null,
"status_progress": null,
"uploading_started_at": "2024-01-16T14:00:00Z",
"uploading_ended_at": "2024-01-16T14:02:15Z",
"processing_started_at": null,
"processing_ended_at": null,
"expires_at": "2024-04-16T14:00:00Z"
}
]
}
}
}
python h3_gql.py ./scanner_files_page.graphql '{
"page_input": {
"page_size": 10
}
}'
Save the example request as ./scanner_files_page.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./scanner_files_page.graphql '{
"page_input": {
"page_size": 10
}
}'
Save the example request as ./scanner_files_page.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./scanner_files_page.graphql '{
"page_input": {
"page_size": 10
}
}'
Save the example request as ./scanner_files_page.graphql.
See h3-cli Examples for installation and usage.
scanner_files_count
Description
Returns the total count of vulnerability scanner files for the current user's client account. Accepts an optional PageInput to apply filters before counting.
Response
Returns an Int!
Arguments
page_input - PageInput
query ScannerFilesCount($page_input: PageInput) {
scanner_files_count(page_input: $page_input)
}
Examples may not include all available fields for a type.
{
"data": {
"scanner_files_count": 5
}
}
python h3_gql.py ./scanner_files_count.graphql
Save the example request as ./scanner_files_count.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./scanner_files_count.graphql
Save the example request as ./scanner_files_count.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./scanner_files_count.graphql
Save the example request as ./scanner_files_count.graphql.
See h3-cli Examples for installation and usage.
scanner_file
Description
Returns a single ScannerFile by its unique identifier. The file must belong to the current user's client account.
Response
Returns a ScannerFile
Arguments
uuid - String!
query ScannerFile($uuid: String!) {
scanner_file(uuid: $uuid) {
...ScannerFileFragment
}
}
fragment ScannerFileFragment on ScannerFile {
uuid
vendor
file_name
file_size_bytes
file_size_formatted
format
status
status_message
status_progress
uploading_started_at
uploading_ended_at
processing_started_at
processing_ended_at
expires_at
}
Examples may not include all available fields for a type.
{
"data": {
"scanner_file": {
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"vendor": "Qualys",
"file_name": "qualys-scan-2024-01.csv",
"file_size_bytes": 2048576,
"file_size_formatted": "2.0 MB",
"format": "CSV",
"status": "COMPLETED",
"status_message": "Processing completed successfully",
"status_progress": 100.0,
"uploading_started_at": "2024-01-15T09:00:00Z",
"uploading_ended_at": "2024-01-15T09:01:30Z",
"processing_started_at": "2024-01-15T09:02:00Z",
"processing_ended_at": "2024-01-15T09:10:45Z",
"expires_at": "2024-04-15T09:00:00Z"
}
}
}
python h3_gql.py ./scanner_file.graphql '{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./scanner_file.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./scanner_file.graphql '{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./scanner_file.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./scanner_file.graphql '{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./scanner_file.graphql.
See h3-cli Examples for installation and usage.
scanner_classifications_csv_presigned_url
Description
Generates or retrieves a CSV export of scanner classifications for the specified scanner file and returns a presigned URL to download it. The CSV contains risk intelligence data produced by correlating scanner findings with NodeZero pentest results. If a pre-generated CSV exists from the ETL pipeline, its URL is returned directly; otherwise the CSV is generated on demand.
Response
Returns a String
query ScannerClassificationsCsvPresignedUrl($scanner_file_uuid: String!) {
scanner_classifications_csv_presigned_url(scanner_file_uuid: $scanner_file_uuid)
}
Examples may not include all available fields for a type.
{
"data": {
"scanner_classifications_csv_presigned_url": "https://s3.amazonaws.com/h3-exports/scanner-classifications/1234abcd-1234-abcd-1234-abcd1234abcd.csv?X-Amz-Algorithm=AWS4-HMAC-SHA256&..."
}
}
python h3_gql.py ./scanner_classifications_csv_presigned_url.graphql '{
"scanner_file_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./scanner_classifications_csv_presigned_url.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./scanner_classifications_csv_presigned_url.graphql '{
"scanner_file_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./scanner_classifications_csv_presigned_url.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./scanner_classifications_csv_presigned_url.graphql '{
"scanner_file_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd"
}'
Save the example request as ./scanner_classifications_csv_presigned_url.graphql.
See h3-cli Examples for installation and usage.
upload_scanner_file
Description
Initiates the upload of a vulnerability scanner file. Returns a UploadScannerFileOutput containing a presigned URL. Use the presigned URL with an HTTP PUT request to upload the file content. After upload completes, call process_scanner_file to begin risk intelligence analysis.
Response
Returns an UploadScannerFileOutput!
Arguments
input - UploadScannerFileInput!
mutation UploadScannerFile($input: UploadScannerFileInput!) {
upload_scanner_file(input: $input) {
scanner_file_uuid
upload_url
}
}
Examples may not include all available fields for a type.
{
"data": {
"upload_scanner_file": {
"scanner_file_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"upload_url": "https://s3.amazonaws.com/scanner-uploads/1234abcd-1234-abcd-1234-abcd1234abcd?X-Amz-Algorithm=AWS4-HMAC-SHA256&..."
}
}
}
python h3_gql.py ./upload_scanner_file.graphql '{
"input": {
"vendor": "Qualys",
"file_name": "qualys-scan-2024-01.csv",
"file_size_in_bytes": 2048576
}
}'
Save the example request as ./upload_scanner_file.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./upload_scanner_file.graphql '{
"input": {
"vendor": "Qualys",
"file_name": "qualys-scan-2024-01.csv",
"file_size_in_bytes": 2048576
}
}'
Save the example request as ./upload_scanner_file.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./upload_scanner_file.graphql '{
"input": {
"vendor": "Qualys",
"file_name": "qualys-scan-2024-01.csv",
"file_size_in_bytes": 2048576
}
}'
Save the example request as ./upload_scanner_file.graphql.
See h3-cli Examples for installation and usage.
delete_scanner_files
Description
Permanently deletes one or more vulnerability scanner files and their associated data from both storage and the database. Returns the count of files successfully deleted.
Response
Returns a DeleteScannerFilesOutput!
Arguments
input - DeleteScannerFilesInput!
mutation DeleteScannerFiles($input: DeleteScannerFilesInput!) {
delete_scanner_files(input: $input) {
deleted_count
}
}
Examples may not include all available fields for a type.
{
"data": {
"delete_scanner_files": {
"deleted_count": 2
}
}
}
python h3_gql.py ./delete_scanner_files.graphql '{
"input": {
"scanner_file_uuids": [
"1234abcd-1234-abcd-1234-abcd1234abcd",
"5678abcd-5678-abcd-5678-abcd5678abcd"
]
}
}'
Save the example request as ./delete_scanner_files.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./delete_scanner_files.graphql '{
"input": {
"scanner_file_uuids": [
"1234abcd-1234-abcd-1234-abcd1234abcd",
"5678abcd-5678-abcd-5678-abcd5678abcd"
]
}
}'
Save the example request as ./delete_scanner_files.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./delete_scanner_files.graphql '{
"input": {
"scanner_file_uuids": [
"1234abcd-1234-abcd-1234-abcd1234abcd",
"5678abcd-5678-abcd-5678-abcd5678abcd"
]
}
}'
Save the example request as ./delete_scanner_files.graphql.
See h3-cli Examples for installation and usage.
process_scanner_file
Description
Triggers risk intelligence processing for a vulnerability scanner file. Processing imports the scanner data and cross-references it with your NodeZero pentest results to produce ScannerClassification records. The file must be in PENDING or FAILED status, or in COMPLETED status with the force flag set to true for reprocessing. Returns an error if the file is currently being processed or has expired.
Response
Returns a ProcessScannerFileOutput!
Arguments
input - ProcessScannerFileInput!
mutation ProcessScannerFile($input: ProcessScannerFileInput!) {
process_scanner_file(input: $input) {
success
}
}
Examples may not include all available fields for a type.
{
"data": {
"process_scanner_file": {
"success": true
}
}
}
python h3_gql.py ./process_scanner_file.graphql '{
"input": {
"scanner_file_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"force": false
}
}'
Save the example request as ./process_scanner_file.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./process_scanner_file.graphql '{
"input": {
"scanner_file_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"force": false
}
}'
Save the example request as ./process_scanner_file.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./process_scanner_file.graphql '{
"input": {
"scanner_file_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"force": false
}
}'
Save the example request as ./process_scanner_file.graphql.
See h3-cli Examples for installation and usage.
update_scanner_file
Description
Updates the metadata of a vulnerability scanner file, such as its display name. Returns the updated ScannerFile.
Response
Returns an UpdateScannerFileOutput!
Arguments
input - UpdateScannerFileInput!
mutation UpdateScannerFile($input: UpdateScannerFileInput!) {
update_scanner_file(input: $input) {
success
scanner_file {
...ScannerFileFragment
}
}
}
fragment ScannerFileFragment on ScannerFile {
uuid
vendor
file_name
file_size_bytes
file_size_formatted
format
status
status_message
uploading_started_at
processing_started_at
processing_ended_at
expires_at
}
Examples may not include all available fields for a type.
{
"data": {
"update_scanner_file": {
"success": true,
"scanner_file": {
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"vendor": "Qualys",
"file_name": "qualys-scan-2024-01-renamed.csv",
"file_size_bytes": 2048576,
"file_size_formatted": "2.0 MB",
"format": "CSV",
"status": "COMPLETED",
"status_message": "Processing completed successfully",
"uploading_started_at": "2024-01-15T09:00:00Z",
"processing_started_at": "2024-01-15T09:02:00Z",
"processing_ended_at": "2024-01-15T09:10:45Z",
"expires_at": "2024-04-15T09:00:00Z"
}
}
}
}
python h3_gql.py ./update_scanner_file.graphql '{
"input": {
"scanner_file_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"file_name": "qualys-scan-2024-01-renamed.csv"
}
}'
Save the example request as ./update_scanner_file.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./update_scanner_file.graphql '{
"input": {
"scanner_file_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"file_name": "qualys-scan-2024-01-renamed.csv"
}
}'
Save the example request as ./update_scanner_file.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./update_scanner_file.graphql '{
"input": {
"scanner_file_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"file_name": "qualys-scan-2024-01-renamed.csv"
}
}'
Save the example request as ./update_scanner_file.graphql.
See h3-cli Examples for installation and usage.
DeleteScannerFilesInput
Description
Input for the delete_scanner_files mutation.
Fields
scanner_file_uuids - [String!]!
mutation DeleteScannerFilesExample(
$input: DeleteScannerFilesInput = {
scanner_file_uuids: [
"1234abcd-1234-abcd-1234-abcd1234abcd"
"5678abcd-5678-abcd-5678-abcd5678abcd"
]
}
) {
delete_scanner_files(input: $input) {
deleted_count
}
}
Examples may not include all available fields for a type.
DeleteScannerFilesOutput
Description
Output from the delete_scanner_files mutation.
Fields
deleted_count - Int!
fragment DeleteScannerFilesOutputFragment on DeleteScannerFilesOutput {
deleted_count
}
Examples may not include all available fields for a type.
{
"deleted_count": 2
}
ProcessScannerFileInput
Description
Input for the process_scanner_file mutation.
mutation ProcessScannerFileExample(
$input: ProcessScannerFileInput = {
scanner_file_uuid: "1234abcd-1234-abcd-1234-abcd1234abcd"
force: false
}
) {
process_scanner_file(input: $input) {
success
}
}
Examples may not include all available fields for a type.
ProcessScannerFileOutput
Description
Output from the process_scanner_file mutation.
Fields
success - Boolean!
PROCESSING status while risk intelligence analysis runs asynchronously. fragment ProcessScannerFileOutputFragment on ProcessScannerFileOutput {
success
}
Examples may not include all available fields for a type.
{
"success": true
}
ScannerCategory
Description
Raw classification categories assigned to vulnerability scanner findings. A single classification may have multiple categories. See ScannerDisplayCategory for the prioritized display version used in UI presentation.
Values
CONFIRMED_EXPLOITABLE
CONTEXTUALLY_EXPLOITABLE
DETECTED_ON_HIGH_VALUE_TARGET
THREAT_ACTOR_DETECTED
VULNERABLE_NOT_EXPLOITED
ASSET_NOT_DISCOVERED
MITIGATED
Example
"CONFIRMED_EXPLOITABLE"
ScannerCategoryBreakdown
Description
Aggregate classification counts grouped by composite risk categories. These categories combine multiple ScannerDisplayCategory values for higher-level analysis.
Fields
exploitable - Int!
not_exploitable - Int!
hvt_or_threat_actor_not_exploitable - Int!
NOT_EXPLOITED_ON_HVT or NOT_EXPLOITED_THREAT_ACTOR). scanner_confirmed_exploitable - Int!
priority - Int!
fragment ScannerCategoryBreakdownFragment on ScannerCategoryBreakdown {
exploitable
not_exploitable
hvt_or_threat_actor_not_exploitable
scanner_confirmed_exploitable
priority
}
Examples may not include all available fields for a type.
{
"exploitable": 20,
"not_exploitable": 80,
"hvt_or_threat_actor_not_exploitable": 10,
"scanner_confirmed_exploitable": 15,
"priority": 35
}
ScannerCategoryCount
Description
The number of classifications assigned to a specific ScannerCategory. Since classifications may belong to multiple categories, these counts may not sum to the total.
Fields
category - ScannerCategory!
count - Int!
fragment ScannerCategoryCountFragment on ScannerCategoryCount {
category
count
}
Examples may not include all available fields for a type.
{
"category": "CONFIRMED_EXPLOITABLE",
"count": 12
}
ScannerClassification
Description
Represents a single vulnerability classification produced by cross-referencing a third-party scanner finding with NodeZero pentest results. Each classification captures the correlation between what the scanner reported and what NodeZero discovered, enabling prioritized remediation based on confirmed exploitability, high-value target exposure, and threat actor association.
Fields
uuid - ID!
vuln_scanner_file_uuid - ID!
vuln_scanner_file_data_uuid - ID
vuln_scanner_asset_uuid - ID
finding_evidence_edge_tab_uuid - ID
categories - [ScannerCategory!]!
display_category - ScannerDisplayCategory!
weakness_name - String
weakness_id - String
risk_score - Float
risk_severity - String
risk_score: CRITICAL, HIGH, MEDIUM, LOW, or INFO. is_reported_by_scanner - Boolean!
is_reported_by_nodezero - Boolean!
weakness_series_uuid - ID
host_tab_uuid - ID
asset_uuid - ID
scanned_ip - String!
scanned_host - String
is_high_value_target - Boolean!
threat_actor_ids - [String!]
threat_actors - [ThreatActor!]
downstream_impact_types - [String!]
downstream_impact_types_and_counts - [String!]
Type: N. business_risks - [String!]
nodezero_asset - Asset
weakness_series - WeaknessSeries
fragment ScannerClassificationFragment on ScannerClassification {
uuid
vuln_scanner_file_uuid
categories
display_category
weakness_name
weakness_id
risk_score
risk_severity
is_reported_by_scanner
is_reported_by_nodezero
scanned_ip
scanned_host
is_high_value_target
host_tab_uuid
asset_uuid
weakness_series_uuid
downstream_impact_types
business_risks
}
Examples may not include all available fields for a type.
{
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"vuln_scanner_file_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"categories": ["CONFIRMED_EXPLOITABLE"],
"display_category": "CONFIRMED_EXPLOITABLE",
"weakness_name": "SMB Signing Not Required",
"weakness_id": "CVE-2020-1472",
"risk_score": 9.8,
"risk_severity": "CRITICAL",
"is_reported_by_scanner": true,
"is_reported_by_nodezero": true,
"scanned_ip": "10.0.1.25",
"scanned_host": "DC01.acme.local",
"is_high_value_target": true,
"host_tab_uuid": "5678efgh-5678-efgh-5678-efgh5678efgh",
"asset_uuid": "9999aaaa-9999-aaaa-9999-aaaa9999aaaa",
"weakness_series_uuid": "bbbb2222-bbbb-2222-bbbb-2222bbbb2222",
"downstream_impact_types": ["RansomwareExposure", "SensitiveDataExposure"],
"business_risks": ["Data Breach", "Ransomware"]
}
ScannerClassificationFacets
Description
Faceted filter values for scanner classifications. Each facet provides the distinct values present in the current (optionally filtered) dataset along with counts, enabling dynamic filter UIs. See FacetValue.
Fields
page_info - PageInfo
threat_actor_names - [FacetValue]
business_risk_names - [FacetValue]
fragment ScannerClassificationFacetsFragment on ScannerClassificationFacets {
threat_actor_names {
label
value
value_count
}
business_risk_names {
label
value
value_count
}
}
Examples may not include all available fields for a type.
{
"threat_actor_names": [
{ "label": "APT29", "value": "APT29", "value_count": 5 },
{ "label": "Lazarus Group", "value": "Lazarus Group", "value_count": 3 }
],
"business_risk_names": [
{ "label": "Data Breach", "value": "Data Breach", "value_count": 12 },
{ "label": "Ransomware", "value": "Ransomware", "value_count": 8 }
]
}
ScannerClassificationPage
Description
Paginated response containing ScannerClassification records.
Fields
classifications - [ScannerClassification!]!
fragment ScannerClassificationPageFragment on ScannerClassificationPage {
classifications {
uuid
display_category
weakness_name
weakness_id
risk_score
risk_severity
is_reported_by_scanner
is_reported_by_nodezero
scanned_ip
scanned_host
is_high_value_target
}
}
Examples may not include all available fields for a type.
{
"classifications": [
{
"uuid": "abcd1234-abcd-1234-abcd-1234abcd1234",
"display_category": "CONFIRMED_EXPLOITABLE",
"weakness_name": "SMB Signing Not Required",
"weakness_id": "CVE-2020-1472",
"risk_score": 9.8,
"risk_severity": "CRITICAL",
"is_reported_by_scanner": true,
"is_reported_by_nodezero": true,
"scanned_ip": "10.0.1.25",
"scanned_host": "DC01.acme.local",
"is_high_value_target": true
}
]
}
ScannerClassificationsSummary
Description
Aggregate statistics and breakdowns for scanner classifications within a ScannerFile. Provides multiple views into the data for building dashboards and summary reports.
Fields
counts_by_display_category - [ScannerDisplayCategoryCount!]!
counts_by_category - [ScannerCategoryCount!]!
counts_by_severity - [ScannerSeverityCount!]!
source_breakdown - ScannerSourceBreakdown!
category_breakdown - ScannerCategoryBreakdown!
counts_by_downstream_impact - [ScannerDownstreamImpactCount!]!
fragment ScannerClassificationsSummaryFragment on ScannerClassificationsSummary {
counts_by_display_category {
display_category
count
}
counts_by_severity {
severity
count
}
source_breakdown {
found_by_scanner
found_by_nodezero
found_by_both
found_by_scanner_only
found_by_nodezero_only
}
category_breakdown {
exploitable
not_exploitable
priority
}
counts_by_downstream_impact {
impact_type
count
}
}
Examples may not include all available fields for a type.
{
"counts_by_display_category": [
{ "display_category": "CONFIRMED_EXPLOITABLE", "count": 12 },
{ "display_category": "CONTEXTUALLY_EXPLOITABLE", "count": 8 },
{ "display_category": "VULNERABLE_NOT_EXPLOITED", "count": 45 }
],
"counts_by_severity": [
{ "severity": "CRITICAL", "count": 10 },
{ "severity": "HIGH", "count": 25 },
{ "severity": "MEDIUM", "count": 30 },
{ "severity": "LOW", "count": 15 }
],
"source_breakdown": {
"found_by_scanner": 90,
"found_by_nodezero": 50,
"found_by_both": 35,
"found_by_scanner_only": 55,
"found_by_nodezero_only": 15
},
"category_breakdown": {
"exploitable": 20,
"not_exploitable": 80,
"priority": 35
},
"counts_by_downstream_impact": [
{ "impact_type": "RansomwareExposure", "count": 8 },
{ "impact_type": "SensitiveDataExposure", "count": 5 }
]
}
ScannerDisplayCategory
Description
Priority-ordered display category for scanner classifications. Each classification is assigned exactly one display category (the highest-priority one that applies), making this suitable for mutually exclusive UI presentation. Ordered from highest to lowest severity.
Values
CONFIRMED_EXPLOITABLE
CONTEXTUALLY_EXPLOITABLE
NOT_EXPLOITED_ON_HVT
NOT_EXPLOITED_THREAT_ACTOR
ASSET_NOT_DISCOVERED
VULNERABLE_NOT_EXPLOITED
MITIGATED
Example
"CONFIRMED_EXPLOITABLE"
ScannerDisplayCategoryCount
Description
The number of classifications assigned to a specific ScannerDisplayCategory.
Fields
display_category - ScannerDisplayCategory!
count - Int!
fragment ScannerDisplayCategoryCountFragment on ScannerDisplayCategoryCount {
display_category
count
}
Examples may not include all available fields for a type.
{
"display_category": "CONFIRMED_EXPLOITABLE",
"count": 12
}
ScannerDownstreamImpactCount
Description
The number of distinct classifications associated with a specific downstream impact type (e.g. data exfiltration, lateral movement).
fragment ScannerDownstreamImpactCountFragment on ScannerDownstreamImpactCount {
impact_type
count
}
Examples may not include all available fields for a type.
{
"impact_type": "RansomwareExposure",
"count": 8
}
ScannerFile
Description
Represents an uploaded vulnerability scanner file from a third-party vendor (Qualys, Tenable, or Rapid7). After upload and processing, the file's scanner findings are cross-referenced with NodeZero pentest results to produce ScannerClassification records for risk intelligence analysis.
Fields
uuid - String!
vendor - String!
Qualys, Tenable, Rapid7). See ScannerFileVendor. file_name - String!
file_size_bytes - Float
file_size_formatted - String
2.4 MB). format - ScannerFileFormat
status - ScannerFileStatus!
status_message - String
status, such as error details for FAILED files. status_progress - Float
PROCESSING status. uploading_started_at - Datetime!
uploading_ended_at - Datetime
processing_started_at - Datetime
processing_ended_at - Datetime
expires_at - Datetime
classifications_count - Int!
Arguments
page_input - PageInput
classifications_page - ScannerClassificationPage!
Arguments
page_input - PageInput
classifications_summary - ScannerClassificationsSummary!
Arguments
page_input - PageInput
classifications_facets - ScannerClassificationFacets!
Arguments
page_input - PageInput
fragment ScannerFileFragment on ScannerFile {
uuid
vendor
file_name
file_size_bytes
file_size_formatted
format
status
status_message
status_progress
uploading_started_at
uploading_ended_at
processing_started_at
processing_ended_at
expires_at
classifications_count
}
Examples may not include all available fields for a type.
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"vendor": "Qualys",
"file_name": "qualys-scan-2024-01.csv",
"file_size_bytes": 2048576,
"file_size_formatted": "2.0 MB",
"format": "CSV",
"status": "COMPLETED",
"status_message": "Processing completed successfully",
"status_progress": 100.0,
"uploading_started_at": "2024-01-15T09:00:00Z",
"uploading_ended_at": "2024-01-15T09:01:30Z",
"processing_started_at": "2024-01-15T09:02:00Z",
"processing_ended_at": "2024-01-15T09:10:45Z",
"expires_at": "2024-04-15T09:00:00Z",
"classifications_count": 142
}
ScannerFileFormat
Description
Supported file formats for uploaded vulnerability scanner files.
Values
CSV
XML
Example
"CSV"
ScannerFileStatus
Description
Lifecycle status of a vulnerability scanner file as it progresses through upload and risk intelligence processing.
Values
PENDING
PROCESSING
FAILED
COMPLETED
EXPIRED
DUPLICATE
Example
"PENDING"
ScannerFileVendor
Description
Supported third-party vulnerability scanner vendors for BYO Scanner file uploads.
Values
Qualys
Tenable
Rapid7
Example
"Qualys"
ScannerFilesPage
Description
Paginated response containing ScannerFile records.
Fields
scanner_files - [ScannerFile!]!
fragment ScannerFilesPageFragment on ScannerFilesPage {
scanner_files {
uuid
vendor
file_name
file_size_formatted
format
status
status_message
uploading_started_at
processing_ended_at
expires_at
}
}
Examples may not include all available fields for a type.
{
"scanner_files": [
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"vendor": "Qualys",
"file_name": "qualys-scan-2024-01.csv",
"file_size_formatted": "2.0 MB",
"format": "CSV",
"status": "COMPLETED",
"status_message": "Processing completed successfully",
"uploading_started_at": "2024-01-15T09:00:00Z",
"processing_ended_at": "2024-01-15T09:10:45Z",
"expires_at": "2024-04-15T09:00:00Z"
}
]
}
ScannerSeverity
Description
Severity levels for scanner classification risk scores, based on standard CVSS score ranges.
Values
CRITICAL
HIGH
MEDIUM
LOW
INFO
UNKNOWN
Example
"CRITICAL"
ScannerSeverityCount
Description
The number of classifications at a specific ScannerSeverity level.
Fields
severity - ScannerSeverity!
count - Int!
fragment ScannerSeverityCountFragment on ScannerSeverityCount {
severity
count
}
Examples may not include all available fields for a type.
{
"severity": "CRITICAL",
"count": 10
}
ScannerSourceBreakdown
Description
Breakdown of classification counts by detection source, showing the overlap between the third-party vulnerability scanner and NodeZero pentest findings.
Fields
found_by_scanner - Int!
found_by_nodezero - Int!
found_by_both - Int!
found_by_scanner_only - Int!
found_by_nodezero_only - Int!
fragment ScannerSourceBreakdownFragment on ScannerSourceBreakdown {
found_by_scanner
found_by_nodezero
found_by_both
found_by_scanner_only
found_by_nodezero_only
}
Examples may not include all available fields for a type.
{
"found_by_scanner": 90,
"found_by_nodezero": 50,
"found_by_both": 35,
"found_by_scanner_only": 55,
"found_by_nodezero_only": 15
}
UpdateScannerFileInput
Description
Input for the update_scanner_file mutation.
mutation UpdateScannerFileExample(
$input: UpdateScannerFileInput = {
scanner_file_uuid: "1234abcd-1234-abcd-1234-abcd1234abcd"
file_name: "qualys-scan-2024-01-renamed.csv"
}
) {
update_scanner_file(input: $input) {
success
scanner_file {
uuid
file_name
}
}
}
Examples may not include all available fields for a type.
UpdateScannerFileOutput
Description
Output from the update_scanner_file mutation.
Fields
success - Boolean!
scanner_file - ScannerFile!
fragment UpdateScannerFileOutputFragment on UpdateScannerFileOutput {
success
scanner_file {
uuid
vendor
file_name
status
}
}
Examples may not include all available fields for a type.
{
"success": true,
"scanner_file": {
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"vendor": "Qualys",
"file_name": "qualys-scan-2024-01-renamed.csv",
"status": "COMPLETED"
}
}
UploadScannerFileInput
Description
Input for the upload_scanner_file mutation.
Fields
vendor - ScannerFileVendor!
file_name - String
file_size_in_bytes - Float
mutation UploadScannerFileExample(
$input: UploadScannerFileInput = {
vendor: Qualys
file_name: "qualys-scan-2024-01.csv"
file_size_in_bytes: 2048576
}
) {
upload_scanner_file(input: $input) {
scanner_file_uuid
upload_url
}
}
Examples may not include all available fields for a type.
UploadScannerFileOutput
Description
Output from the upload_scanner_file mutation.
fragment UploadScannerFileOutputFragment on UploadScannerFileOutput {
scanner_file_uuid
upload_url
}
Examples may not include all available fields for a type.
{
"scanner_file_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"upload_url": "https://s3.amazonaws.com/scanner-uploads/1234abcd-1234-abcd-1234-abcd1234abcd?X-Amz-Algorithm=AWS4-HMAC-SHA256&..."
}
Platform Features: CSV Format
These types document the format of CSV exports available from various queries in the API.
ActionLogCSV
Description
String scalar type representing a ActionLogCSV row with columns:
- IP: String
- ModuleName: String
- Cmd: String
- StartTime: String
- EndTime: String
- Targets: String
- MitreTactics: String
- OpID: String
Example
ActionLogCSV
ActiveDirPasswordCSV
Description
String scalar type representing a ActiveDirPasswordCSV row with columns:
- Score: Float
- Severity: String
- Username: String
- UserStatus: String
- HashMasked: String
- CleartextMasked: String
- PasswordLength: String
- Cracked: Boolean
- CrackMethod: String
- CrackMethodLabel: String
- PasswordRank: String
- PasswordRankLabel: String
- UsersWithSimilarPassword: String
- NumSimilarPassword: Int
- PwdLastSet: String
- LDAPDomainName: String
- Hostname: String
- IP: String
- OpID: String
Example
ActiveDirPasswordCSV
CertificateCSV
Description
String scalar type representing a CertificateCSV row with columns:
- FirstSeen: Datetime
- Vhost: String
- IP: String
- Port: Int
- Expiration: String
- Issuer: String
- CommonName: String
- AltNames: String
- AltNamesList: String
- Signed: String
- OpID: String
Example
CertificateCSV
CredentialCSV
Description
String scalar type representing a CredentialCSV row with columns:
- FirstSeen: Datetime
- CredType: String
- CredSource: String
- UserName: String
- Cleartext: String
- Role: String
- Confirmed: Boolean
- Hostname: String
- VhostName: String
- IP: String
- Port: Int
- Protocol: String
- IPAddresses: String
- ServiceType: String
- Service: String
- LDAPDomain: String
- AzureDomain: String
- UserGroups: String
- UserCloudRoles: String
- LoginFormUrl: String
- OS: String
- Hardware: String
- Device: String
- Product: String
- Permissions: String
- Injected: String
- Cracked: Boolean
- Anon: Boolean
- Hash: String
- HashType: String
- RiskScore: Float
- RiskScoreDescription: String
- OpID: String
- ProvenEntityEid: String
- BusinessRisks: String
Example
CredentialCSV
DatabaseRepoCSV
Description
String scalar type representing a DatabaseRepoCSV row with columns:
- UUID: String
- EntityType: String
- FirstSeen: Datetime
- Name: String
- Service: String
- ServiceType: String
- Product: String
- IP: String
- Uri: String
- Hostname: String
- ProtocolPort: String
- NumDataResources: Int
- PermissionsList: String
- Permissions: String
- Authenticated: Boolean
- Score: Float
- Severity: String
- ContextScoreDescription: String
- OpID: String
Example
DatabaseRepoCSV
DockerRegistryCSV
Description
String scalar type representing a DockerRegistryCSV row with columns:
- UUID: String
- EntityType: String
- FirstSeen: Datetime
- Name: String
- Service: String
- ServiceType: String
- Product: String
- IP: String
- Hostname: String
- ProtocolPort: String
- NumDataResources: Int
- PermissionsList: String
- Permissions: String
- Authenticated: Boolean
- Score: Float
- Severity: String
- ContextScoreDescription: String
- OpID: String
Example
DockerRegistryCSV
EDROverviewHostCSV
Description
String scalar type representing a EDROverviewHostCSV row with columns:
- UUID: String
- Score: Float
- Severity: String
- IP: String
- HostNames: String
- EDRVendors: String
- UnblockedEvents: Int
- MitreAttackTactics: String
- DownstreamImpacts: String
- IsDomainController: Boolean
- IsPublic: Boolean
- IsDatabaseServer: Boolean
- IsLoadBalancer: Boolean
- IsMailServer: Boolean
- IsVPN: Boolean
- IsWAF: Boolean
- IsK8sNode: Boolean
- IsK8sService: Boolean
- IsK8sPod: Boolean
Example
EDROverviewHostCSV
ExternalDomainCSV
Description
String scalar type representing a ExternalDomainCSV row with columns:
- Name: String
- TldName: String
- Reachable: Boolean
- InScope: String
- CNAMEs: String
- CnamesList: String
- Ips: String
- IpsList: String
- CloudProviders: String
- CloudProvidersList: String
- CloudServices: String
- CloudServicesList: String
- CloudRegions: String
- CloudRegionsList: String
- Organizations: String
- OrganizationsList: String
- Isps: String
- IspsList: String
- Asns: String
- AsnsList: String
- Countries: String
- CountriesList: String
- DNSHostnames: String
- DNSHostnamesList: String
- CertificateIssuers: String
- CertificateIssuersList: String
- OpID: String
Example
ExternalDomainCSV
ExternalDomainXopCSV
Description
String scalar type representing a ExternalDomainXopCSV row with columns:
- Name: String
- IP: String
- Status: String
- IpType: String
- Reachable: Boolean
- Isp: String
- Organization: String
- LastSeen: String
- FirstSeen: String
- AssetType: String
- Aliases: String
- Ips: String
- TldInScope: Boolean
Example
ExternalDomainXopCSV
GitRepoCSV
Description
String scalar type representing a GitRepoCSV row with columns:
- UUID: String
- EntityType: String
- Name: String
- GitAccountName: String
- GitAccountType: String
- GitAccountSource: String
- NumGitRepoSensitiveFindings: Int
- Score: Float
- Severity: String
- OpID: String
Example
GitRepoCSV
HostCSV
Description
String scalar type representing a HostCSV row with columns:
- FirstSeen: Datetime
- Subnet: String
- SubnetSource: String
- IP: String
- Hostname: String
- DNSHostnames: String
- LDAPHostname: String
- InScope: Boolean
- OS: String
- Hardware: String
- Device: String
- NumWeaknesses: Int
- NumConfirmedWeaknesses: Int
- NumDataResources: Int
- NumCredentials: Int
- NumConfirmedCredentials: Int
- NumServices: Int
- NumWebShares: Int
- RiskScore: Float
- RiskScoreDescription: String
- OpID: String
- BusinessRisks: String
Example
HostCSV
HostXopCSV
Description
String scalar type representing a HostXopCSV row with columns:
- IP: String
- Status: String
- Domains: String
- ThirdPartyAliases: String
- AssetType: String
- Isp: String
- Organization: String
- LastSeen: Datetime
- FirstSeen: String
- Asn: String
- OpID: String
Example
HostXopCSV
ImpactCSV
Description
String scalar type representing a ImpactCSV row with columns:
- Score: Float
- Severity: String
- ImpactType: String
- Name: String
- AffectedAsset: String
- IP: String
- Hostname: String
- TimeToCompromise: String
- BusinessRisks: String
Example
ImpactCSV
S3BucketCSV
Description
String scalar type representing a S3BucketCSV row with columns:
- UUID: String
- EntityType: String
- Name: String
- AwsAccountID: String
- CloudServiceName: String
- CloudProviderName: String
- ServiceType: String
- NumDataResources: Int
- PermissionsList: String
- AwsAnonymousUserPermissionsList: String
- AwsCrossAccountUserPermissionsList: String
- Score: Float
- Severity: String
- OpID: String
Example
S3BucketCSV
ScannerClassificationCSV
Description
String scalar type representing a ScannerClassificationCSV row with columns:
- UUID: String
- WeaknessName: String
- WeaknessID: String
- RiskScore: Float
- RiskSeverity: String
- Categories: String
- IP: String
- Host: String
- Status: String
- MarkedAs: String
- DownstreamImpactTypes: String
- BusinessRisks: String
- AttackPath: Int
- ThreatActors: String
- Mitigations: String
- References: String
Example
ScannerClassificationCSV
ServiceCSV
Description
String scalar type representing a ServiceCSV row with columns:
- FirstSeen: Datetime
- Hostname: String
- IP: String
- Port: Int
- Protocol: String
- Service: String
- ServiceType: String
- Product: String
- OS: String
- Hardware: String
- Device: String
- LDAPHostname: String
- VhostNames: String
- NumWeaknesses: Int
- NumCredentials: Int
- NumDataResources: Int
- RiskScore: Float
- RiskScoreDescription: String
- NonStandardPort: Boolean
- Enumerated: Boolean
- DNSServer: Boolean
- DomainController: Boolean
- MailServer: Boolean
- OpID: String
Example
ServiceCSV
TicketCSV
Description
String scalar type representing a TicketCSV row with columns:
- UUID: String
- AssignedBy: String
- Status: String
- Severity: String
- TicketName: String
- WeaknessID: String
- WeaknessName: String
- AssetCount: Int
- CreatedAt: Datetime
- LastUpdated: Datetime
- SyncSystem: String
- SyncDate: Datetime
- ExternalID: String
Example
TicketCSV
UserCSV
Description
String scalar type representing a UserCSV row with columns:
- Name: String
- Compromised: Boolean
- Source: String
- Hostname: String
- VhostName: String
- IP: String
- Role: String
- LocalAdmin: Boolean
- DomainAdmin: Boolean
- LDAPDomainName: String
- AzureDomainName: String
- GroupNames: String
- CloudRoleNames: String
- OpID: String
Example
UserCSV
WeaknessCSV
Description
String scalar type representing a WeaknessCSV row with columns:
- WeaknessID: String
- FirstSeen: Datetime
- Name: String
- RootCause: String
- Severity: String
- ContextScore: Float
- ContextScoreDescription: String
- Confirmed: Boolean
- Hostname: String
- CNAME: String
- OS: String
- IP: String
- Port: Int
- Protocol: String
- ProtocolPort: String
- Service: String
- ServiceType: String
- Product: String
- OpID: String
- Description: String
- AssetID: String
- AllHostnames: String
- Repo: String
- Vhost: String
- ResourceUri: String
- UserName: String
- UserDomainName: String
- ProvenEntityEid: String
- Impact: String
- Mitigations: String
- References: String
- ThreatActors: String
- BusinessRisks: String
Example
WeaknessCSV
WeaknessSeriesCSV
Description
String scalar type representing a WeaknessSeriesCSV row with columns:
- UUID: String
- WeaknessName: String
- WeaknessID: String
- AffectedAsset: String
- WeaknessCategory: String
- Status: String
- NoteStatus: String
- NoteText: String
- Severity: String
- Verifiable: Boolean
- LatestOpID: String
- IP: String
- FirstSeen: Datetime
- LastSeen: String
Example
WeaknessSeriesCSV
Admin
Administrative APIs for your Horizon3.ai account. View your account settings and the client accounts you have access to. For Managed Service Providers (MSPs), view aggregated data across your subclient accounts.
Admin: Account Management
View account settings and organizational configuration.
session_user_account
Description
Returns the UserAccount for the currently authenticated user, including their profile information and role within the current ClientAccount.
Response
Returns a UserAccount
query SessionUserAccount {
session_user_account {
...UserAccountFragment
}
}
fragment UserAccountFragment on UserAccount {
uuid
email
name
user_role_id
sign_in_type
last_signed_in_at
has_tripwires_access
has_rapid_response_access
has_unread_notifications_by_type
}
Examples may not include all available fields for a type.
{
"data": {
"session_user_account": {
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"email": "john.smith@example.com",
"name": "John Smith",
"user_role_id": "ORG_ADMIN",
"sign_in_type": "BASIC",
"last_signed_in_at": "2024-01-15T09:00:00Z",
"has_tripwires_access": true,
"has_rapid_response_access": true,
"has_unread_notifications_by_type": ["EvidenceOfWeakness"]
}
}
}
python h3_gql.py ./session_user_account.graphql
Save the example request as ./session_user_account.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./session_user_account.graphql
Save the example request as ./session_user_account.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./session_user_account.graphql
Save the example request as ./session_user_account.graphql.
See h3-cli Examples for installation and usage.
client_accounts_count
Description
Returns the number of ClientAccount records accessible by the currently authenticated user. Supports filtering via page_input.
Response
Returns an Int!
Arguments
page_input - PageInput
query ClientAccountsCount($page_input: PageInput) {
client_accounts_count(page_input: $page_input)
}
Examples may not include all available fields for a type.
{
"data": {
"client_accounts_count": 5
}
}
python h3_gql.py ./client_accounts_count.graphql '{
"page_input": {
"page_size": 10
}
}'
Save the example request as ./client_accounts_count.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./client_accounts_count.graphql '{
"page_input": {
"page_size": 10
}
}'
Save the example request as ./client_accounts_count.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./client_accounts_count.graphql '{
"page_input": {
"page_size": 10
}
}'
Save the example request as ./client_accounts_count.graphql.
See h3-cli Examples for installation and usage.
client_accounts_page
Description
Returns a paginated list of ClientAccount records that the currently authenticated user has access to. Use exclude_user_roles to omit accounts where the user holds a specific role (e.g., exclude accounts where the user is READONLY).
Response
Returns a ClientAccountsPage!
Arguments
page_input - PageInput
exclude_user_roles - [AuthzRole]
query ClientAccountsPage($page_input: PageInput) {
client_accounts_page(page_input: $page_input) {
client_accounts {
...ClientAccountFragment
}
}
}
fragment ClientAccountFragment on ClientAccount {
uuid
company_name
company_short_name
session_user_role_id
company_logo_url
tripwires_enabled
assets_count
internal_assets_count
external_assets_count
row_created_at
}
Examples may not include all available fields for a type.
{
"data": {
"client_accounts_page": {
"client_accounts": [
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"company_name": "Horizon3 AI, Inc",
"company_short_name": "H3",
"session_user_role_id": "ORG_ADMIN",
"company_logo_url": "https://portal.yourorg.com/logos/h3-logo.png",
"tripwires_enabled": true,
"assets_count": 250,
"internal_assets_count": 200,
"external_assets_count": 50,
"row_created_at": "2023-06-01T12:00:00Z"
},
{
"uuid": "5678efgh-5678-efgh-5678-efgh5678efgh",
"company_name": "Acme Corporation",
"company_short_name": "Acme",
"session_user_role_id": "USER",
"company_logo_url": null,
"tripwires_enabled": false,
"assets_count": 75,
"internal_assets_count": 60,
"external_assets_count": 15,
"row_created_at": "2023-09-15T08:30:00Z"
}
]
}
}
}
python h3_gql.py ./client_accounts_page.graphql '{
"page_input": {
"page_size": 10
}
}'
Save the example request as ./client_accounts_page.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./client_accounts_page.graphql '{
"page_input": {
"page_size": 10
}
}'
Save the example request as ./client_accounts_page.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./client_accounts_page.graphql '{
"page_input": {
"page_size": 10
}
}'
Save the example request as ./client_accounts_page.graphql.
See h3-cli Examples for installation and usage.
ClientAccount
Description
Represents an organization (tenant) on the platform. Each client account has an isolated database for security data. Accounts may be organized in parent-child hierarchies for MSP and Consulting+ (C_PLUS) deployments, where a parent account manages multiple subclient accounts.
Fields
uuid - String!
parent_uuid - String
null for top-level accounts. child_client_accounts - [ClientAccount!]!
child_client_accounts_page - ClientAccountsPage!
Arguments
page_input - PageInput
child_client_accounts_count - Int!
0 otherwise. Arguments
page_input - PageInput
company_name - String!
company_short_name - String!
company_logo_url - String
secondary_company_logo_url - String
company_colors - [BrandColor!]
white_label_reports_enabled - Boolean
white_label_reports_cascade - Boolean
row_created_at - Datetime
session_user_role_id - AuthzRole
null if the user does not have access to this specific account. tripwires_enabled - Boolean!
assets_count - Int
internal_assets_count - Int
external_assets_count - Int
fragment ClientAccountFragment on ClientAccount {
uuid
parent_uuid
company_name
company_short_name
company_logo_url
secondary_company_logo_url
company_colors {
type
color
}
white_label_reports_enabled
white_label_reports_cascade
session_user_role_id
tripwires_enabled
assets_count
internal_assets_count
external_assets_count
row_created_at
}
Examples may not include all available fields for a type.
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"parent_uuid": null,
"company_name": "Horizon3 AI, Inc",
"company_short_name": "H3",
"company_logo_url": "https://portal.yourorg.com/logos/h3-logo.png",
"secondary_company_logo_url": null,
"company_colors": [
{ "type": "primary", "color": "#bb032d" },
{ "type": "secondary", "color": "#1a1a2e" }
],
"white_label_reports_enabled": true,
"white_label_reports_cascade": false,
"session_user_role_id": "ORG_ADMIN",
"tripwires_enabled": true,
"assets_count": 250,
"internal_assets_count": 200,
"external_assets_count": 50,
"row_created_at": "2023-06-01T12:00:00Z"
}
UserAccount
Description
A user's identity and profile on the platform. Users are identified by their email address and may have access to multiple ClientAccounts with different AuthzRoles in each. A user may also have multiple SignInTypes configured (e.g., BASIC, GOOGLE, SSO).
Fields
uuid - String
email - EmailAddress
name - String
user_role_id - AuthzRole
sign_in_type - SignInType
BASIC, GOOGLE, MICROSOFT, or SSO. last_signed_in_at - Datetime
has_unread_notifications_by_type - [NotificationType]!
has_tripwires_access - Boolean!
has_rapid_response_access - Boolean!
fragment UserAccountFragment on UserAccount {
uuid
email
name
user_role_id
sign_in_type
last_signed_in_at
has_tripwires_access
has_rapid_response_access
has_unread_notifications_by_type
}
Examples may not include all available fields for a type.
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"email": "john.smith@example.com",
"name": "John Smith",
"user_role_id": "ORG_ADMIN",
"sign_in_type": "BASIC",
"last_signed_in_at": "2024-01-15T09:00:00Z",
"has_tripwires_access": true,
"has_rapid_response_access": true,
"has_unread_notifications_by_type": ["EvidenceOfWeakness"]
}
APIKey
Description
An API key used for programmatic access to the GraphQL API. API keys are associated with a specific ClientAccount and UserAccount, and carry the permissions of the assigned role.
Fields
uuid - String!
api_key - String
h3_cli_install_command - String
A shell command that installs the h3-cli and configures it to use this API key. Only populated when the API key is first created.
starts_with - String!
created_at - Datetime!
last_accessed_at - Datetime
null if the key has never been used. fragment APIKeyFragment on APIKey {
uuid
api_key
h3_cli_install_command
starts_with
created_at
last_accessed_at
}
Examples may not include all available fields for a type.
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"api_key": null,
"h3_cli_install_command": null,
"starts_with": "aDJfYXBp",
"created_at": "2024-01-10T14:30:00Z",
"last_accessed_at": "2024-01-15T09:00:00Z"
}
AccessLevel
Description
The access level of a ClientAccount, which determines the tier of features and capabilities available to the organization.
Values
FREE_TRIAL
READONLY. READONLY
FULL
POV
FULL but intended for managed clients evaluating the product. Transitions to READONLY after 30 days. C_PLUS
MSP
FLEX
Example
"FREE_TRIAL"
AuthzRole
Description
The authorization role assigned to a user within a specific ClientAccount. A user's role determines their permissions and may differ across client accounts they have access to.
Values
USER
READONLY
ORG_ADMIN
NODEZERO_RUNNER
NODEZERO_OPERATOR
PHISHER
Example
"USER"
BrandColor
Description
A brand color in a ClientAccount's white-label color scheme. Used for co-branded reports and portal customization.
Fields
type - BrandColorType!
color - HexColor!
fragment BrandColorFragment on BrandColor {
type
color
}
Examples may not include all available fields for a type.
{
"type": "primary",
"color": "#bb032d"
}
BrandColorType
Description
Identifies a brand color as either the primary or secondary color in a ClientAccount's white-label color scheme.
Values
primary
secondary
Example
"primary"
ClientAccountsPage
Description
A paginated list of ClientAccount records. Returned by client_accounts_page.
Fields
page_info - PageInfo
client_accounts - [ClientAccount!]!
fragment ClientAccountsPageFragment on ClientAccountsPage {
page_info {
page_num
page_size
}
client_accounts {
uuid
company_name
company_short_name
session_user_role_id
row_created_at
}
}
Examples may not include all available fields for a type.
{
"page_info": {
"page_num": 1,
"page_size": 10
},
"client_accounts": [
{
"uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"company_name": "Horizon3 AI, Inc",
"company_short_name": "H3",
"session_user_role_id": "ORG_ADMIN",
"row_created_at": "2023-06-01T12:00:00Z"
},
{
"uuid": "5678efgh-5678-efgh-5678-efgh5678efgh",
"company_name": "Acme Corporation",
"company_short_name": "Acme",
"session_user_role_id": "USER",
"row_created_at": "2023-09-15T08:30:00Z"
}
]
}
HexColor
Description
A string representing a color in hexadecimal notation (e.g., #def or #bb032d). Used for white-label BrandColor customization.
Example
"#bb032d"
SignInType
Description
The authentication method used by a UserAccount to sign in to the platform. A single user (identified by email) may have multiple sign-in types available.
Values
BASIC
GOOGLE
LINKED_IN
MICROSOFT
SSO
Example
"BASIC"
Admin: MSP
For Managed Service Providers (MSPs), view aggregated data across your subclient accounts.
subclient_account_summaries
Description
Returns a list of SubclientAccountSummary records containing all-time usage metrics (ops count, sign-in counts, user counts, etc.) for each subclient under the current user's parent account. Set include_parent to true to include the parent account's own metrics. Requires multi-tenancy to be enabled; returns an empty list otherwise.
Response
Returns [SubclientAccountSummary!]!
query SubclientAccountSummaries($include_parent: Boolean, $page_input: PageInput) {
subclient_account_summaries(include_parent: $include_parent, page_input: $page_input) {
...SubclientAccountSummaryFragment
}
}
fragment SubclientAccountSummaryFragment on SubclientAccountSummary {
client_account_uuid
company_name
enrolled_date
ops_count
successfully_launched_ops_count
first_op_date
last_op_date
uniq_ips_count
users_count
user_sign_ins_count
first_sign_in_date
last_sign_in_date
}
Examples may not include all available fields for a type.
{
"data": {
"subclient_account_summaries": [
{
"client_account_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"company_name": "Acme Security Corp",
"enrolled_date": "2023-06-15",
"ops_count": 24,
"successfully_launched_ops_count": 22,
"first_op_date": "2023-07-01",
"last_op_date": "2024-01-10",
"uniq_ips_count": 350,
"users_count": 5,
"user_sign_ins_count": 142,
"first_sign_in_date": "2023-06-16",
"last_sign_in_date": "2024-01-12"
},
{
"client_account_uuid": "5678efgh-5678-efgh-5678-efgh5678efgh",
"company_name": "Beta Networks LLC",
"enrolled_date": "2023-09-01",
"ops_count": 12,
"successfully_launched_ops_count": 11,
"first_op_date": "2023-09-15",
"last_op_date": "2024-01-08",
"uniq_ips_count": 180,
"users_count": 3,
"user_sign_ins_count": 65,
"first_sign_in_date": "2023-09-02",
"last_sign_in_date": "2024-01-09"
}
]
}
}
python h3_gql.py ./subclient_account_summaries.graphql '{
"include_parent": false,
"page_input": {
"page_size": 10
}
}'
Save the example request as ./subclient_account_summaries.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./subclient_account_summaries.graphql '{
"include_parent": false,
"page_input": {
"page_size": 10
}
}'
Save the example request as ./subclient_account_summaries.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./subclient_account_summaries.graphql '{
"include_parent": false,
"page_input": {
"page_size": 10
}
}'
Save the example request as ./subclient_account_summaries.graphql.
See h3-cli Examples for installation and usage.
user_summaries_for_subclient_accounts
Description
Returns a list of ClientAccountUserSummary records showing per-user sign-in activity for each subclient account. Set include_parent to true to include users from the parent account. Requires multi-tenancy to be enabled; returns an empty list otherwise.
Response
Returns [ClientAccountUserSummary!]!
query UserSummariesForSubclientAccounts($include_parent: Boolean, $page_input: PageInput) {
user_summaries_for_subclient_accounts(include_parent: $include_parent, page_input: $page_input) {
...ClientAccountUserSummaryFragment
}
}
fragment ClientAccountUserSummaryFragment on ClientAccountUserSummary {
company_name
user_email
company_linkedin_url
sign_in_count
first_sign_in_date
last_sign_in_date
}
Examples may not include all available fields for a type.
{
"data": {
"user_summaries_for_subclient_accounts": [
{
"company_name": "Acme Security Corp",
"user_email": "admin@acmesecurity.com",
"company_linkedin_url": "https://www.linkedin.com/company/acme-security",
"sign_in_count": 87,
"first_sign_in_date": "2023-06-16T10:30:00Z",
"last_sign_in_date": "2024-01-12T14:22:00Z"
},
{
"company_name": "Acme Security Corp",
"user_email": "analyst@acmesecurity.com",
"company_linkedin_url": "https://www.linkedin.com/company/acme-security",
"sign_in_count": 55,
"first_sign_in_date": "2023-07-01T08:15:00Z",
"last_sign_in_date": "2024-01-11T16:45:00Z"
}
]
}
}
python h3_gql.py ./user_summaries_for_subclient_accounts.graphql '{
"include_parent": false,
"page_input": {
"page_size": 10
}
}'
Save the example request as ./user_summaries_for_subclient_accounts.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./user_summaries_for_subclient_accounts.graphql '{
"include_parent": false,
"page_input": {
"page_size": 10
}
}'
Save the example request as ./user_summaries_for_subclient_accounts.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./user_summaries_for_subclient_accounts.graphql '{
"include_parent": false,
"page_input": {
"page_size": 10
}
}'
Save the example request as ./user_summaries_for_subclient_accounts.graphql.
See h3-cli Examples for installation and usage.
impact_summaries_for_subclient_accounts
Description
Returns a list of ClientAccountImpactSummary records aggregating attack path impacts by type for each subclient account. Each record shows how many pentests observed the impact and the total count of attack paths. Set include_parent to true to include the parent account. Requires multi-tenancy to be enabled; returns an empty list otherwise.
Response
Returns [ClientAccountImpactSummary!]!
query ImpactSummariesForSubclientAccounts($include_parent: Boolean, $page_input: PageInput) {
impact_summaries_for_subclient_accounts(include_parent: $include_parent, page_input: $page_input) {
...ClientAccountImpactSummaryFragment
}
}
fragment ClientAccountImpactSummaryFragment on ClientAccountImpactSummary {
client_account_uuid
impact_type
first_seen_date
last_seen_date
ops_count
impact_paths_count
}
Examples may not include all available fields for a type.
{
"data": {
"impact_summaries_for_subclient_accounts": [
{
"client_account_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"impact_type": "Data Exfiltration",
"first_seen_date": "2023-09-15",
"last_seen_date": "2024-01-10",
"ops_count": 8,
"impact_paths_count": 23
},
{
"client_account_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"impact_type": "Ransomware",
"first_seen_date": "2023-10-01",
"last_seen_date": "2024-01-05",
"ops_count": 4,
"impact_paths_count": 11
}
]
}
}
python h3_gql.py ./impact_summaries_for_subclient_accounts.graphql '{
"include_parent": false,
"page_input": {
"page_size": 10
}
}'
Save the example request as ./impact_summaries_for_subclient_accounts.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./impact_summaries_for_subclient_accounts.graphql '{
"include_parent": false,
"page_input": {
"page_size": 10
}
}'
Save the example request as ./impact_summaries_for_subclient_accounts.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./impact_summaries_for_subclient_accounts.graphql '{
"include_parent": false,
"page_input": {
"page_size": 10
}
}'
Save the example request as ./impact_summaries_for_subclient_accounts.graphql.
See h3-cli Examples for installation and usage.
weakness_summaries_for_subclient_accounts
Description
Returns a list of ClientAccountWeaknessSummary records aggregating weakness occurrences by vulnerability ID for each subclient account. Set include_parent to true to include the parent account. Requires multi-tenancy to be enabled; returns an empty list otherwise.
Response
Returns [ClientAccountWeaknessSummary!]!
query WeaknessSummariesForSubclientAccounts($include_parent: Boolean, $page_input: PageInput) {
weakness_summaries_for_subclient_accounts(include_parent: $include_parent, page_input: $page_input) {
...ClientAccountWeaknessSummaryFragment
}
}
fragment ClientAccountWeaknessSummaryFragment on ClientAccountWeaknessSummary {
company_name
vuln_id
first_seen_date
last_seen_date
first_op_id
last_op_id
ops_count
weaknesses_count
}
Examples may not include all available fields for a type.
{
"data": {
"weakness_summaries_for_subclient_accounts": [
{
"company_name": "Acme Security Corp",
"vuln_id": "CVE-2023-44487",
"first_seen_date": "2023-10-20",
"last_seen_date": "2024-01-10",
"first_op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"last_op_id": "5678efgh-5678-efgh-5678-efgh5678efgh",
"ops_count": 5,
"weaknesses_count": 12
},
{
"company_name": "Beta Networks LLC",
"vuln_id": "CVE-2021-34527",
"first_seen_date": "2023-11-01",
"last_seen_date": "2024-01-08",
"first_op_id": "9012ijkl-9012-ijkl-9012-ijkl9012ijkl",
"last_op_id": "3456mnop-3456-mnop-3456-mnop3456mnop",
"ops_count": 3,
"weaknesses_count": 7
}
]
}
}
python h3_gql.py ./weakness_summaries_for_subclient_accounts.graphql '{
"include_parent": false,
"page_input": {
"page_size": 10
}
}'
Save the example request as ./weakness_summaries_for_subclient_accounts.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./weakness_summaries_for_subclient_accounts.graphql '{
"include_parent": false,
"page_input": {
"page_size": 10
}
}'
Save the example request as ./weakness_summaries_for_subclient_accounts.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./weakness_summaries_for_subclient_accounts.graphql '{
"include_parent": false,
"page_input": {
"page_size": 10
}
}'
Save the example request as ./weakness_summaries_for_subclient_accounts.graphql.
See h3-cli Examples for installation and usage.
cpe_strings_for_subclient_accounts
Description
Returns a list of ClientAccountCPEString records containing Common Platform Enumeration (CPE) data for each endpoint discovered across subclient accounts. CPE strings provide standardized identification of hardware, operating systems, and software on network endpoints. Set include_parent to true to include the parent account. Requires multi-tenancy to be enabled; returns an empty list otherwise.
Response
Returns [ClientAccountCPEString!]!
query CPEStringsForSubclientAccounts($include_parent: Boolean, $page_input: PageInput) {
cpe_strings_for_subclient_accounts(include_parent: $include_parent, page_input: $page_input) {
...ClientAccountCPEStringFragment
}
}
fragment ClientAccountCPEStringFragment on ClientAccountCPEString {
client_account_company_name
op_id
endpoint_created_at_date
ip
cpe
os_vendors
os_products
os_versions
}
Examples may not include all available fields for a type.
{
"data": {
"cpe_strings_for_subclient_accounts": [
{
"client_account_company_name": "Acme Security Corp",
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"endpoint_created_at_date": "2024-01-10",
"ip": "10.0.1.50",
"cpe": "cpe:/o:microsoft:windows_server_2019:-",
"os_vendors": ["Microsoft"],
"os_products": ["Windows Server 2019"],
"os_versions": ["10.0.17763"]
},
{
"client_account_company_name": "Beta Networks LLC",
"op_id": "5678efgh-5678-efgh-5678-efgh5678efgh",
"endpoint_created_at_date": "2024-01-08",
"ip": "192.168.1.10",
"cpe": "cpe:/o:canonical:ubuntu_linux:22.04",
"os_vendors": ["Canonical"],
"os_products": ["Ubuntu Linux"],
"os_versions": ["22.04"]
}
]
}
}
python h3_gql.py ./cpe_strings_for_subclient_accounts.graphql '{
"include_parent": false,
"page_input": {
"page_size": 10
}
}'
Save the example request as ./cpe_strings_for_subclient_accounts.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./cpe_strings_for_subclient_accounts.graphql '{
"include_parent": false,
"page_input": {
"page_size": 10
}
}'
Save the example request as ./cpe_strings_for_subclient_accounts.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./cpe_strings_for_subclient_accounts.graphql '{
"include_parent": false,
"page_input": {
"page_size": 10
}
}'
Save the example request as ./cpe_strings_for_subclient_accounts.graphql.
See h3-cli Examples for installation and usage.
overall_summary_for_subclient_accounts
Description
Returns an OverallSummarySubclientAccounts record with high-level aggregated metrics (total ops, weaknesses, attack paths, etc.) across all subclient accounts. Set include_parent to true to include the parent account's own metrics. Requires multi-tenancy to be enabled; returns an empty list otherwise.
Response
Returns an OverallSummarySubclientAccounts
Arguments
include_parent - Boolean
query OverallSummaryForSubclientAccounts($include_parent: Boolean) {
overall_summary_for_subclient_accounts(include_parent: $include_parent) {
...OverallSummarySubclientAccountsFragment
}
}
fragment OverallSummarySubclientAccountsFragment on OverallSummarySubclientAccounts {
enrolled_clients_count
non_empty_ops_count
ops_count
hosts_or_unique_ips_scanned_count
impact_paths_count
weaknesses_count
weaknesses_mitigated_count
total_duration_of_ops_seconds
}
Examples may not include all available fields for a type.
{
"data": {
"overall_summary_for_subclient_accounts": {
"enrolled_clients_count": 15,
"non_empty_ops_count": 112,
"ops_count": 125,
"hosts_or_unique_ips_scanned_count": 4200,
"impact_paths_count": 340,
"weaknesses_count": 1580,
"weaknesses_mitigated_count": 620,
"total_duration_of_ops_seconds": 2592000
}
}
}
python h3_gql.py ./overall_summary_for_subclient_accounts.graphql '{
"include_parent": false
}'
Save the example request as ./overall_summary_for_subclient_accounts.graphql.
See Python Examples for the h3_gql.py helper script.
./h3_gql.sh ./overall_summary_for_subclient_accounts.graphql '{
"include_parent": false
}'
Save the example request as ./overall_summary_for_subclient_accounts.graphql.
See cURL Examples for the h3_gql.sh helper script.
h3 gql ./overall_summary_for_subclient_accounts.graphql '{
"include_parent": false
}'
Save the example request as ./overall_summary_for_subclient_accounts.graphql.
See h3-cli Examples for installation and usage.
ClientAccountCPEString
Description
Common Platform Enumeration (CPE) data for an endpoint discovered in a subclient account's pentest. CPE is a standardized naming scheme for identifying hardware and software. Returned by cpe_strings_for_subclient_accounts.
Fields
client_account_company_name - String
op_id - String
endpoint_created_at_date - Date
ip - String
cpe - String
hw_vendors - [String]
hw_products - [String]
hw_devices - [String]
hw_versions - [String]
hw_models - [String]
hw_families - [String]
hw_cpes - [String]
os_vendors - [String]
os_architectures - [String]
os_products - [String]
os_versions - [String]
os_editions - [String]
os_builds - [String]
os_families - [String]
os_devices - [String]
os_languages - [String]
os_cpes - [String]
fragment ClientAccountCPEStringFragment on ClientAccountCPEString {
client_account_company_name
op_id
endpoint_created_at_date
ip
cpe
os_vendors
os_products
os_versions
}
Examples may not include all available fields for a type.
{
"client_account_company_name": "Acme Security Corp",
"op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"endpoint_created_at_date": "2024-01-10",
"ip": "10.0.1.50",
"cpe": "cpe:/o:microsoft:windows_server_2019:-",
"os_vendors": ["Microsoft"],
"os_products": ["Windows Server 2019"],
"os_versions": ["10.0.17763"]
}
ClientAccountImpactSummary
Description
Aggregated summary of attack path impacts for a subclient account, grouped by impact type. Each record represents a unique combination of subclient and impact type. Returned by impact_summaries_for_subclient_accounts.
Fields
client_account_uuid - String
impact_type - String
first_seen_date - Date
last_seen_date - Date
ops_count - Int
impact_paths_count - Int
fragment ClientAccountImpactSummaryFragment on ClientAccountImpactSummary {
client_account_uuid
impact_type
first_seen_date
last_seen_date
ops_count
impact_paths_count
}
Examples may not include all available fields for a type.
{
"client_account_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"impact_type": "Data Exfiltration",
"first_seen_date": "2023-09-15",
"last_seen_date": "2024-01-10",
"ops_count": 8,
"impact_paths_count": 23
}
ClientAccountUserSummary
Description
Per-user activity summary for a subclient account, showing sign-in frequency and recency. Each record represents a unique user within a specific subclient. Returned by user_summaries_for_subclient_accounts.
Fields
company_name - String!
user_email - String
company_linkedin_url - String
sign_in_count - Int
first_sign_in_date - Datetime
last_sign_in_date - Datetime
fragment ClientAccountUserSummaryFragment on ClientAccountUserSummary {
company_name
user_email
company_linkedin_url
sign_in_count
first_sign_in_date
last_sign_in_date
}
Examples may not include all available fields for a type.
{
"company_name": "Acme Security Corp",
"user_email": "admin@acmesecurity.com",
"company_linkedin_url": "https://www.linkedin.com/company/acme-security",
"sign_in_count": 87,
"first_sign_in_date": "2023-06-16T10:30:00Z",
"last_sign_in_date": "2024-01-12T14:22:00Z"
}
ClientAccountWeaknessSummary
Description
Aggregated summary of weakness occurrences for a subclient account, grouped by vulnerability identifier. Each record represents a unique combination of subclient and vulnerability. Returned by weakness_summaries_for_subclient_accounts.
Fields
company_name - String
vuln_id - String
CVE-2021-44228) for this weakness. first_seen_date - Date
last_seen_date - Date
first_op_id - String
last_op_id - String
ops_count - Int
weaknesses_count - Int
ops_count if the weakness appears multiple times within a single pentest). fragment ClientAccountWeaknessSummaryFragment on ClientAccountWeaknessSummary {
company_name
vuln_id
first_seen_date
last_seen_date
first_op_id
last_op_id
ops_count
weaknesses_count
}
Examples may not include all available fields for a type.
{
"company_name": "Acme Security Corp",
"vuln_id": "CVE-2023-44487",
"first_seen_date": "2023-10-20",
"last_seen_date": "2024-01-10",
"first_op_id": "1234abcd-1234-abcd-1234-abcd1234abcd",
"last_op_id": "5678efgh-5678-efgh-5678-efgh5678efgh",
"ops_count": 5,
"weaknesses_count": 12
}
OverallSummarySubclientAccounts
Description
High-level aggregated metrics across all subclient accounts under a parent MSP account. Provides a single-row summary of total activity and findings. Returned by overall_summary_for_subclient_accounts.
Fields
enrolled_clients_count - Int
non_empty_ops_count - Int
ops_count - Int
hosts_or_unique_ips_scanned_count - Int
impact_paths_count - Int
weaknesses_count - Int
weaknesses_mitigated_count - Int
total_duration_of_ops_seconds - Long
fragment OverallSummarySubclientAccountsFragment on OverallSummarySubclientAccounts {
enrolled_clients_count
non_empty_ops_count
ops_count
hosts_or_unique_ips_scanned_count
impact_paths_count
weaknesses_count
weaknesses_mitigated_count
total_duration_of_ops_seconds
}
Examples may not include all available fields for a type.
{
"enrolled_clients_count": 15,
"non_empty_ops_count": 112,
"ops_count": 125,
"hosts_or_unique_ips_scanned_count": 4200,
"impact_paths_count": 340,
"weaknesses_count": 1580,
"weaknesses_mitigated_count": 620,
"total_duration_of_ops_seconds": 2592000
}
SubclientAccountSummary
Description
All-time summary metrics for a subclient account, including pentest counts, user activity, and enrollment status. Returned by subclient_account_summaries. Requires multi-tenancy to be enabled on the parent account; returns an empty list otherwise.
Fields
client_account_uuid - String!
company_name - String!
enrolled_date - Date
ops_count - Int
successfully_launched_ops_count - Int
failed_or_autocanceled_ops_count - Int
auto_canceled_ops_count - Int
failed_ops_count - Int
empty_ops_count - Int
first_op_date - Date
last_op_date - Date
uniq_ips_count - Int
users_count - Int
user_sign_ins_count - Int
first_sign_in_date - Date
last_sign_in_date - Date
fragment SubclientAccountSummaryFragment on SubclientAccountSummary {
client_account_uuid
company_name
enrolled_date
ops_count
successfully_launched_ops_count
first_op_date
last_op_date
uniq_ips_count
users_count
user_sign_ins_count
first_sign_in_date
last_sign_in_date
}
Examples may not include all available fields for a type.
{
"client_account_uuid": "1234abcd-1234-abcd-1234-abcd1234abcd",
"company_name": "Acme Security Corp",
"enrolled_date": "2023-06-15",
"ops_count": 24,
"successfully_launched_ops_count": 22,
"first_op_date": "2023-07-01",
"last_op_date": "2024-01-10",
"uniq_ips_count": 350,
"users_count": 5,
"user_sign_ins_count": 142,
"first_sign_in_date": "2023-06-16",
"last_sign_in_date": "2024-01-12"
}
Boolean
Description
The Boolean scalar type represents true or false.
Date
Description
String scalar type with date ISO format serialization, eg. 2021-07-22.
Example
"2021-07-22"
Datetime
Description
String scalar type with datetime ISO format serialization, eg. 2021-07-22T05:02:40.294996 .
Example
"2021-07-22T05:02:40.294996"
EmailAddress
Description
String scalar type with email address format required.
Example
"user@example.com"
Float
Description
The Float scalar type represents signed double-precision fractional values as specified by IEEE 754.
Example
123.45
ID
Description
The ID scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as "4") or integer (such as 4) input value will be accepted as an ID.
Example
4
Int
Description
The Int scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1.
Example
123
JSONObject
Description
String scalar type with JSON serialization.
Example
"{\"hello\": \"world\"}"
Long
Description
Int scalar type alias.
Example
5234
String
Description
The String scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.
Example
"xyz789"
StringNoWhitespace
Description
String scalar type that cannot be an empty string or contain whitespace.
Example
"non-empty-string"
StringNotEmpty
Description
String scalar type that cannot be an empty string.
Example
"non empty string"