---
name: atlassian-jira-oauth-app
description: The Jira Cloud layer on top of the shared `atlassian-cloud-oauth` skill — the Jira classic scope set and its granular counterparts, the split between the Jira platform, Jira Software, Jira Service Management, Confluence and Assets APIs, `/ex/jira/{cloudid}/rest/api/3/...` addressing, and the 3LO limitations that are Jira's alone. Use when asked to get Jira OAuth credentials, create a Jira Cloud app or 3LO integration, scope a Jira connector, or fix a Jira OAuth error like a 401 on `/ex/jira/...` or a scope mismatch on an endpoint you are entitled to call. Read `atlassian-cloud-oauth` first for the developer console, the single callback URL, the cloudid indirection and rotating refresh tokens. Covers Jira Cloud only — Jira Data Center/Server uses a different auth model entirely, and Confluence and Jira Service Management are separate scope families.
---

# Atlassian Jira Cloud OAuth 2.0 (3LO) App Registration

Registering the app is the shared part. **What is specific to Jira is that "Jira" is five APIs, not one** — the Jira
platform, Jira Software, Jira Service Management, Confluence and Assets each carry their own scope list inside the
same console app — and that Jira's classic scopes are broad enough that most connectors never need the granular
family at all.

The expensive Jira-specific mistake is assuming a scope you added covers a product you did not add. Adding the Jira
API does not give you Jira Service Management scopes; the consent screen rejects what the console does not know
about, and the failure looks like a permissions problem.

## Built on: `atlassian-cloud-oauth`

**Read `atlassian-cloud-oauth` first, then this file.** It owns all the portal mechanics, and this file does not
repeat them:

- The Developer Console, creating an **OAuth 2.0 integration**, enabling 3LO, account-level vs resource-level grants,
  and where the client ID and secret live.
- **One callback URL per app**, and what that forces on a platform serving several data centers.
- The classic/granular scope model in general, `offline_access`, the under-50 ceiling, and scope changes
  re-consenting every existing user.
- **Rotating refresh tokens** — 90-day inactivity expiry, 10-minute reuse leeway, and the failure that only shows up
  on the *second* refresh.
- The **cloudid indirection**: `accessible-resources`, `/ex/{product}/{cloudid}/...`, the multi-site array, and the
  required `audience` and `prompt=consent` authorize parameters.
- Distribution, the unreviewed-app warning, Marketplace approval, data residency, credential handoff, and the two
  practices Atlassian names as non-compliant (collecting API tokens, or having customers create individual 3LO apps).

If you are reading only this file, you are missing all of the above.

## Inputs to collect before you start

The base skill lists the console inputs. These are the Jira-specific ones:

| Input | Notes |
| --- | --- |
| **Which Atlassian products does the integration actually call?** | Jira platform, Jira Software, Jira Service Management, Confluence and Assets are separate APIs with separate scope lists (§2) |
| **Read-only, or create/edit issues?** | Decides how far up the classic ladder you go (§1) |
| **Does it administer projects or configuration?** | `manage:jira-project` and `manage:jira-configuration` are broad and visible on the consent screen (§1) |
| **Does it register webhooks?** | Dynamic webhook registration is its own scope (§1) |
| **Does anything depend on JQL over entity properties?** | 3LO apps cannot do this at all (§3) |
| **A Jira Cloud site to test against** | A free site is enough; a sandbox needs Premium/Enterprise |

## Quick Start

1. Work the base skill's console steps, adding the **Jira API(s)** you actually call under Permissions (§2).
2. Add the classic Jira scopes for what the integration does, plus `offline_access` (§1).
3. Confirm the client addresses `/ex/jira/{cloudid}/rest/api/3/...` and not the customer's site host (§2).
4. Check §3 before promising anything that depends on JQL over entity properties or on per-user grant revocation.
5. Finish the base skill's capture, round-trip and handoff steps, adding the Jira checks in §4.

## Jira platform state (verified 2026-09-20 — re-verify before trusting)

