Skip to content

Jira

NightVision integrates with Jira in both directions. From your CI pipeline, nightvision export jira files a Jira ticket for each finding in a scan. In the other direction, when someone changes the status of a linked Jira issue, NightVision updates the finding’s resolution to match. For example, moving an issue to “Won’t Do” sets the finding to “Won’t Fix” in NightVision.

  • An organization admin account in NightVision (to configure the integration).
  • A Jira project whose issues you file from NightVision findings.
  • A Jira credential that can create issues in that project (see Authentication below).

nightvision export jira creates a Jira ticket for each finding in a scan and sets the ticket priority from the finding severity. Drop findings you do not want to file by severity (--exclude-severity info,low) or resolution (--exclude-resolution false_positive,wont_fix), set the issue type with --issue-type (default Task), and pass --swagger-file to include each finding’s source location in the ticket.

Re-running the command files nothing new. Each finding carries a stable fingerprint, and an existing ticket is adopted by its fingerprint label, so a re-run skips findings already filed rather than creating duplicates.

The command authenticates to Jira with an account email and an API token, passed as --user-email and --jira-token. The account must have permission to create issues in the target project. There are two kinds of token, and they connect differently:

  • A classic (unscoped) API token from a regular Jira user account authenticates against your Jira site. Pass --base-url https://your-site.atlassian.net.
  • An Atlassian service-account token is always scoped and connects only through the Atlassian API gateway. Pass --jira-cloud-id <cloud id> instead of --base-url, and give the token the read:jira-work and write:jira-work scopes. Find the cloud id at https://your-site.atlassian.net/_edge/tenant_info.

The token is supplied at run time and is never stored by NightVision.

To keep these settings out of every CI job, store them once in the app: open Settings, then Organization, then the Jira Status Sync section, and fill in the Outbound settings. Choose the token type: a classic user token stores a base URL, a service-account token stores a cloud id instead. Set the project key, issue type, and user email alongside it. A CI job then runs nightvision export jira with only the scan id and the token; a flag still overrides a stored value. The API token is the exception: it is never stored and stays supplied by CI.

In NightVision, open Settings, then Organization, then the Jira Status Sync section, and select Enable. NightVision generates a webhook URL and a secret, both shown in that section.

In Jira, create an automation rule (Project settings, then Automation) that runs on an issue transition, scoped to the issues you file tickets for (for example, a condition on the nightvision label). Add a “Send web request” action that POSTs to the NightVision webhook URL:

https://<your NightVision API host>/api/v1/jira/webhooks/<integration id>/

Add a header named X-NightVision-Jira-Token whose value is the secret from the Jira Status Sync section. NightVision matches it against the stored secret and ignores any request that does not match. A Jira automation cannot sign the request body, so this shared-secret header is how the request is authenticated.

Set the web request body to “Custom data” and send the issue key and status:

{
"issue": {
"key": "{{issue.key}}",
"fields": {
"status": {
"name": "{{issue.status.name}}",
"statusCategory": { "key": "{{issue.status.statusCategory.key}}" }
}
}
}
}

You can rotate the secret from the same section; update the automation’s header value with the new secret afterward.

How Jira status maps to a finding resolution

Section titled “How Jira status maps to a finding resolution”

By default:

  • A “Won’t Do” status sets the finding to Won’t Fix.
  • A done or closed status sets the finding to Resolved.
  • A to-do or in-progress status sets the finding back to Open.

The mapping matches the status categories common to most Jira workflows.

To change how a specific status maps, add an override in the Jira Status Sync section: map a Jira status name to Open, Resolved, Won’t Fix, or False Positive. An override applies only to the status you name and takes precedence over the defaults.

A status change that arrives from Jira is recorded against the finding with its source marked as Jira, and is not pushed back out to Jira. The two systems therefore do not echo each other.