# Jira

{% hint style="info" %}
Cortex connects to many third-party vendors whose system interfaces frequently change. As a result, integration behavior or configuration steps may shift without notice. If you encounter unexpected issues, check with your system administrator or refer to the vendor's documentation for the most current information. Additionally, integration sync times vary and are subject to scheduling overrides and timing variance.
{% endhint %}

[Jira](https://www.atlassian.com/software/jira/guides/getting-started/introduction) is a project management tool that helps developers track and manage bugs and work items.

By integrating Jira with Cortex, you can drive improvements and coordinate issue management across teams. Through the integration, you can create Jira work items directly in Cortex based on an Initiative's action items. The integration also allows you to enhance insights into a number of key values for your entities:

* Customer facing incidents
* Security tickets
* Ongoing projects

## How to configure Jira with Cortex

It is possible to configure the integration with a Jira Cloud instance or a self-hosted Jira instance (using either basic auth or OAuth). You can also use Cortex Axon Relay to securely integrate your on-premises data. See the tabs below for instructions on each option.

{% tabs %}
{% tab title="Jira Cloud" %}
**Jira Cloud**

**Prerequisites**

Before configuring Cortex with Jira Cloud:

* Create a [Jira API token](https://id.atlassian.com/manage-profile/security/api-tokens). To generate a token, you must have the `Browse users and groups` permissions in Jira and access to the needed Jira projects.
* If you are using a scoped token, you will need your [Atlassian Cloud ID](https://support.atlassian.com/jira/kb/retrieve-my-atlassian-sites-cloud-id/). Scoped tokens must include the following scopes:
  * Read: `jira-work`, `jira-user`, `project-category:jira`, `project:jira`, `project-version:jira`, `project.property:jira`, `project.component:jira`, `issue-type:jira`, `issue-type-hierarchy:jira`, `user:jira`, `avatar:jira`, `project.avatar:jira`, `application-role:jira`, `group:jira`
  * Write: `jira-work`

**Configure the integration in Cortex**

1. In Cortex, navigate to the [Jira settings page](https://app.getcortexapp.com/admin/integrations/jira):
   * Click **Integrations** from the main nav. Search for and select **Jira**.
2. Click **Add configuration**. then select **Cloud** for the integration type.
   * If you are using a scoped token, select **Cloud (scoped token)**.
3. In the Jira integration modal, "Jira Cloud" is selected by default in the upper right corner. Configure the integration form:
   * **Account alias**: Enter an alias for your account.
   * **Subdomain**: Enter the subdomain for your Jira instance.
     * For example, this field would take `cortex-docs` from `https://cortex-docs.atlassian.net`.
   * **Base URL**: This field automatically populates `atlassian.net`.
     * If you are using a legacy Jira Cloud instance (i.e., you access your Jira instance on `jira.com`), change the base URL from the dropdown.
   * **Email**: Enter the email address associated with the user who generated the token in Jira.
     * Note: The email address associated with a given Jira token **must** match the email address of the user associated with that token.
   * **API token**: Enter your Jira API token.
4. Click **Save**.
   {% endtab %}

{% tab title="On-prem (Basic)" %}
**Jira on-prem (Basic)**

**Prerequisite**

If you're using a self-hosted instance of Jira, you'll need to verify that your Cortex instance is able to reach the Jira instance.\
\
We route our requests through a static IP address. Reach out to support at <help@cortex.io> to receive details about our static IP. If you're unable to directly allowlist our static IP, you can route requests through a secondary proxy in your network that has this IP allowlisted and have that proxy route traffic to your Jira instance.

**Configure the integration in Cortex**

1. In Cortex, navigate to the [Jira settings page](https://app.getcortexapp.com/admin/settings/jira):
   1. In Cortex, click your avatar in the lower left corner, then click **Settings**.
   2. Under "Integrations," click **Jira**.
2. Click **Add configuration**.
3. In the upper right corner of the Jira integration modal, click the dropdown labeled `Cloud`. Select `On-prem (basic auth)`.
4. Configure the Jira integration form:
   * **Account alias**: Enter an alias for your account.
   * **Host**: Enter the URL for your Jira on-premises host.
   * **Frontend host**: Enter the URL for your Jira on-premises frontend host.
   * **Username** and **Password**: Enter your Jira username and password.
5. Click **Save**.
   {% endtab %}

{% tab title="On-prem (OAuth)" %}
**Jira on-prem (OAuth)**

**Prerequisites**

To integrate Cortex with Jira using OAuth, you must be running a self-hosted Jira instance with Jira server version 8.22 or higher.

If you're using a self-hosted instance of Jira, you'll need to verify that your Cortex instance is able to reach the Jira instance.\
\
We route our requests through a static IP address. Reach out to support at <help@cortex.io> to receive details about our static IP. If you're unable to directly allowlist our static IP, you can route requests through a secondary proxy in your network that has this IP allowlisted and have that proxy route traffic to your Jira instance.

**Step 1: Create an application link from Jira**

1. In your Jira server, navigate to Settings > Applications > Application Links. Click **Create link**.
2. Configure the application link settings:
   * **Application type**: Select `External`.
   * **Direction**: Select `Incoming`.
   * **Redirect URL**: For default configuration, enter the URL of your Cortex instance appended with `/oauth/internal/jira`. For a non-default configuration, enter the URL of your Cortex instance appended with `/oauth/internal/jira/`.
   * **Permission**: Select `write`.
3. Click **Save**.
4. The application link will have an associated client ID and client secret. Copy these values and store them in a secure location, as you will need them in the next steps.

**Step 2: Configure the integration in Cortex**

1. In Cortex, navigate to the [Jira settings page](https://app.getcortexapp.com/admin/settings/jira):
   1. In Cortex, click your avatar in the lower left corner, then click **Settings**.
   2. Under "Integrations," click **Jira**.
2. Click **Add configuration**.
3. In the upper right corner of the Jira integration modal, click the dropdown labeled `Cloud`. Select `On-prem (OAuth)`.
4. Configure the Jira integration form:
   * **Account alias**: Enter an alias for your account.
   * **Host**: Enter the URL for your Jira on-premises host.
   * **Frontend host**: Enter the URL for your Jira on-premises frontend host.
   * **Client ID** and **Client secret**: Enter the client ID and secret associated with the application link you created in the previous steps.
5. Click **Save**.
6. You will be redirected to the Jira settings page. Click **Install** next to your integration name.
   * A confirmation modal will appear, asking you to allow Cortex access to your Jira account.
   * The accessing user can be a user persona or a system account. We recommend using a system account to maintain your organization's access in case the user who set up the integration leaves your organization.
     {% endtab %}

{% tab title="Relay broker" %}
**Configure Jira with Cortex Axon Relay**

See [Internally hosted integrations](https://docs.cortex.io/ingesting-data-into-cortex/integrations/axon-relay) for instructions.
{% endtab %}
{% endtabs %}

**Configure the integration for multiple Jira accounts**[**​**](https://docs.cortex.io/docs/reference/integrations/jira#configure-the-integration-for-multiple-propsintegration-accounts)

The Jira integration has multi-account support. You can add a configuration for each additional by repeating the process above.

Each configuration requires an alias, which Cortex uses to correlate the designated with registrations for various entities. Registrations can also use a default configuration without a listed alias. You can edit aliases and default configurations from the Jira page in your Cortex settings. Select the edit icon next to a given configuration and toggle **Set as default** on. If you only have one configuration, it will automatically be set as the default.

## Set a default JQL query for your Jira integration

You can set a custom JQL query for your [Jira integration instances](#tenant-level) and for [individual entities](#entity-level). This allows you to filter which Jira work items are surfaced on entity pages or in other places in Cortex where CQL is used.

The default JQL applies to `jira.issues()` and `jira.numOfIssues()` but not to `jira.rawJql()`.

{% hint style="warning" %}
Note that if you define additional filter logic for your default JQL query when writing a Scorecard rule, you must add that logic in a filter clause. See [Adding filter logic to the default JQL query in a Scorecard](#adding-filter-logic-to-the-default-jql-query-in-a-scorecard) for more information.
{% endhint %}

{% tabs %}
{% tab title="Tenant level" %}
**Set default JQL query at a tenant level**

From the [Jira settings page](https://app.getcortexapp.com/admin/settings/jira) in Cortex, you can set a custom JQL query for your Jira integration.

When Cortex queries for Jira work items, the `statusCategory` is directly grabbed from the [API response](https://docs.atlassian.com/DAC/javadoc/jira/reference/com/atlassian/jira/issue/status/category/StatusCategory.html).

The default query — `statusCategory in ("To Do", "In Progress")` — will filter your Jira tickets to display only those with `To Do` and `In Progress` statuses, excluding closed tickets. The `indeterminate` status category will map to `In Progress` according to the API. Cortex does not use the `status` field for mapping these categories.

Entering a custom JQL query on the Jira integration settings page allows you to override the default for all entities in your workspace. To map work items with a custom status, you can write a custom JQL query that uses `status` instead of `statusCategory`.
{% endtab %}

{% tab title="Entity level" %}
**Set default JQL query at entity level**

You can configure default JQL for entities in their [entity YAML](https://docs.cortex.io/entities#defining-entities-via-yaml-file). For example:

```yaml
x-cortex-issues:
    jira:
      projects:
      - name: PROJECT_A
        alias: Jira Project A
      defaultJql: "project = project_a"
```

{% endtab %}
{% endtabs %}

### Fallback logic for default JQL

It is possible to set custom JQL at both the entity and tenant level, but note the fallback logic:

1. If any JQL is passed into a query, Cortex uses that.
2. If not, Cortex uses entity-level default JQL.
3. If not, Cortex uses tenant-wide default JQL.
4. If none, then no JQL is used for filtering.

### Adding filter logic to the default JQL query in a Scorecard

The CQL statement will use the default JQL setting in a Scorecard rule only if you do not define additional filter logic. Any filter logic applied to the statement will override the default JQL query.

To work around this: If you need to include additional filter logic on your query in a Scorecard, you can move the filter logic to the filter clause.

For example, if your default JQL query is set to `"project = project_a"`, then you can add `jira.issues()` to a Scorecard rule to automatically surface only the work items relating to Project A. However, you cannot use `jira.issues(some_other_filter_logic)` in a Scorecard; Cortex will not append your default JQL to the additional filter logic.

In this example, the workaround would be to add a filter clause:\
`jira.issues().filter(some_other_filter_logic)`.

## How to connect Cortex entities to Jira labels, components, or projects

### Discovery

By default, Cortex will tie Jira tickets to entities by searching for any tickets where the `label`, `component`, or `project` field for the work item includes the [Cortex tag](https://docs.cortex.io/entities#cortex-tag). For example, if your Cortex tag is “my-entity,” then the corresponding tickets in Jira should have “my-entity” as a label, component, or project.

If your Jira label/component/project doesn't cleanly match the Cortex tag, you can override this in the Cortex [entity descriptor](https://docs.cortex.io/entities#defining-entities-via-yaml-file).

Without an override, a ticket's label, component, or project must **exactly match** the Cortex tag in the descriptor.

### Connecting via YAML or the Cortex UI

{% tabs %}
{% tab title="Cortex UI" %}
**Connect Jira entities via the Cortex UI**

1. Navigate to an [entity's details page](https://docs.cortex.io/ingesting-data-into-cortex/entities/details) in Cortex.
2. In the upper right corner, click **Configure entity**.\\

   <div align="left"><figure><img src="https://826863033-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FJW7pYRxS4dHS3Hv6wxve%2Fuploads%2Fgit-blob-4377b900f82f853bbf04515ee4b722a56ebc35c1%2Fconfigure-entity-team.jpg?alt=media" alt="In the upper right side of an entity, click &#x22;Configure entity.&#x22;"><figcaption></figcaption></figure></div>
3. Click the **Project management** tab, then click **+Add**.\\

   <div align="left"><figure><img src="https://826863033-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FJW7pYRxS4dHS3Hv6wxve%2Fuploads%2Fgit-blob-76d2fab28795fc034d44dcf53012d9c3667f986e%2Fjira-ui.jpg?alt=media" alt="Click Project management, then click Add." width="563"><figcaption></figcaption></figure></div>
4. In the side panel, configure the details:
   * **Jira service type**: Choose component, label, or project.
   * **Alias**: If you have multiple Jira configurations, select which one this service is associated with.
   * **Name**: Enter the name of the service.
5. At the bottom of the side panel, click **Add**.
   {% endtab %}

{% tab title="Entity YAML" %}
**Editing the entity descriptor**

If you need to override automatic discovery, you can define `x-cortex-issues` blocks in your Cortex entity descriptor.

Note: For all of the following, `alias` is optional, and the default Jira configuration will be used if not provided. You can use Jira `labels`, `components`, or `projects` to match entities.

Each of these blocks has the same field definitions.

| Field   | Description                                                                                      | Required |
| ------- | ------------------------------------------------------------------------------------------------ | :------: |
| `name`  | Label name in Jira                                                                               |   **✓**  |
| `alias` | Alias for the configuration in Cortex (only needed if you have opted into multi-account support) |          |

```yaml
x-cortex-issues:
  jira:
    labels:
      - name: labelA
        alias: alias1
      - name: labelB
```

```yaml
x-cortex-issues:
  jira:
    components:
      - name: component1
        alias: alias1
```

```yaml
x-cortex-issues:
  jira:
    projects:
      - name: project1
        alias: alias1
```

```yaml
x-cortex-issues:
  jira:
    labels:
      - name: label1
      - name: label2
      - name: label3
    components:
      - name: component1
      - name: component2
```

By default, Cortex will surface outstanding issues per entity in the catalog with a default [JQL](https://www.atlassian.com/blog/jira-software/jql-the-most-flexible-way-to-search-jira-14) query: `statusCategory in ("To Do", "In Progress")`. If you'd like to override this, you can provide a new default query with:

```yaml
x-cortex-issues:
  jira:
    defaultJql: 'status = "In Progress"'
```

{% endtab %}
{% endtabs %}

### Identity mappings

Cortex maps Jira accounts to team members defined in the team catalog, so you do not need to define Jira users in a team member's YAML file.

You can confirm that users' Jira accounts are connected from the [Jira user mappings section in Settings](https://app.getcortexapp.com/admin/settings/jira-mappings).

## Using the Jira integration

#### Entity pages

Once the integration is established, you'll be able to pull in data about the work items in any linked Jira instances for a given entity:

* **Number of issues:** Unresolved issues associated with an entity that have the JQL status "in progress" or "to do"
* **Number of issues from JQL query:** Issues associated with an entity that match an arbitrary JQL query

Cortex will tie Jira tickets directly to entities within the catalog. Click **Issue tracking** in the entity's sidebar to see associated Jira tickets.

From this tab you can find a list of all issues with a label that matches the Cortex tag.

* **Key:** The issue key (or "ticket number") for a Jira work item.
* **Issue summary:** Title of the Jira work item and the user designated as the issue reporter.
* **Assignee:** User designated as the work item assignee.
* **Priority:** The work item's priority level in Jira - Lowest, Low, Medium, High, Highest. This will display with the [icon](https://support.atlassian.com/jira-service-management-cloud/docs/what-are-priority-levels-in-jira-service-management/) that corresponds to the priority level in your Jira instance.
* **Created:** Date the work item was created.
* **Due:** Due date for the work item, if applicable.

This list will also be available from a team's homepage when the team's Cortex tag matches a `label`, `component`, or `project` in Jira.

#### Initiatives

Initiatives allow you to set deadlines for specific rules or a set of rules in a given Scorecard and send notifications to users about upcoming due dates.

From the Issues tab of an Initiative, you can automatically create a Jira ticket from a failing rule.

Read about creating Jira issues from Initiatives in the documentation: [Creating issues based on initiatives](https://docs.cortex.io/improve/initiatives/issue-config).

#### Dev homepage

The Jira integration enables Cortex to pull information about issues into the [dev homepage](https://docs.cortex.io/streamline/homepage). You can find open work items assigned to you under the [Issues tab](https://app.getcortexapp.com/admin/home?activeTab=Issues). The work items that display will depend both on the Jira instances you've connected and the JQL query defined in Settings.

Work items are refreshed every 5 minutes. You can use the **Refresh work items** button to manually refresh issues at any point.

### Scorecards and CQL

With the Jira integration, you can create Scorecard rules and write CQL queries based on Jira work items.

See more examples in the [CQL Explorer](https://app.getcortexapp.com/admin/cql-explorer) in Cortex.

<details>

<summary>Issues</summary>

Number of **unresolved** issues associated with the entity, where unresolved is defined as the JQL status = "Open" OR status = "To Do".

**Definition:** `jira.numOfIssues()`

**Example**

For a Scorecard measuring entity maturity, you can use this expression to make sure entities have fewer than 3 Jira issues:

```
jira.numOfIssues() <= 10
```

</details>

<details>

<summary>Issues from JQL query</summary>

Number of issues associated with the entity based on arbitrary JQL query.

**Definition:** `jira.numOfIssues(jqlQuery: Text | Null)`

**Example**

For a more specific rule in an entity maturity Scorecard, you can use this expression with a JQL query to make sure entities have no more than 3 open customer-facing tickets.

```
jira.numOfIssues("status = \"Open\" and labels = \"customer-facing\"") <= 3
```

</details>

### View integration logs <a href="#still-need-help" id="still-need-help"></a>

## Background sync

The [engineering homepage](https://docs.cortex.io/streamline/homepage) runs a background job every 5 minutes to refresh the Issues tab.

## FAQs and troubleshooting

**I've added a Jira integration, but I'm not sure what JQL is being generated to query Jira.**

When running Scorecard rules, Cortex appends `AND (component = cortex-tag OR labels = cortex-tag OR project = cortex-tag)` to the [JQL you defined](#jira-default-jql), where `cortex-tag` is the [Cortex tag](https://docs.cortex.io/entities#cortex-tag).

**My Scorecard rules are failing, even though there are tickets in my Jira instance.**

Make sure that the ticket has a label, component, or project that matches **exactly** with the Cortex tag or the list defined in your entity descriptor.

**I received "Configuration error: Integration error for Jira: Unexpected HTTP response 0".**

When using Jira Cloud, you'll need to create a Jira API token and add it on in Jira Settings in Cortex. The email address in Settings **must be the same as the user that the token is associated with**. Cortex also expects only the subdomain of your Jira instance, not the entire URL.

**I received "Configuration error: Jira: Unexpected HTTP response 403: Forbidden".**

1. Make sure that the entity name in Cortex matches the label, component, or project name in Jira.
2. Make sure the subdomain and base URL correspond with the Jira instance you're trying to connect.
3. Verify that the Jira token you added is still valid. You can run the following [curl command](https://developer.atlassian.com/cloud/jira/platform/basic-auth-for-rest-apis/#supply-basic-auth-headers) to confirm:

```
curl -D- \
-X GET \
-H "Authorization: Basic {{your-token}}" \
-H "Content-Type: application/json" \
"https://{{your-domain}}.atlassian.net/rest/api/2/issue/{{valid-ticket-number}}"
```

**I configured the integration, but I am not seeing Work Items populate.**

The background job fetches work items every 5 minutes. However, a fresh integration configuration may result in longer waiting times, as it also fetches historical data.

## Still need help?[​](https://docs.cortex.io/docs/reference/integrations/aws#still-need-help) <a href="#still-need-help" id="still-need-help"></a>

The following options are available to get assistance from the Cortex Customer Engineering team:

* **Email**: <help@cortex.io>, or open a support ticket in the in app Resource Center
* **Slack**: Users with a connected Slack channel will have a workflow added to their account. From here, you can either @CortexTechnicalSupport or add a `:ticket:` reaction to a question in Slack, and the team will respond directly.

Don’t have a Slack channel? Talk with your Customer Success Manager.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.cortex.io/ingesting-data-into-cortex/integrations/jira.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
