Skip to content

feat: Jira On Create Issue#2981

Open
alabro-bm wants to merge 21 commits intosuperplanehq:mainfrom
alabro-bm:feature/superplane-2890-on-create-issue
Open

feat: Jira On Create Issue#2981
alabro-bm wants to merge 21 commits intosuperplanehq:mainfrom
alabro-bm:feature/superplane-2890-on-create-issue

Conversation

@alabro-bm
Copy link
Contributor

@alabro-bm alabro-bm commented Feb 9, 2026

Superplane 2890

Added 3 more components for Jira:

  • On Issue Created
  • List Webhooks
  • Delete Webhooks

The idea was to create only the on issue created, but due to the debugging issues with the webhook since I already had the api implementation for list webhooks and delete webhooks I decided just add components for it.

Screenshot 2026-02-09 at 13 06 46

Notes

  1. I had to remove the webhook endpoint header check for content type. It was asking for content type application/json where as jira was sending most probably with charset=utf-8. This can be conflicting with other webhooks so I had to remove it completely.
  2. Had to implement another authentication type for the jira integration. Webhooks dont work with simple tokens, they require application to be registered in https://developer.atlassian.com/. Proper permissions to be setup for the app etc..
  3. When having 2 different type integrations when we have a dropdown there was a race condition on react side for rendering the form components that I had to resolve so that the selected form is shown.

Authentication

Jira supports two authentication methods: API Token and OAuth 2.0.

API Token

  1. Go to https://id.atlassian.com/manage-profile/security/api-tokens
  2. Click Create API token and copy the token
  3. In SuperPlane, select API Token as auth type and enter your Jira base URL, email, and token

OAuth 2.0

  1. Create the app

  2. Go to https://developer.atlassian.com/console/myapps/

  3. Click Create > OAuth 2.0 integration

  4. Name your app and agree to the terms

  5. Set permissions

Go to Permissions and add these scopes under Jira API:

  • read:jira-work - Read issues and projects
  • write:jira-work - Create issues
  • read:jira-user - Read user info
  • manage:jira-webhook - Register and delete webhooks
  1. Distribution controls

By default the app is private, meaning only the app creator can authorize it. To allow other users in your Atlassian
organization to connect:

  1. Go to the Distribution tab

  2. Click Edit and set distribution status to Sharing

  3. Fill in the required fields (app description, privacy policy URL, etc.)

  4. You do not need to submit for Marketplace listing, sharing is sufficient

  5. Get your credentials

Go to Settings to find the Client ID and create a Secret.

  1. Create the integration in SuperPlane

  2. Create a Jira integration and select OAuth 2.0 as auth type

  3. Enter the Client ID and Client Secret

  4. Copy the integration ID from the URL or integration details

  5. Set the callback URL

Go back to the Atlassian app, Authorization > OAuth 2.0 (3LO), and add:

https://SUPERPLANE_URL_GOES_HERE(OR_NGROK)/api/v1/integrations/INTEGRATION_ID_GOES_HERE/callback

  1. Connect

  2. Go back to SuperPlane and click connect

  3. You'll be redirected to Atlassian for authorization

  4. After authorizing, select the Jira Cloud site to use

alabro-bm and others added 8 commits February 5, 2026 16:33
Signed-off-by: alabro-bm <atanas.labroski@brightmarbles.io>
… and tests

Signed-off-by: alabro-bm <atanas.labroski@brightmarbles.io>
Signed-off-by: alabro-bm <atanas.labroski@brightmarbles.io>
Signed-off-by: alabro-bm <atanas.labroski@brightmarbles.io>
Signed-off-by: alabro-bm <atanas.labroski@brightmarbles.io>
Signed-off-by: alabro-bm <atanas.labroski@brightmarbles.io>
Signed-off-by: alabro-bm <atanas.labroski@brightmarbles.io>
@shiroyasha shiroyasha added the pr:stage-2/3 Needs to pass functional review label Feb 9, 2026
alabro-bm and others added 6 commits February 9, 2026 13:33
Signed-off-by: alabro-bm <atanas.labroski@brightmarbles.io>
Signed-off-by: alabro-bm <atanas.labroski@brightmarbles.io>
Signed-off-by: alabro-bm <atanas.labroski@brightmarbles.io>
Signed-off-by: alabro-bm <atanas.labroski@brightmarbles.io>
Signed-off-by: alabro-bm <atanas.labroski@brightmarbles.io>

