X Tutup
Skip to content

feat: Implement support for Atlassian Scoped User Tokens#928

Open
adrian-gierakowski wants to merge 1 commit intoankitpokhrel:mainfrom
adrian-gierakowski:feat-scoped-user-tokens
Open

feat: Implement support for Atlassian Scoped User Tokens#928
adrian-gierakowski wants to merge 1 commit intoankitpokhrel:mainfrom
adrian-gierakowski:feat-scoped-user-tokens

Conversation

@adrian-gierakowski
Copy link

@adrian-gierakowski adrian-gierakowski commented Jan 9, 2026

This PR introduces support for Atlassian Scoped User Tokens in jira-cli.

Previously, the CLI used Basic Authentication against the instance domain, which resulted in 401 Unauthorized for scoped tokens.

This change modifies the jira init command to fetch the cloudId from the /_edge/tenant_info endpoint. If a cloudId is found, the server URL in the configuration is updated to https://api.atlassian.com/ex/jira/<cloudId>, which is the correct endpoint for scoped tokens.

This approach ensures that the cloudId is fetched only once during the initialization process, making the implementation more efficient. The change is also backward-compatible, as it falls back to the user-provided server URL if the cloudId cannot be fetched.

fixes #850

Copilot AI review requested due to automatic review settings January 9, 2026 19:02
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements support for Atlassian Scoped User Tokens by automatically detecting cloud instances during initialization and converting the server URL to use the Atlassian API gateway endpoint format.

Key changes:

  • Adds tenant info fetching during jira init to retrieve cloudId
  • Automatically converts cloud instance URLs to the API gateway format (https://api.atlassian.com/ex/jira/<cloudId>)
  • Maintains backward compatibility by falling back to the user-provided URL if tenant info cannot be fetched

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
pkg/jira/types.go Adds TenantInfo struct to hold cloudId from tenant info endpoint
internal/cmd/init/init.go Implements fetchTenantInfo function and integrates it into the initialization flow to automatically detect and configure cloud instances

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


// TenantInfo holds tenant info.
type TenantInfo struct {
CloudId string `json:"cloudId"`
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The field name "CloudId" should follow Go naming conventions for acronyms and be "CloudID" instead. In Go, acronyms like ID, URL, HTTP, etc. should be all uppercase when used in identifier names.

Suggested change
CloudId string `json:"cloudId"`
CloudID string `json:"cloudId"`

Copilot uses AI. Check for mistakes.
if err := json.NewDecoder(res.Body).Decode(&info); err != nil {
return nil, nil // Also okay if this fails.
}
if info.CloudId == "" {
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The field reference "info.CloudId" should be "info.CloudID" to match Go naming conventions for acronyms. This needs to be updated once the struct field name is corrected.

Suggested change
if info.CloudId == "" {
if info.CloudID == "" {

Copilot uses AI. Check for mistakes.
params := parseFlags(cmd.Flags())

if info, err := fetchTenantInfo(params.server); err == nil && info != nil {
params.server = "https://api.atlassian.com/ex/jira/" + info.CloudId
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The field reference "info.CloudId" should be "info.CloudID" to match Go naming conventions for acronyms. This needs to be updated once the struct field name is corrected.

Copilot uses AI. Check for mistakes.
Comment on lines +98 to +124
func fetchTenantInfo(server string) (*jira.TenantInfo, error) {
server = strings.TrimSuffix(server, "/")
req, err := http.NewRequest(http.MethodGet, server+"/_edge/tenant_info", nil)
if err != nil {
return nil, err
}

res, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
defer func() { _ = res.Body.Close() }()

if res.StatusCode != http.StatusOK {
return nil, nil // It's okay if this fails.
}

var info jira.TenantInfo
if err := json.NewDecoder(res.Body).Decode(&info); err != nil {
return nil, nil // Also okay if this fails.
}
if info.CloudId == "" {
return nil, nil
}

return &info, nil
}
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new fetchTenantInfo function lacks test coverage. Given that this repository has comprehensive test coverage for other functions (as seen in pkg/jira/*_test.go files), this function should have tests covering:

  • Successful tenant info retrieval with valid cloudId
  • Non-200 status code responses
  • Invalid JSON response handling
  • Empty cloudId handling
  • Network errors

Copilot uses AI. Check for mistakes.
@adrian-gierakowski adrian-gierakowski marked this pull request as draft January 9, 2026 20:24
@adrian-gierakowski
Copy link
Author

converted to draft as it broken issue urls for opening in browser
we need to keep the original server url for that purpose
working on a solution

@adrian-gierakowski adrian-gierakowski marked this pull request as ready for review January 14, 2026 14:05
This commit introduces support for Atlassian Scoped User Tokens in jira-cli.

Previously, the CLI used Basic Authentication against the instance domain, which resulted in `401 Unauthorized` for scoped tokens.

This change modifies the `jira init` command to fetch the `CloudID` from the `/_edge/tenant_info` endpoint (if installation == Cloud). If a `CloudID` is found, the server URL in the configuration is updated to `https://api.atlassian.com/ex/jira/<CloudID>`, which is the correct endpoint for scoped tokens, while the originally provided server url is stored as `browse_server` (as this is used to generate urls for viewing issues etc in the browser).

This approach ensures that the `CloudID` is fetched only once during the initialization process. The change is also backward-compatible, as it falls back to the user-provided server URL if the `CloudID` cannot be fetched. Non-scoped tokes also work with this approach since they can be used to fetch CloudID and to call api.atlassian.com.

fixes ankitpokhrel#850
@tayydev
Copy link

tayydev commented Mar 5, 2026

@adrian-gierakowski out of curiosity is this work done/ready now? This is a feature gap I just spent a couple hours debugging before noticing 😔

@adrian-gierakowski
Copy link
Author

@adrian-gierakowski out of curiosity is this work done/ready now? This is a feature gap I just spent a couple hours debugging before noticing 😔

I do have this working on my fork. Not sure if this branch is up to date. Will check tomorrow.

@adrian-gierakowski
Copy link
Author

@tayydev this is the branch I'm currently using https://github.com/adrian-gierakowski/jira-cli/commits/all-new-features-2

It's got a few other features I've implemented,
see commit history for

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

API Token with Scope support

3 participants

X Tutup