The Jira 3LO documentation was last updated 2026-09-18, so this is current as of writing. Check the linked pages
before following any older runbook.

- **Atlassian's stated recommendation for Jira is classic scopes**: *"When choosing your scopes, the recommendation
  is to use classic scopes"*, and for granular: *"Use these scopes only when you can't use classic scopes."* That is
  a stronger classic preference than some other Atlassian products, whose newer API generations document granular
  scopes only — do not carry a Confluence-shaped habit into a Jira app, or the reverse.
- **Jira platform REST v3** is the current generation for 3LO apps, addressed as
  `/ex/jira/{cloudid}/rest/api/3/<resource>`.
- **Known 3LO limitation:** Jira apps using 3LO **cannot declare searchable entity properties**, so they cannot
  reference entity properties in JQL. No scope fixes this; it is a property of 3LO apps.
- **An admin cannot revoke one user's grant** from the Connected Apps screen — the grant is between the app and the
  user, so an admin can only uninstall. This bites when a customer expects per-user offboarding.

If the console or the scope lists do not look like this, stop and report what you actually see rather than clicking
on.

**Jira Cloud only.** Jira **Data Center / Server** does not use this at all — it uses OAuth 1.0a via application
links (RSA-SHA1 signed) or personal access tokens, registered inside the customer's own instance, with no
Atlassian-hosted developer console, no `auth.atlassian.com`, and no cloudid. If the customer's URL is not
`*.atlassian.net` (or a custom Cloud domain), you are in the wrong document.

## 1. Jira scopes

**Classic scopes** are broad and are the recommended default. For the Jira platform API there are six:

| Scope | What Atlassian says it grants |
| --- | --- |
| `read:jira-user` | View user information — usernames, email addresses, avatars |
| `read:jira-work` | Read project and issue data; search issues; attachments and worklogs |
| `write:jira-work` | Create and edit issues, post comments as the user, create worklogs, delete issues |
| `manage:jira-project` | Create and edit project settings and project-level objects (versions, components) |
| `manage:jira-configuration` | Jira administration — create projects and custom fields, view workflows, link types |
| `manage:jira-webhook` | Fetch, register, refresh and delete dynamically declared webhooks |

**Granular scopes** are per-resource and follow a `verb:resource:jira` shape — `read:issue:jira`,
`write:comment:jira`, `delete:attachment:jira`, `write:project:jira`, and several hundred more. Atlassian's guidance
for Jira is unambiguous: *"Use these scopes only when you can't use classic scopes."*

What matters operationally, on top of the base skill's scope rules:

- **Six classic scopes cover most Jira connectors.** Reach for granular only when an endpoint's reference page offers
  no classic alternative. Mixing families within one product is the shape most likely to produce a 401 with a
  scope-mismatch message on an endpoint you are certain you are entitled to call.
- **Find the scope an endpoint needs in the OAuth scopes required field** in the Jira REST API reference. If an
  operation says *"Apps can't access this REST resource"*, no scope will help — it is not available to 3LO at all.
- **`manage:jira-configuration` is a Jira-administration scope** and reads that way on the consent screen. It is
  routinely the reason an enterprise security review stalls. Only add it if an endpoint you call actually requires
  it.

> **As of 2026-09-20, Unified.to's Jira connector requests:** `offline_access` in every per-object scope set, plus
> **classic** Jira scopes — `read:jira-user`, `read:jira-work`, `write:jira-work`, `manage:jira-configuration`,
> `manage:jira-project`, and `manage:jira-webhook` for webhook registration — with the scope set narrowed per unified
> object and per read/write direction rather than one flat union. The one exception is the project-write path, which
> **also carries the granular scope `write:project:jira`** alongside the classic project scopes: that is a mixed-family
> set, and it is the first thing to check if project creation fails with a scope error. Separately, the identity /
> login authorization requests only `read:jira-user` — with no `offline_access`, so that flow gets no refresh token by
> design. The connector also offers a **non-OAuth path** (Jira subdomain + account email + an Atlassian API token),
> which is exactly the pattern Atlassian's 3LO pages name as non-compliant (see the base skill). Confirm all of this
> with the connector's owner before registering — the connector, not this document, is the source of truth for what
> it sends.

