Exporter Configuration
Exporters pipe security scan findings directly into your issue trackers and alerting systems, so vulnerabilities discovered by NAT automatically become work items your team can act on.
How exporters work
After a scan completes, NAT sends each finding above the configured minimum severity to one or more exporters. Each exporter is a named plugin that knows how to authenticate with and create records in a specific system.
Basic usage
nat security-scan --spec ./openapi.yaml --base-url https://api.example.com \
--export <exporter-name> \
--export-config key=value \
--export-config key2=value2Filtering by severity
Use --export-min-severity to only export findings at or above a given severity level:
nat security-scan --spec ./openapi.yaml --base-url https://api.example.com \
--export github-issues \
--export-config token=$GITHUB_TOKEN \
--export-config repo=myorg/myrepo \
--export-min-severity highValid values are informational, low, medium, high, and critical.
Custom exporter directories
To load exporters from a local directory in addition to the built-ins:
nat security-scan --spec ./openapi.yaml --base-url https://api.example.com \
--export my-custom-exporter \
--exporters-dir ./exportersNever paste tokens or passwords directly into commands. Use environment variables (e.g., $GITHUB_TOKEN) so credentials are not stored in your shell history or CI logs.
GitHub Issues (github-issues)
Creates a GitHub Issue for each finding. Supports deduplication so re-running a scan does not create duplicate issues.
Config
| Key | Required | Description |
|---|---|---|
token | Required | GitHub personal access token (or GITHUB_TOKEN in Actions). Needs repo scope. |
repo | Required | Repository in owner/repo format, e.g. myorg/myrepo. |
labels | Optional | Comma-separated list of labels to apply to each issue. |
assignees | Optional | Comma-separated list of GitHub usernames to assign. |
deduplicate | Optional | Set to true to skip creating an issue when one with the same finding title is already open. Default: false. |
Example
nat security-scan --spec ./openapi.yaml --base-url https://api.example.com \
--export github-issues \
--export-config token=$GITHUB_TOKEN \
--export-config repo=myorg/myrepo \
--export-config labels=security,nat \
--export-config assignees=alice,bob \
--export-config deduplicate=trueWhen running inside GitHub Actions, GITHUB_TOKEN is available automatically. Set deduplicate=true to keep your issue tracker tidy on repeated scans.
Jira Cloud (jira)
Creates a Jira issue for each finding using the Jira Cloud REST API.
Config
| Key | Required | Description |
|---|---|---|
base_url | Required | Your Jira Cloud base URL, e.g. https://myorg.atlassian.net. |
project_key | Required | The Jira project key where issues will be created, e.g. SEC. |
email | Required | Email address of the Atlassian account used for authentication. |
api_token | Required | Atlassian API token. Generate one at id.atlassian.com (opens in a new tab). |
issue_type | Optional | Issue type name, e.g. Bug, Task, Story. Default: Bug. |
component | Optional | Component name to assign to each issue. |
Example
nat security-scan --spec ./openapi.yaml --base-url https://api.example.com \
--export jira \
--export-config base_url=https://myorg.atlassian.net \
--export-config project_key=SEC \
--export-config email=$JIRA_EMAIL \
--export-config api_token=$JIRA_API_TOKEN \
--export-config issue_type=Bug \
--export-config component=APIGitLab Issues (gitlab)
Creates a GitLab issue for each finding using the GitLab REST API. Works with both GitLab.com and self-hosted GitLab instances.
Config
| Key | Required | Description |
|---|---|---|
gitlab_url | Required | Base URL of your GitLab instance, e.g. https://gitlab.com or https://gitlab.myorg.com. |
project_id | Required | Numeric ID of the GitLab project. Find it on the project's General Settings page. |
private_token | Required | GitLab personal access token with api scope. |
labels | Optional | Comma-separated list of label names to apply to each issue. |
assignee_ids | Optional | Comma-separated list of numeric GitLab user IDs to assign. |
confidential | Optional | Set to true to mark issues as confidential. Default: false. |
Example
nat security-scan --spec ./openapi.yaml --base-url https://api.example.com \
--export gitlab \
--export-config gitlab_url=https://gitlab.com \
--export-config project_id=12345678 \
--export-config private_token=$GITLAB_TOKEN \
--export-config labels=security,vulnerability \
--export-config confidential=trueLinear (linear)
Creates a Linear issue for each finding using the Linear GraphQL API.
Config
| Key | Required | Description |
|---|---|---|
api_key | Required | Linear API key. Generate one in your Linear workspace settings under API. |
team_id | Required | The ID of the Linear team where issues will be created. |
project_id | Optional | Linear project ID to associate issues with a specific project. |
assignee_id | Optional | Linear user ID to assign each issue to. |
label_ids | Optional | Comma-separated list of Linear label IDs to apply. |
Example
nat security-scan --spec ./openapi.yaml --base-url https://api.example.com \
--export linear \
--export-config api_key=$LINEAR_API_KEY \
--export-config team_id=TEAM_ID \
--export-config project_id=PROJECT_ID \
--export-config label_ids=LABEL_ID_1,LABEL_ID_2To find your team ID and project ID, use the Linear API explorer at https://api.linear.app/graphql or check the URL when viewing a team or project in the Linear web app.
Azure DevOps (azure-devops)
Creates an Azure DevOps work item for each finding.
Config
| Key | Required | Description |
|---|---|---|
organization | Required | Azure DevOps organization name, e.g. myorg from https://dev.azure.com/myorg. |
project | Required | Azure DevOps project name. |
pat | Required | Azure DevOps personal access token with Work Items (Read & Write) scope. |
work_item_type | Optional | Work item type, e.g. Bug, Issue, Task. Default: Bug. |
area_path | Optional | Area path for the work item, e.g. MyProject\Security. |
iteration_path | Optional | Iteration (sprint) path, e.g. MyProject\Sprint 5. |
assignee | Optional | Email address of the user to assign work items to. |
Example
nat security-scan --spec ./openapi.yaml --base-url https://api.example.com \
--export azure-devops \
--export-config organization=myorg \
--export-config project=MyProject \
--export-config pat=$AZURE_DEVOPS_PAT \
--export-config work_item_type=Bug \
--export-config area_path=MyProject\\Security \
--export-config assignee=alice@myorg.comShortcut (shortcut)
Creates a Shortcut (formerly Clubhouse) story for each finding.
Config
| Key | Required | Description |
|---|---|---|
api_token | Required | Shortcut API token. Find it in Settings β API Tokens. |
project_id | Required | Numeric ID of the Shortcut project. |
group_id | Optional | ID of the Shortcut team (group) to associate with each story. |
epic_id | Optional | ID of an existing epic to add stories to. |
workflow_state_id | Optional | ID of the workflow state (column) to place new stories in. |
story_type | Optional | Story type: bug, feature, or chore. Default: bug. |
labels | Optional | Comma-separated list of label names to apply. |
Example
nat security-scan --spec ./openapi.yaml --base-url https://api.example.com \
--export shortcut \
--export-config api_token=$SHORTCUT_API_TOKEN \
--export-config project_id=12345 \
--export-config story_type=bug \
--export-config labels=security,nat \
--export-config epic_id=67890PagerDuty (pagerduty)
Sends each finding as a PagerDuty alert, triggering your on-call escalation policies for critical security issues.
Config
| Key | Required | Description |
|---|---|---|
routing_key | Required | PagerDuty Events API v2 integration key (32-character string). |
service_id | Optional | PagerDuty service ID to associate events with. |
escalation_policy | Optional | Escalation policy ID to use when creating incidents. |
source | Optional | Logical name of the source system. Default: nat-security-scan. |
component | Optional | Component of the source machine that triggered the event. |
group | Optional | Logical grouping for the event, e.g. api-gateway. |
playbook_url | Optional | URL to a runbook or playbook for responders. |
artifact_url | Optional | URL to supporting artifact (e.g., scan report). |
timeout | Optional | HTTP request timeout in seconds. Default: 30. |
Example
nat security-scan --spec ./openapi.yaml --base-url https://api.example.com \
--export pagerduty \
--export-config routing_key=$PAGERDUTY_ROUTING_KEY \
--export-config source=production-api \
--export-config component=auth-service \
--export-min-severity criticalPagerDuty exporters are best combined with --export-min-severity critical or --export-min-severity high to avoid paging on-call engineers for low-severity informational findings.
ServiceNow (servicenow)
Creates a ServiceNow incident or record for each finding. Supports both OAuth token and username/password authentication.
Config
| Key | Required | Description |
|---|---|---|
instance_url | Required | Your ServiceNow instance URL, e.g. https://myorg.service-now.com. |
oauth_token | Required (or username+password) | OAuth 2.0 bearer token for authentication. |
username | Required (or oauth_token) | ServiceNow username for basic authentication. |
password | Required with username | ServiceNow password for basic authentication. |
table | Optional | ServiceNow table to create records in. Default: incident. |
category | Optional | Category value for the created record, e.g. software. |
field_mapping | Optional | JSON string mapping NAT finding fields to ServiceNow fields. |
Authentication modes
ServiceNow supports two authentication modes β use whichever matches your instance configuration:
OAuth token (recommended):
nat security-scan --spec ./openapi.yaml --base-url https://api.example.com \
--export servicenow \
--export-config instance_url=https://myorg.service-now.com \
--export-config oauth_token=$SERVICENOW_TOKEN \
--export-config table=incident \
--export-config category=softwareUsername and password:
nat security-scan --spec ./openapi.yaml --base-url https://api.example.com \
--export servicenow \
--export-config instance_url=https://myorg.service-now.com \
--export-config username=$SERVICENOW_USER \
--export-config password=$SERVICENOW_PASS \
--export-config table=incidentYou must provide either oauth_token or both username and password. Providing both sets of credentials will cause a validation error.
Webhook (webhook)
POSTs a JSON payload to any HTTP or HTTPS endpoint for each finding, enabling integration with any system that accepts webhooks.
Config
| Key | Required | Description |
|---|---|---|
webhook_url | Required | The full URL to POST findings to. Must start with http:// or https://. |
auth_header | Optional | Value for the Authorization header, e.g. Bearer my-token. |
custom_headers | Optional | JSON string of additional headers to include, e.g. {"X-Source": "nat"}. |
hmac_secret | Optional | Secret key for HMAC-SHA256 request signing. The signature is sent in the X-NAT-Signature header. |
include_report_context | Optional | Set to true to include full scan metadata alongside each finding. Default: false. |
batch_mode | Optional | Set to true to send all findings in a single request as a JSON array instead of one request per finding. Default: false. |
timeout | Optional | HTTP request timeout in seconds. Default: 30. |
Example
nat security-scan --spec ./openapi.yaml --base-url https://api.example.com \
--export webhook \
--export-config webhook_url=https://hooks.example.com/nat-findings \
--export-config auth_header=Bearer\ $WEBHOOK_SECRET \
--export-config hmac_secret=$HMAC_KEY \
--export-config include_report_context=true \
--export-config batch_mode=trueThe webhook_url must begin with http:// or https://. A URL that does not pass this validation will cause the export to fail immediately without sending any findings.
Use hmac_secret to verify the authenticity of incoming payloads on your server. Compare the value in the X-NAT-Signature header against an HMAC-SHA256 of the raw request body using your secret.
Using multiple exporters
You can specify --export more than once to send findings to multiple destinations in a single scan:
nat security-scan --spec ./openapi.yaml --base-url https://api.example.com \
--export github-issues \
--export-config token=$GITHUB_TOKEN \
--export-config repo=myorg/myrepo \
--export jira \
--export-config base_url=https://myorg.atlassian.net \
--export-config project_key=SEC \
--export-config email=$JIRA_EMAIL \
--export-config api_token=$JIRA_API_TOKEN \
--export-min-severity highWhen using multiple exporters, --export-min-severity and --exporters-dir apply to all exporters in the command.
Next steps
- Security Scanning β understand findings, severity scores, and scan tuning
- CLI Reference β full reference for all
natCLI flags - Custom Check Plugins β write your own security checks