Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 16 additions & 14 deletions docs/content/issue_tracking/pro_integration/integrations.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@ aliases:
DefectDojo Pro's Integrations let you push your Findings and Finding Groups to ticket tracking systems to easily integrate security remediation with your teams existing development workflow.

Supported Integrations:
- [Azure Devops](/issue_tracking/pro_integration/integrations/#azure-devops-boards)
- [Bitbucket](/issue_tracking/pro_integration/integrations/#bitbucket)
- [GitHub](/issue_tracking/pro_integration/integrations/#github)
- [GitLab Boards](/issue_tracking/pro_integration/integrations/#gitlab)
- [Freshservice](/issue_tracking/pro_integration/integrations/#freshservice)
- [ServiceNow](/issue_tracking/pro_integration/integrations/#servicenow)
- [Shortcut](/issue_tracking/pro_integration/integrations/#shortcut)
- Azure Devops
- Bitbucket
- Freshservice
- GitHub
- GitLab Boards
- Jira
- ServiceNow
- Shortcut

## Opening the Integrations page

Expand Down Expand Up @@ -71,13 +72,14 @@ Project Integrations will have varying requirements for how DefectDojo will need

For the complete list of requirements, please open the vendor specific pages below:

- [Azure Devops](/issue_tracking/pro_integration/integrations/#azure-devops-boards)
- [Bitbucket](/issue_tracking/pro_integration/integrations/#bitbucket)
- [GitHub](/issue_tracking/pro_integration/integrations/#github)
- [GitLab Boards](/issue_tracking/pro_integration/integrations/#gitlab)
- [Freshservice](/issue_tracking/pro_integration/integrations/#freshservice)
- ServiceNow (Coming Soon)
- [Shortcut](/issue_tracking/pro_integration/integrations/#shortcut)
- [Azure Devops](/issue_tracking/pro_integration/integrations_toolreference/#azure-devops-boards)
- [Bitbucket](/issue_tracking/pro_integration/integrations_toolreference/#bitbucket)
- [Freshservice](/issue_tracking/pro_integration/integrations_toolreference/#freshservice)
- [GitHub](/issue_tracking/pro_integration/integrations_toolreference/#github)
- [GitLab Boards](/issue_tracking/pro_integration/integrations_toolreference/#gitlab)
- [Jira](/issue_tracking/pro_integration/integrations_toolreference/#jira)
- [ServiceNow](/issue_tracking/pro_integration/integrations_toolreference/#servicenow)
- [Shortcut](/issue_tracking/pro_integration/integrations_toolreference/#shortcut)

## Error Handling and Debugging

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,121 @@ By default, GitLab has statuses of 'opened' and 'closed'. Additional status lab
- **False Positive Mapping**: `closed`
- **Risk Accepted Mapping**: `closed`

## Jira

The Jira integration pushes DefectDojo Findings and Finding Groups to a Jira project as issues, keeps each issue's status in sync with the Finding, and links the Finding back to the created issue. Both Jira **Cloud** and **Data Center / Server** are supported. Jira Service Management is not supported.

### Choosing an authentication method

Set **Jira Deployment** first, then pick an **Authentication Method**:

**Jira Cloud**
- **API Token (email + token)** — HTTP Basic auth using an Atlassian account email and an [API token](https://id.atlassian.com/manage-profile/security/api-tokens). Calls go directly to your site URL.
- **OAuth 2.0 (recommended)** — a one-time browser consent; DefectDojo obtains and refreshes the tokens for you.
- **Service Account Token** — a scoped API token created for an Atlassian [service account](https://support.atlassian.com/user-management/docs/manage-api-tokens-for-service-accounts/).

**Jira Data Center / Server**
- **Personal Access Token (recommended)**
- **Username + Password**

> **How Cloud auth reaches Jira:** OAuth 2.0 and Service Account both authenticate as a Bearer token against Atlassian's gateway — `https://api.atlassian.com/ex/jira/{cloudId}` — which is a *different host* than your `https://your-site.atlassian.net` site URL. DefectDojo uses the gateway for every API call but always builds the ticket link shown on a Finding from your **site URL**, so the link a user clicks is a normal, browsable `.../browse/{ISSUE-KEY}` link. (API Token and Data Center auth call the site URL directly, so there is no split.)

### Instance Setup

- **Label** should be the label you want to use to identify this integration.
- **Location** should be set to your Jira **site URL**, for example `https://your-organization.atlassian.net`. This is used for the browsable ticket links, and — for API Token and Data Center auth — as the API base URL.
- The remaining fields depend on the method you chose above (email + API token, OAuth client credentials, service-account token, PAT, or username + password).

### OAuth 2.0 setup (Cloud)

Create a dedicated app in the [Atlassian developer console](https://developer.atlassian.com/console/myapps/), then connect from DefectDojo.

1. Choose **Create → OAuth 2.0 integration**. It must be an *OAuth 2.0 integration* — a Connect or Forge app cannot use the 3LO authorization-code grant (you'd get `grant_type is not enabled for client`).
2. When prompted for **Access type**, choose **Resource-level**. This scopes the token to the single Jira site the user authorizes, which is exactly what one DefectDojo connection targets. (**Account-level** grants access to every site in the Atlassian account — broader than needed.)
3. Under **Permissions**, add the **Jira platform REST API** and grant the scopes listed below. Note: `offline_access` is *not* listed here — it is a standard OAuth scope DefectDojo requests in the authorization URL, not something you add on this screen.
4. Under **Authorization**, next to **OAuth 2.0 (3LO)** click **Configure** and set the **Callback URL** to `https://<your-defectdojo-host>/integrators/jira/oauth/callback` — it must match your DefectDojo site URL exactly. Enabling this is what turns on the authorization-code grant and refresh tokens; skipping it causes the `grant_type is not enabled` / `Client is not allowed to use offline_access` errors.
5. Copy the **Client ID** and **Client Secret** into the DefectDojo form and **Submit** to save the connection.
6. Click **Connect with Jira** and approve the consent screen. Atlassian redirects back to DefectDojo, which stores the tokens and resolves your `cloudId` automatically. A "Connected" indicator appears when it succeeds.

> The callback host is your DefectDojo `SITE_URL`. Atlassian must be able to redirect the browser there, and the value must match what DefectDojo sends exactly — so use the real hostname your users reach DefectDojo at, not a value only reachable from inside the network.

#### Minimum OAuth scopes

DefectDojo requests these four classic scopes by default, and they are also the **absolute minimum** required — each one backs a specific behavior:

| Scope | Required for |
|-------|--------------|
| `read:jira-work` | Reading the project, issues, and available transitions (connection validation and status sync). |
| `write:jira-work` | Creating and editing issues, and executing status transitions. |
| `read:jira-user` | The connection's identity check — DefectDojo calls `/myself` when validating access. |
| `offline_access` | Issuing a **refresh token**. Without it the access token expires (~1 hour after you connect) and the connection stops working, because DefectDojo can no longer refresh it. |

Atlassian recommends classic scopes over granular ones; the four above keep the app's footprint minimal and are sufficient for everything the integration does.

##### Granular scope alternative

If your organization requires **granular** scopes instead of classic, the minimum equivalent set is:

| Granular scope | Required for |
|----------------|--------------|
| `read:user:jira` | The `/myself` identity check. |
| `read:project:jira` | Validating the target project exists. |
| `read:issue:jira` | Reading an issue's current status during sync. |
| `write:issue:jira` | Creating and editing issues **and executing status transitions** — there is no separate transition-write scope; a transition is a write to the issue. |
| `read:issue.transition:jira` | Listing the transitions available on an issue. |
| `offline_access` | The refresh token (same as classic). |

Depending on your site's field configuration, an endpoint may also require companion read scopes to expand fields — most commonly `read:status:jira` and `read:field:jira` (and `read:issue-meta:jira` for create). If a push fails with a `403` "scope does not match" error, add the exact scope named in the error. This companion-scope sprawl is precisely why classic scopes are recommended.

For the **Service Account Token** method, grant the token `read:jira-work` and `write:jira-work` (plus `read:jira-user`) — or the granular equivalents above without `offline_access`. `offline_access` does not apply — a service-account token is long-lived and is not refreshed by DefectDojo.

### Issue Tracker Mapping

- **Project Key**: the key of the Jira project to create issues in, for example `SEC`.
- **Issue Type**: the issue type to create, for example `Bug` or `Task`. Defaults to `Bug`.

### Severity Mapping Details

Defaults match Jira's default priority scheme. Edit them to match the priority names in your project:

- **Severity Field Name**: `priority`
- **Info Mapping**: `Lowest`
- **Low Mapping**: `Low`
- **Medium Mapping**: `Medium`
- **High Mapping**: `High`
- **Critical Mapping**: `Highest`

### Status Mapping Details

Statuses vary per project workflow, so these defaults are meant to be edited to **your** workflow's status names:

- **Status Field Name**: `status`
- **Active Mapping**: `To Do`
- **Closed Mapping**: `Done`
- **False Positive Mapping**: `Done`
- **Risk Accepted Mapping**: `Done`

### Custom Fields (optional)

You can map additional Jira fields — for example a required `resolution` on close, or `labels` — in the mapping's **Custom Fields** step. Each custom-field mapping has four parts:

- **Source** — where the value comes from: an attribute of the **Finding**, **Test**, **Engagement**, or **Asset** being pushed, or a **Static value**.
- **Value** — for an object source, the specific attribute to read, chosen from a list of that object's fields with human-readable labels (for example *Severity*, *CVE*, *Mitigation*). For a **Static value** source this is a free-text box you type the literal value into.
- **Vendor Field** — the Jira field to write to. Because DefectDojo can read Jira's field catalog, this is a searchable picker that lists each field by its **display name** and resolves it to the internal id for you — so you select *DD Close Justification* and DefectDojo stores `customfield_10255`. The picker is populated from the connection, so it works once the connection is saved and validated.
- **Application point** — *when* to send the field: on **ticket creation**, on **every update**, or as part of a specific status **transition** (Active / Closed / False Positive / Risk Accepted). A transition-scoped field is sent as part of that transition's edit — this is how you supply a value Jira only accepts on a transition screen, most commonly a `resolution` your workflow requires when an issue is resolved.

### Ticket Templates (optional)

By default Jira issues use DefectDojo's built-in title and body. To customize them, attach a **Ticket Template** to the mapping in its **Ticket Template** step. A template defines four independently-optional pieces — the **Finding** summary and description, and the **Finding Group** summary and description. Any piece left blank falls back to the built-in default, so you can override just the title, just the body, or all four. Use **Test render** in the template editor to preview the rendered output against sample data — catching mistakes such as unknown placeholders or values that exceed a field's length limit — before saving. If a template is later deleted, the mappings that used it revert to the built-in defaults automatically.

### How it works

- **Create / Update / Delete:** creating pushes a new issue and records the link on the Finding; updating edits the existing issue; deleting a Finding force-closes its issue (nothing is deleted in Jira). Pushes can be manual ("Push to Integrators") or automatic per the Issue Tracker Assignment.
- **Status reconciliation:** after creating (and on every update) DefectDojo reads the issue's current status and, if it differs from the mapped target, finds a single workflow transition that reaches it and applies it. If no such transition exists, the mapping records an error rather than failing silently. Any transition-scoped custom fields are sent with that transition.
- **Ticket link:** the link surfaced on the Finding is `https://your-site.atlassian.net/browse/{ISSUE-KEY}` — always your public site URL, never the internal gateway.
- **Token lifecycle (OAuth):** DefectDojo owns the whole flow — it performs the authorization-code exchange, stores the access and refresh tokens, and refreshes on demand before a push, persisting the new refresh token each time (Atlassian rotates it on every refresh).
- **Credential storage:** all connection credentials (passwords, tokens, client secrets, OAuth tokens) are encrypted at rest and are never returned through the API — editing a connection shows a "leave blank to keep" placeholder for stored secrets.

## ServiceNow

The ServiceNow Integration allows you to push DefectDojo Findings as ServiceNow Incidents.
Expand Down
Loading