## 2. "Jira" is five APIs

Under **Permissions → Add**, the console offers each Atlassian product API separately, and each carries its own scope
list:

| API | Scope family | Notes |
| --- | --- | --- |
| **Jira platform** | The classic six above, plus granular `…:jira` | Issues, projects, users, webhooks |
| **Jira Software** | Its own list (boards, sprints, backlogs) | Adding the Jira platform API does **not** add these |
| **Jira Service Management** | `read:servicedesk-request`, `write:servicedesk-request`, `manage:servicedesk-customer` on top of the Jira classic six | Requests, queues, customers |
| **Confluence** | An entirely separate family — see the Atlassian Confluence skill | Same console app, different product segment in the URL |
| **Assets** | Its own list | Objects and schemas |

Two consequences:

- **A scope for a product whose API you never added fails at the consent screen**, not at save time, and the message
  reads like a scope-name problem rather than a missing-API problem.
- **The product segment in the API URL follows the API you called, not the app.** Jira platform v3 reads are
  `https://api.atlassian.com/ex/jira/{cloudid}/rest/api/3/<resource>`; Confluence is `/ex/confluence/{cloudid}/…` with
  its own base path. The same cloudid commonly serves both on one site, so a URL can carry the right cloudid and the
  wrong product segment and 404 on every call.

Unified.to maintains **separate connectors for Atlassian Confluence and Atlassian Jira Service Management**, each
with its own credentials and its own scope set. One Atlassian app *can* serve several products if you add each
product's API and scopes to it, but that is a decision to make with the connectors' owners, not a default.

> **As of 2026-09-20, Unified.to's Jira connector** resolves the cloud ID during connection initialization: it calls
> the accessible-resources endpoint, takes the **first** site in the response, stores
> `https://api.atlassian.com/ex/jira/{cloudid}` as that connection's API base, and derives the site subdomain from the
> returned site URL. Because the first entry is taken, a customer whose grant covers **more than one Jira site** can
> be connected to the wrong one, and because resolution happens at setup, a later change in the grant is not
> automatically picked up.
>
> **Probable bug, worth confirming before you debug anything downstream:** the connector's *fallback* cloud-ID path —
> the one used when the primary resolution does not produce a site, and the one the non-OAuth API-token path uses,
> reading the cloud ID from the customer site's own tenant-info endpoint — builds the API base with the
> **`/ex/confluence/` product segment rather than `/ex/jira/`**. A connection that takes that branch would address the
> wrong product's API on a correct cloud ID, which presents as a 404 on every Jira call rather than as an auth error.
> Raise it with the connector's owner; do not work around it in the console.

## 3. Jira-only 3LO limitations

- **Entity properties are not searchable from a 3LO app.** Jira apps using 3LO cannot declare searchable entity
  properties, and therefore cannot reference them in JQL. If a requirement depends on querying app-written entity
  properties, 3LO is the wrong app type and no scope changes that — raise it before building.
- **Per-user grant revocation does not exist for an admin.** The grant binds the app to the user, so a site admin
  looking at Connected Apps can uninstall but cannot revoke one person's access. Customers with offboarding
  requirements need to hear this up front.

## 4. Jira-specific end-to-end checks

On top of the base skill's authorize → accessible-resources → refresh round trip:

1. Make one real read against `https://api.atlassian.com/ex/jira/{cloudid}/rest/api/3/...` — confirming the product
   segment as well as the cloudid (§2).
2. If the integration registers webhooks, exercise that path specifically — `manage:jira-webhook` is easy to omit and
   the failure only appears when a webhook is registered, not at connect.
