fix(oauth): trim Atlassian OAuth scopes to fix CloudFront 414 (#4388)

* fix(oauth): trim Atlassian OAuth scopes to fix CloudFront 414

* fix(oauth): restore Confluence scopes whose tools are still active

* fix(oauth): add JSM Forms scopes for form tools

* fix(oauth): restore read:issue.vote:jira scope

Jira issue retrieve tool reads fields.votes.votes and fields.votes.hasVoted
from the GET /rest/api/3/issue payload, which requires the
read:issue.vote:jira granular scope. Restoring to prevent vote data from
being omitted in retrieve responses.

* fix(oauth): drop redundant Jira granular scopes covered by classic

Atlassian recommends <50 scopes per OAuth app to keep authorize URLs
under URL-length limits. Drops 20 granular Jira read/write scopes that
are subsumed by the classic read:jira-work / write:jira-work scopes
already in the list. Existing user tokens are unaffected — Atlassian
refresh keeps originally-granted scopes; the trimmed list only applies
to new authorizations.

Kept granular scopes: delete:* (no classic equivalent) and JSM
granular scopes (separate scope family).

* fix(oauth): re-add read:issue.vote:jira to match PR description

Bugbot flagged that the previous classic-scope collapse dropped this
granular scope while the PR description still claimed it was restored.
Classic read:jira-work covers vote reads, but adding the granular
explicitly keeps the description, code, and intent aligned.
This commit is contained in:
Waleed
2026-05-01 16:30:48 -07:00
committed by GitHub
parent add55b4ffa
commit 38aa163b1c
3 changed files with 17 additions and 47 deletions
+2 -2
View File
@@ -82,7 +82,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
{
error: errorMessage,
authRequired: true,
requiredScopes: ['read:jira-work', 'read:project:jira'],
requiredScopes: ['read:jira-work'],
},
{ status: response.status }
)
@@ -202,7 +202,7 @@ export const GET = withRouteHandler(async (request: NextRequest) => {
{
error: errorMessage,
authRequired: true,
requiredScopes: ['read:jira-work', 'read:project:jira'],
requiredScopes: ['read:jira-work'],
},
{ status: response.status }
)
+11 -45
View File
@@ -441,7 +441,6 @@ export const OAUTH_PROVIDERS: Record<string, OAuthProviderConfig> = {
'read:confluence-content.all',
'read:confluence-space.summary',
'read:space:confluence',
'read:space-details:confluence',
'write:confluence-content',
'write:confluence-space',
'write:confluence-file',
@@ -451,7 +450,6 @@ export const OAUTH_PROVIDERS: Record<string, OAuthProviderConfig> = {
'write:comment:confluence',
'delete:comment:confluence',
'delete:attachment:confluence',
'read:content:confluence',
'delete:page:confluence',
'read:label:confluence',
'write:label:confluence',
@@ -460,18 +458,19 @@ export const OAUTH_PROVIDERS: Record<string, OAuthProviderConfig> = {
'search:confluence',
'read:me',
'offline_access',
'read:hierarchical-content:confluence',
'read:content.metadata:confluence',
'read:user:confluence',
'read:confluence-user',
'read:task:confluence',
'write:task:confluence',
'write:space:confluence',
'delete:space:confluence',
'read:blogpost:confluence',
'write:blogpost:confluence',
'delete:blogpost:confluence',
'read:content.property:confluence',
'write:content.property:confluence',
'read:hierarchical-content:confluence',
'read:content.metadata:confluence',
'read:user:confluence',
'read:task:confluence',
'write:task:confluence',
'write:space:confluence',
'delete:space:confluence',
'read:space.property:confluence',
'write:space.property:confluence',
'read:space.permission:confluence',
@@ -494,42 +493,14 @@ export const OAUTH_PROVIDERS: Record<string, OAuthProviderConfig> = {
'read:jira-user',
'read:jira-work',
'write:jira-work',
'write:issue:jira',
'read:project:jira',
'read:issue-type:jira',
'read:me',
'offline_access',
'read:issue-meta:jira',
'read:issue-security-level:jira',
'read:issue.vote:jira',
'read:issue.changelog:jira',
'read:avatar:jira',
'read:issue:jira',
'read:status:jira',
'read:user:jira',
'read:field-configuration:jira',
'read:issue-details:jira',
'read:issue-event:jira',
'delete:issue:jira',
'write:comment:jira',
'read:comment:jira',
'delete:comment:jira',
'read:attachment:jira',
'write:attachment:jira',
'delete:attachment:jira',
'write:issue-worklog:jira',
'read:issue-worklog:jira',
'delete:issue-worklog:jira',
'write:issue-link:jira',
'delete:issue-link:jira',
'manage:jira-webhook',
'read:webhook:jira',
'write:webhook:jira',
'delete:webhook:jira',
'read:issue.property:jira',
'read:comment.property:jira',
'read:jql:jira',
'read:field:jira',
// Jira Service Management scopes
'read:servicedesk:jira-service-management',
'read:requesttype:jira-service-management',
@@ -537,20 +508,12 @@ export const OAUTH_PROVIDERS: Record<string, OAuthProviderConfig> = {
'write:request:jira-service-management',
'read:request.comment:jira-service-management',
'write:request.comment:jira-service-management',
'read:customer:jira-service-management',
'write:customer:jira-service-management',
'read:servicedesk.customer:jira-service-management',
'write:servicedesk.customer:jira-service-management',
'read:organization:jira-service-management',
'write:organization:jira-service-management',
'read:servicedesk.organization:jira-service-management',
'write:servicedesk.organization:jira-service-management',
'read:organization.user:jira-service-management',
'write:organization.user:jira-service-management',
'read:organization.property:jira-service-management',
'write:organization.property:jira-service-management',
'read:organization.profile:jira-service-management',
'write:organization.profile:jira-service-management',
'read:queue:jira-service-management',
'read:request.sla:jira-service-management',
'read:request.status:jira-service-management',
@@ -559,6 +522,9 @@ export const OAUTH_PROVIDERS: Record<string, OAuthProviderConfig> = {
'write:request.participant:jira-service-management',
'read:request.approval:jira-service-management',
'write:request.approval:jira-service-management',
'read:form:jira-service-management',
'write:form:jira-service-management',
'delete:form:jira-service-management',
],
},
},
+4
View File
@@ -70,6 +70,7 @@ export const SCOPE_DESCRIPTIONS: Record<string, string> = {
'read:hierarchical-content:confluence': 'View page hierarchy (children and ancestors)',
'read:content.metadata:confluence': 'View content metadata (required for ancestors)',
'read:user:confluence': 'View Confluence user profiles',
'read:confluence-user': 'View Confluence user profiles (v1 API)',
'read:task:confluence': 'View Confluence inline tasks',
'write:task:confluence': 'Update Confluence inline tasks',
'delete:blogpost:confluence': 'Delete Confluence blog posts',
@@ -200,6 +201,9 @@ export const SCOPE_DESCRIPTIONS: Record<string, string> = {
'Add and remove participants from customer requests',
'read:request.approval:jira-service-management': 'View approvals on customer requests',
'write:request.approval:jira-service-management': 'Approve or decline customer requests',
'read:form:jira-service-management': 'View JSM forms and templates',
'write:form:jira-service-management': 'Attach, save, and submit JSM forms',
'delete:form:jira-service-management': 'Delete JSM forms',
// Microsoft scopes
'User.Read': 'Read Microsoft user',