---
title: Jira | Keycard
description: Access Jira issues, projects, and workflows
---

[Atlassian developer console](https://developer.atlassian.com/admin/myapps/)[OAuth setup guide](https://developer.atlassian.com/cloud/jira/platform/oauth-2-3lo-apps/)[API docs](https://developer.atlassian.com/cloud/jira/platform/rest/v3/)

Adding Jira provisions a resource (the upstream Atlassian API at `https://api.atlassian.com/ex/jira`, with default scopes pre-set) and a provider for Atlassian’s OAuth issuer - auto-provisioned on first install, or reused if you already connected another Atlassian resource.

Your application calls Keycard’s [token-exchange endpoint](/sdk/oauth/index.md) with the user’s identity, gets back a token scoped to this resource, and uses it to call Atlassian directly. Identity, [policy](/admin/access-policies/index.md), and audit log apply to every exchange - the OAuth client secret stays inside Keycard. Each exchange is recorded in the audit log with the user identity, the resource accessed, and the policy decision.

## Scopes

SCOPES

OAuth permissions Keycard requests on install. Override or add scopes in Console.

- read:jira-work

  default

- read:jira-user

  default

- write:jira-work

  default

- manage:jira-project

- manage:jira-configuration

- manage:jira-webhook

Show all 6 scopes  Show defaults only

Note

The verification endpoint returns the list of Atlassian sites the user has authorized access to, along with their cloud IDs.

## Use Jira from your code

USE FROM CODE

Call Jira from your application with a Keycard-issued token scoped to this resource.

After installing Jira, your application exchanges a Keycard-issued access token for a token scoped to this resource. Pass the user’s access token as the `subject_token`.

- [Python](#tab-panel-122)
- [TypeScript](#tab-panel-123)

```
from keycardai.oauth import Client, BasicAuth, TokenType
import requests


# Exchange the user's Keycard token for a Jira token.
with Client(
    "https://<zone-id>.keycard.cloud",
    auth=BasicAuth("<your-client-id>", "<your-client-secret>"),
) as client:
    response = client.exchange_token(
        subject_token=user_access_token,
        subject_token_type=TokenType.ACCESS_TOKEN,
        resource="https://api.atlassian.com/ex/jira",
    )


# Call Jira directly with the exchanged token.
r = requests.get(
    "https://api.atlassian.com/ex/jira/<endpoint>",
    headers={"Authorization": f"Bearer {response.access_token}"},
)
```

```
import { TokenExchangeClient } from "@keycardai/oauth/tokenExchange";


const client = new TokenExchangeClient("https://<zone-id>.keycard.cloud", {
  clientId: "<your-client-id>",
  clientSecret: "<your-client-secret>",
});


const response = await client.exchangeToken({
  subjectToken: userAccessToken,
  resource: "https://api.atlassian.com/ex/jira",
});


// Call Jira directly with the exchanged token.
const res = await fetch("https://api.atlassian.com/ex/jira/<endpoint>", {
  headers: { Authorization: `Bearer ${response.accessToken}` },
});
```

See the [OAuth SDK → Token Exchange](/sdk/oauth/#token-exchange/index.md) reference for the full client API.

## Setup

SETUP

Register your OAuth credentials with Keycard so the resource can issue tokens.

### Create an Atlassian OAuth app

1. Go to the [Atlassian Developer Console](https://developer.atlassian.com/admin/myapps/)
2. Click **Create** → **OAuth 2.0 integration**
3. Enter a name for your integration
4. Click **Create**

Note

If you’ve already created an Atlassian OAuth app for Confluence, you can reuse the same app. Skip to [Configure Jira permissions](#configure-jira-permissions).

### Configure Jira permissions

1. Go to **Permissions** in your app settings

2. Find **Jira** and click **Add**

3. Configure the scopes:

   - `read:jira-work` - Read Jira project and issue data
   - `read:jira-user` - Read user information
   - `write:jira-work` - Create and edit issues

### Set the callback URL

1. Go to **Authorization** in your app settings
2. Click **Add** next to OAuth 2.0 (3LO)
3. Enter the redirect URI provided by Keycard as the **Callback URL**

### Get credentials

1. Go to **Settings** in your app
2. Note the **Client ID** and **Secret**

### Register in Keycard

1. Open [Keycard Console](https://console.keycard.ai) → your zone → **Resources**

2. Click **Explore Resources**

3. Find and click **Jira** in the catalog

4. In the configuration dialog:

   - If this is your first Atlassian resource, copy the **Redirect URL** and verify it’s set as the callback URL in your Atlassian OAuth app. Enter the **Client ID** and **Secret** from your app settings.
   - Review the **User scopes** - the defaults (`read:jira-work`, `read:jira-user`, `write:jira-work`) are pre-populated

5. Click **Add Jira API**

Tip

If you’ve already added Confluence, the dialog will show that the existing Atlassian provider will be reused - no credentials needed. You’ll only need to review the scopes.

## Troubleshooting

TROUBLESHOOTING

Common errors when wiring Jira into your zone.

Empty accessible-resources response

The user hasn’t granted access to any Atlassian sites. During the OAuth consent flow, ensure you select at least one site. If re-authorizing, you may need to revoke and re-grant access.

Error 401: Unauthorized

The token is invalid or expired. Atlassian tokens expire after a short period. Reconnect the provider in Keycard Console - Keycard will handle the refresh if a refresh token was issued.

Error: consent\_required

The app’s permissions were updated after the user last authorized it. The user needs to re-authorize to grant the new scopes. Remove the provider connection and connect again.

## Related

RELATED

- [Catalog overview](/admin/catalog/index.md) - browse other API and MCP servers
- [Access policies](/admin/access-policies/index.md) - control who can use Jira
- [Identity providers](/admin/identity-providers/index.md) - control who can sign in

[PreviousGoogle Drive](/admin/catalog/api-servers/google-drive/index.md)[NextLinear](/admin/catalog/api-servers/linear/index.md)