3. If Jira Service Management or Confluence endpoints are called, confirm those APIs were added to the app and their
   scopes granted (§2) — the per-site `scopes` array from `accessible-resources` is where you see what actually
   landed.
4. Connect a user who lacks *Administer Jira* and confirm the connector degrades honestly: a scope grant does not
   exceed the user's own permissions, so project creation fails at the API, not at consent.

| Symptom | Cause |
| --- | --- |
| Auth succeeds, every Jira call 401s or 404s | Client is calling `<site>.atlassian.net` instead of `/ex/jira/{cloudid}` (base skill) |
| 404 on every call, cloudid looks correct | Wrong product segment in the API base — see the fallback-path note in §2 |
| Consent screen rejects a scope that exists in the docs | That product's API was never added to the app (§2) |
| Jira Service Management or Confluence endpoints 403 | Those APIs and their scopes are not on this app (§2) |
| Project creation fails with a scope error | Mixed classic/granular project scopes (§1) |
| Webhook registration fails, everything else works | `manage:jira-webhook` missing (§1) |
| App has `manage:jira-project` but cannot create projects | The authorizing user lacks *Administer Jira* — a permission failure, not a scope failure (§1) |
| JQL cannot see an app-written entity property | 3LO apps cannot declare searchable entity properties (§3) |
| Admin wants to revoke one user and can only uninstall | Grants are per user, not per site (§3) |
| Reads the wrong Jira site | First entry of `accessible-resources` taken blindly (§2, base skill) |
| Nothing resembles this document; no `auth.atlassian.com` | It is Jira Data Center/Server, not Cloud — wrong auth model entirely |

## Stop and ask

Beyond the base skill's list, hand back to a human when:

- The integration needs endpoints from **more than one Atlassian product** and nobody has decided whether that is one
  app or several (§2).
- A requirement depends on **JQL over entity properties**, which 3LO cannot do at all (§3).
- A customer's offboarding process assumes **per-user grant revocation** (§3).
- The scope set mixes **classic and granular** Jira scopes and nobody owns resolving it (§1).
- The request is really about **Confluence or Jira Service Management** — separate connectors, separate scope
  families, and Confluence has its own skill.
- The target is **Jira Data Center/Server**.
- The Jira scope lists do not match the **Jira platform state** section above.

## References

Jira-specific only; the base skill carries the portal-wide Atlassian references. Every link verified to resolve on
2026-09-20.

- OAuth 2.0 (3LO) apps (Jira Cloud platform) — https://developer.atlassian.com/cloud/jira/platform/oauth-2-3lo-apps/
- Jira scopes for OAuth 2.0 (3LO) and Forge apps (classic vs granular) — https://developer.atlassian.com/cloud/jira/platform/scopes-for-oauth-2-3LO-and-forge-apps/
- Jira Software scopes — https://developer.atlassian.com/cloud/jira/software/scopes-for-oauth-2-3LO-and-forge-apps/
- Jira Service Management scopes — https://developer.atlassian.com/cloud/jira/service-desk/scopes-for-oauth-2-3LO-and-forge-apps/
- Jira Cloud platform REST API v3 intro (scopes per operation, pagination) — https://developer.atlassian.com/cloud/jira/platform/rest/v3/intro/
- Jira Cloud webhooks — https://developer.atlassian.com/cloud/jira/platform/webhooks/
- Jira Cloud rate limiting — https://developer.atlassian.com/cloud/jira/platform/rate-limiting/
- Jira data security policy developer guide (app access rules) — https://developer.atlassian.com/cloud/jira/platform/data-security-policy-developer-guide/
- Basic auth for REST APIs (the API-token path) — https://developer.atlassian.com/cloud/jira/platform/basic-auth-for-rest-apis/
- Jira Cloud free signup — https://www.atlassian.com/try/cloud/signup?bundle=jira-software
- OAuth for Jira Data Center/Server (OAuth 1.0a — *not* this skill) — https://developer.atlassian.com/server/jira/platform/oauth/