// Use saved config as base, with user overrides on top
const configValues = configOverrides ?? integration?.spec?.configuration ?? {};
const setConfigValues = (newValues: Record<string, unknown>) => setConfigOverrides(newValues);
Copy link
Collaborator

Choose a reason for hiding this comment

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

@alabro-bm can you give me a context, why do we need these changes?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes sure, when we have dropdown select type for the integration (token vs oauth) the form is not preselected. Meaning the user will open the form without data being filled in.

In this scenario we have Token authentication and OAuth 2.0 as well, when navigating to the form the dropdown is the only field present. With this approach there is no race condition and the form is preselected and filled properly with the data relevant for the integration.

@shiroyasha shiroyasha added pr:stage-3/3 Ready for full, in-depth, review and removed pr:stage-2/3 Needs to pass functional review labels Feb 11, 2026
@shiroyasha shiroyasha requested review from shiroyasha and removed request for AleksandarCole February 11, 2026 10:12
@shiroyasha shiroyasha self-assigned this Feb 11, 2026
@shiroyasha
Copy link
Collaborator

@alabro-bm lets add connection instructions to the app, like we do for Discord for example:

CleanShot 2026-02-13 at 12 30 42@2x

Helps a lot while setting it up.

@shiroyasha shiroyasha added pr:stage-2/3 Needs to pass functional review and removed pr:stage-3/3 Ready for full, in-depth, review labels Feb 13, 2026
Signed-off-by: alabro-bm <atanas.labroski@brightmarbles.io>
@alabro-bm
Copy link
Contributor Author

@shiroyasha added the instructions

if signature == "" {
// OAuth dynamic webhooks do not send a signature header.
return http.StatusOK, nil
}
Copy link

Choose a reason for hiding this comment

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

Webhook authenticity check is effectively bypassed

High Severity

verifyJiraSignature returns success when X-Hub-Signature is absent, so OnIssueCreated.HandleWebhook accepts unsigned payloads and can emit jira.issueCreated events. This removes request authenticity validation for a public webhook endpoint and allows forged webhook deliveries if the URL is exposed.

Additional Locations (1)

Fix in Cursor Fix in Web

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is intentional

Signed-off-by: alabro-bm <atanas.labroski@brightmarbles.io>
Signed-off-by: alabro-bm <atanas.labroski@brightmarbles.io>
Signed-off-by: alabro-bm <atanas.labroski@brightmarbles.io>
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

fmt.Sprintf("multiple Jira Cloud sites found: %v -- restrict the OAuth app to a single site", names),
http.StatusBadRequest,
)
return
Copy link

Choose a reason for hiding this comment

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

OAuth setup rejects multi-site Jira accounts

Medium Severity

handleOAuthCallback hard-fails when getAccessibleResources returns more than one site, so integrations cannot be connected for users authorized on multiple Jira Cloud sites. Atlassian can return multiple resources for one token, and this branch blocks setup entirely instead of selecting or storing one usable cloudId.

Fix in Cursor Fix in Web

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's a trade-off: previously it would silently bind to an arbitrary
site (the original bug), now it fails explicitly. If you want to
support multi-site users in the future, that would be a separate
feature (e.g. a site selector in the UI). For now the explicit error
with site names listed is the safer behavior

@shiroyasha
Copy link
Collaborator

The code is ok-ish, but when I reviewed it with fresh eyes, I really hate the UX flow.
This is a deeper problem in the SuperPlane application.

@AleksandarCole @ropsii have scheduled a session to solve it on monday.
Returning it to stage-2/3 until we have it solved.

@shiroyasha shiroyasha removed their request for review February 19, 2026 18:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

mkd pr:stage-2/3 Needs to pass functional review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants