Skip to content

Jira Integration

The Jira integration connects WhiteLotusAI to Jira Cloud so users can retrieve project and issue information through conversational requests.

Documentation status

Source-inspected baseline. Jira Cloud OAuth, project listing, issue search, issue retrieval, and issue creation are present in the repository. End-to-end behavior, authorization boundaries, and production readiness require verification.

Read-only release requirement

The initial release must allow approved project and issue retrieval only. The registered create_issue tool, the requested write:jira-work OAuth scope, and the POST /jira/issue route must be addressed before the integration can be considered strictly read-only.

Integrations overview Gmail integration

1. Purpose and scope

The integration provides a path between the WhiteLotusAI chat service, its integrations service, and the Jira Cloud REST API v3.

The source currently represents the following capabilities:

  • List Jira projects accessible to the connected account.
  • Search issues by project and optional status.
  • Retrieve an issue using its key.
  • Create a Jira issue, subject to the required release restriction.

The implementation targets Jira Cloud. Jira Data Center compatibility must not be assumed without a separate authentication and API compatibility review.

Capability summary

Capability Registered operation Initial release
Project discovery list_projects Permitted, subject to authorization
Issue search search_issues Permitted, subject to authorization
Issue retrieval get_issue Permitted, subject to authorization
Issue creation create_issue Blocked

Scope of this document

This page distinguishes capabilities represented in source code from controls that still require testing. Registration of a tool, existence of a route, or successful compilation does not establish that the feature is secure or production-ready.

2. Architecture and request flow

The integration consists of the chat plugin, tool registry and permission checks, integrations routes, OAuth credential resolution, and the Jira API client.

Request lifecycle

flowchart TD
    U["User request"] --> C["WhiteLotusAI chat service"]
    C --> R["Tool registry and authorization"]
    R --> P{"Approved operation?"}

    P -- "No" --> D["Reject request"]
    P -- "Yes" --> I["Integrations service"]
    I --> A["Validate caller and resolve user connection"]
    A --> T["Resolve access token and cloud ID"]
    T --> J["Jira Cloud REST API v3"]
    J --> N["Normalize result"]
    N --> O["Return response through chat"]

    classDef action fill:#E8F1FE,stroke:#356AC3,color:#172B4D
    classDef decision fill:#FFF2CC,stroke:#B8860B,color:#4D3B00
    classDef rejection fill:#FCE8E6,stroke:#C5221F,color:#5F1512
    classDef success fill:#DDF5E5,stroke:#25804B,color:#16452B

    class U,C,R,I,A,T,J,N action
    class P decision
    class D rejection
    class O success

The diagram describes the intended request flow. It is not evidence that every boundary has been verified in a deployed environment.

Source components

Component Repository location Responsibility
Jira chat plugin chat/package/app/plugins/jira/plugin.py Tool definitions, intent routing, and execution
Tool registry chat/package/app/plugins/registry.py Tool registration and dispatch
Permission checks chat/package/app/plugins/permissions.py Default tool-category permissions
OAuth and integration routes integrations/package/app/handlers/integration_handlers.py OAuth processing, credential resolution, and Jira routes
Jira API client integrations/package/app/managers/jira_client.py Jira Cloud API requests and authentication modes
Alternate Jira handlers integrations/package/app/handlers/jira_handlers.py Additional handlers requiring reachability review

The plugin supplies X-User-Id and X-Internal-Secret headers when a user ID is available.

Internal service boundary

Do not trust a caller-supplied user ID solely because it appears in a header. Verify that the internal secret is validated server-side, that untrusted clients cannot impersonate another user, and that every reachable route enforces the intended authentication and authorization policy.

3. Registered tools and intent routing

The Jira plugin is implemented in chat/package/app/plugins/jira/plugin.py.

Tool Category Purpose Release policy
list_projects READ Lists projects accessible to the account Allow after authorization checks
search_issues READ Searches issues by project and optional status Allow after authorization checks
get_issue READ Retrieves an issue by its key Allow after authorization checks
create_issue WRITE Creates an issue Deny in read-only mode

The intent-routing logic recognizes Jira-related terms and issue keys such as PROJ-123. Recognized issue keys are routed to get_issue; other Jira-related requests can be routed to search_issues.

Example user requests

User request Intended operation
“Show my accessible Jira projects.” list_projects
“Find open issues in KAN.” search_issues
“Show issue PROJ-123.” get_issue
“Create a Jira issue for this bug.” Reject during the read-only release

These examples describe intended routing rather than verified end-to-end results.

Confirmation is not authorization

A tool definition containing requires_confirmation=True is not a substitute for a server-side read-only policy. A write operation must be rejected before the Jira client is invoked, including when a caller bypasses the chat interface.

4. Authentication and configuration

The Jira client supports two authentication modes. They have different identity and authorization implications.

This mode associates Jira credentials with an individual connected user.

  • Uses a bearer access token.
  • Uses an Atlassian cloud ID to construct the API base URL.
  • Resolves credentials associated with the requesting user.
  • Attempts access-token refresh when expiry is detected and a refresh token is available.

Preferred for multi-user deployments: this model can preserve each user's Jira permissions, provided token resolution, caching, and route authorization are correctly implemented.

This mode uses an account configured through environment variables.

  • JIRA_EMAIL identifies the configured account.
  • JIRA_API_TOKEN supplies its API token.
  • JIRA_BASE_URL specifies the Jira site base URL.

This is a shared configured-account model rather than per-user OAuth. Its availability in the code does not establish that it is appropriate for a multi-user production environment.

Security requirement: prevent the shared account from becoming an unintended fallback for users who have not connected Jira individually.

Configuration reference

Variable Purpose
JIRA_CLIENT_ID Atlassian OAuth client ID
JIRA_CLIENT_SECRET Atlassian OAuth client secret
JIRA_REDIRECT_URI Registered OAuth callback URI
JIRA_BASE_URL Jira site base URL for environment-based Basic Auth
JIRA_EMAIL Account email for Basic Auth
JIRA_API_TOKEN API token for Basic Auth
JIRA_DEFAULT_PROJECT Fallback project key for issue searches
JWT_SECRET_KEY Secret used to validate application JWTs
JWT_ALGORITHM Configured JWT validation algorithm
INTERNAL_SECRET Secret for internal service authentication
FRONTEND_URL Frontend destination after OAuth processing

The plugin's env_vars property is empty because it expects user-specific OAuth credentials or the integrations service's configured Basic Auth mode. The plugin performs a separate configuration check for OAuth client settings and Basic Auth settings.

Safe configuration example

Use your existing environment-management mechanism and secret store. The following is a template, not a complete deployment configuration.

# Atlassian OAuth
JIRA_CLIENT_ID=<your-oauth-client-id>
JIRA_CLIENT_SECRET=<your-oauth-client-secret>
JIRA_REDIRECT_URI=<your-registered-callback-uri>

# Optional environment-based Basic Auth
JIRA_BASE_URL=<your-jira-site-url>
JIRA_EMAIL=<your-service-account-email>
JIRA_API_TOKEN=<your-jira-api-token>

# Application and internal service authentication
JWT_SECRET_KEY=<your-application-jwt-secret>
JWT_ALGORITHM=<your-configured-jwt-algorithm>
INTERNAL_SECRET=<your-internal-service-secret>

# Optional issue-search default
JIRA_DEFAULT_PROJECT=KAN
FRONTEND_URL=<your-frontend-url>

Protect credentials

  • Never commit real tokens, client secrets, or signing secrets.
  • Keep local environment files out of version control.
  • Do not print credentials in logs or expose them in browser-visible URLs.
  • Use separate credentials and access policies for development and production.
  • Rotate exposed credentials and invalidate compromised sessions promptly.

5. OAuth authorization flow

The OAuth handlers are defined in integrations/package/app/handlers/integration_handlers.py.

Authorization sequence

sequenceDiagram
    participant U as User browser
    participant W as WhiteLotusAI
    participant S as OAuth state store
    participant A as Atlassian

    U->>W: Start Jira connection
    W->>W: Validate application JWT
    W->>S: Store state bound to user
    W-->>U: Redirect to Atlassian
    U->>A: Authorize requested access
    A-->>U: Redirect with code and state
    U->>W: OAuth callback
    W->>S: Validate and consume state
    W->>A: Exchange authorization code
    A-->>W: Access and refresh tokens
    W->>A: Retrieve accessible resources
    A-->>W: Cloud ID metadata
    W->>W: Persist user connection
    W-->>U: Connection result

The sequence reflects the documented implementation flow. State-store durability, expiry enforcement, token persistence, and callback behavior must be verified through tests.

Implemented flow

  1. The frontend sends an application JWT to the Jira authorization-start endpoint.
  2. The handler validates the JWT and extracts the user ID.
  3. An OAuth state value is created and stored against that user.
  4. The browser is redirected to Atlassian's authorization endpoint.
  5. The callback validates and consumes the stored state.
  6. The authorization code is exchanged for access and refresh tokens.
  7. The handler requests accessible resources to obtain the Jira cloud ID.
  8. Tokens, expiry information, and cloud ID metadata are stored for the user.
  9. The Jira connection is marked active.
  10. The frontend receives a connection result.

Requested OAuth scopes

The current source requests the following scopes:

Scope Purpose Read-only review
read:jira-work Read Jira work information Review against the required operations
write:jira-work Enables write capabilities within its granted scope Remove if not required
read:jira-user Read permitted Jira user information Confirm whether the integration requires it
offline_access Supports refresh-token access Retain only as required by the OAuth design

Least privilege

Before release, remove unnecessary write access and verify the scopes actually granted. Hiding a write tool from the interface does not revoke the authority of an already-issued token.

OAuth security requirements

The current authorization-start endpoint accepts the application JWT in a query parameter. This can expose credentials through browser history, server and proxy logs, monitoring systems, or other URL-handling infrastructure.

Before production approval:

  • Replace query-string credential transport with a safer authenticated flow where possible.
  • Verify JWT signature, expiry, issuer, audience, and applicable claims.
  • Ensure OAuth state is unpredictable, single-use, expires appropriately, and is bound to the initiating user.
  • Validate the callback and authorization-code exchange.
  • Store access and refresh tokens securely and associate them with the correct user.
  • Ensure refresh-token rotation and persistence are handled correctly where applicable.
  • Sanitize provider errors and token-exchange failures before logging.
  • Validate the configured redirect URI against the registered OAuth callback.

6. Jira Cloud API behavior

6.1 Project listing

The client calls the Jira project search endpoint and requests up to 50 results.

The normalized response includes:

  • Project key.
  • Project name.
  • Project type.

The current implementation does not establish that every page of a large Jira site is retrieved. Treat full pagination as unsupported until implemented and tested.

The client constructs JQL using a project key and, when supplied, a status value. Results are ordered by most recently updated, with a limit of 20 issues and selected fields.

Field Purpose
Summary Issue title
Status Current workflow status
Assignee Assigned user
Priority Issue priority
Issue type Classification of the issue

The chat plugin displays up to eight returned issues in its formatted response.

The plugin currently defaults searches without a project argument to KAN. The integrations route also supports JIRA_DEFAULT_PROJECT as its fallback. Confirm that the intended default is consistent across the plugin, service configuration, and any frontend input.

Search behavior

Verify JQL construction, escaping, supported status values, result limits, and permission-filtered results. Do not assume that an issue's absence from search means the issue does not exist; the connected account may not have access to it.

6.3 Issue retrieval

The client retrieves a single issue using its key and formats the following fields:

  • Issue key.
  • Summary.
  • Status.
  • Assignee.
  • Priority.
  • Description.
  • Browse URL.

The current chat response includes the key, summary, status, assignee, and issue URL. A field returned by the client is not necessarily displayed by the chat layer.

6.4 Issue creation

The client and plugin include issue-creation functionality. However, the initial release is intended to be read-only.

Do not enable issue creation in production until a separately approved write-capability design establishes the required scopes, authorization checks, user confirmation behavior, audit logging, and tests.

6.5 Error handling and logging

The integrations service translates Jira client failures into HTTP errors. The chat plugin catches execution errors and often returns a generic availability response.

The client currently logs the upstream response body when issue creation fails.

Review that logging path to avoid recording confidential issue content, personal data, tokens, or unnecessary provider response details. Prefer sanitized error categories, correlation identifiers, and relevant HTTP status codes.

7. Read-only security enforcement

Read-only behavior must be enforced by the backend, not merely by the interface or the tool registry.

Required controls

  • Allow only explicitly approved read tools in the server-side execution path.
  • Reject create_issue before the Jira client is invoked.
  • Restrict write-capable integration routes independently of chat registration.
  • Protect POST /jira/issue from unauthorized and direct callers.
  • Verify that confirmation flags cannot bypass the read-only policy.
  • Ensure denied requests never reach Jira's issue-creation endpoint.
  • Verify that denied requests leave Jira unchanged.
  • Review alternate and legacy handlers for bypass paths.
  • Test the policy using direct HTTP requests as well as conversational requests.

Authorization decision flow

flowchart TD
    A["Incoming Jira operation"] --> B["Authenticate caller"]
    B --> C{"Valid identity and connection?"}

    C -- "Yes" --> D{"Operation explicitly allowlisted?"}
    D -- "No" --> Y["Deny before provider call"]

    D -- "Yes" --> E["Authorize user and resource"]
    E --> F{"Access permitted?"}
    F -- "Yes" --> G["Execute approved Jira read"]
    C -- "No" --> X["Reject request"]
    F -- "No" --> X
    G --> H["Return sanitized result"]

    classDef action fill:#E8F1FE,stroke:#356AC3,color:#172B4D
    classDef decision fill:#FFF2CC,stroke:#B8860B,color:#4D3B00
    classDef rejection fill:#FCE8E6,stroke:#C5221F,color:#5F1512
    classDef success fill:#DDF5E5,stroke:#25804B,color:#16452B

    class A,B,E,G action
    class C,D,F decision
    class X,Y rejection
    class H success

This is the required policy model, not a claim that all checks are currently implemented.

Release-blocking defect

If issue creation succeeds while read-only mode is active, treat it as an authorization defect. Disable the affected route or capability and resolve the bypass before release.

8. Credential isolation and caching

The OAuth resolver checks the user's Jira connection, resolves a token and cloud ID, checks token expiry, and attempts refresh when necessary.

Verify the following conditions:

Control Required behavior
User isolation One user cannot access another user's tokens or Jira data
Cache isolation Cache keys are scoped to the correct user and relevant query
Connection state Connection authorization is checked before cached data is returned
Cache invalidation Disconnects and relevant permission changes invalidate affected data
Token lookup failure A failed lookup does not fall back to another user's credentials
Shared account Environment-based Basic Auth cannot unintentionally expose shared-account data
Refresh behavior Refreshed credentials are persisted and associated with the correct user
Legacy handlers Alternate routes cannot bypass per-user authorization

The repository also contains integrations/package/app/handlers/jira_handlers.py. Its handler functions call the Jira client without explicitly passing per-user OAuth parameters.

Verify whether these handlers are registered or reachable in the deployed application. If reachable, ensure they cannot bypass user-specific authorization or the read-only policy.

9. Troubleshooting

Symptom Investigation
Jira cannot be connected Check OAuth client configuration, callback URI, state validation, and Atlassian consent
No accessible resources returned Verify the Atlassian account's accessible sites and granted access
Connection appears inactive Inspect connection state and per-user token persistence
Access token has expired Verify refresh-token availability, configuration, and refreshed-token persistence
Project listing is empty Check the connected site, project permissions, and response handling
Issue search returns no results Verify project key, status filter, JQL construction, and account permissions
Issue retrieval fails Validate the issue key and confirm the connected user can view the issue
Insufficient permissions Review Jira project permissions, user access, and OAuth scopes
Issue creation succeeds in read-only mode Treat as a release-blocking authorization defect
Jira is temporarily unavailable Inspect sanitized provider status, request timeouts, and service health

Safe diagnostic procedure

  1. Record the timestamp, affected operation, and correlation ID.
  2. Check the chat and integrations service logs.
  3. Verify connection status and non-secret configuration.
  4. Inspect the sanitized upstream status and error category.
  5. Reproduce with a test account that has the minimum required Jira permissions.
  6. Confirm that denied operations do not modify Jira.

Never troubleshoot by placing real tokens or secrets into source files, query strings, screenshots, or documentation.

10. Testing and verification

Use a non-production Jira site and test accounts with controlled permissions. Record test evidence rather than treating checklist completion as implied by source inspection.

Functional tests

  • List accessible projects.
  • Search issues by project.
  • Search issues by status.
  • Retrieve an issue by key.
  • Handle invalid issue keys and inaccessible issues.
  • Handle empty project and issue results.
  • Verify default-project behavior.
  • Verify result limits and pagination behavior.
  • Handle expired tokens, revoked access, rate limits, and provider outages.
  • Verify that errors and logs do not expose secrets or unnecessary issue content.

Authorization tests

  • An unconnected user cannot access Jira through the user-specific OAuth path.
  • One user cannot use another user's token or cached results.
  • Only approved read tools are executable in the initial release.
  • create_issue is rejected before provider invocation.
  • Direct requests to POST /jira/issue are blocked.
  • Alternate or legacy handlers cannot bypass per-user authorization.
  • Denied operations leave Jira unchanged.

OAuth tests

  • Invalid or expired application JWTs fail safely.
  • OAuth state is validated and cannot be reused.
  • Tokens and cloud ID metadata are associated with the correct user.
  • Access-token refresh works and refreshed credentials persist.
  • Revoked and insufficient-scope credentials fail safely.
  • Disconnecting Jira prevents subsequent access.
  • Sensitive credentials are not exposed in URLs or logs.

Release acceptance criteria

The integration should not be marked ready until the following are evidenced:

  1. Approved read operations work with the intended Jira permissions.
  2. OAuth state validation and user-specific token isolation pass testing.
  3. Requested and granted scopes match the approved security policy.
  4. Cache isolation and disconnect behavior are verified.
  5. Every reachable write path is blocked during read-only operation.
  6. Logs and error responses meet the application's data-handling requirements.
  7. Tests are repeatable and their results are recorded for the release.

11. Source references

Use these files when investigating or updating the integration:

File Review focus
chat/package/app/plugins/jira/plugin.py Tool definitions, categories, intent routing, and plugin execution
integrations/package/app/handlers/integration_handlers.py OAuth flow, token resolution, and project/issue routes
integrations/package/app/managers/jira_client.py Jira Cloud REST API v3 calls and authentication modes
integrations/package/app/handlers/jira_handlers.py Alternate handlers and potential authorization bypasses
chat/package/app/plugins/registry.py Tool registration, dispatch, and permission checks
chat/package/app/plugins/permissions.py Default tool-category permissions

12. Readiness decision

Current assessment: not yet verified as production-ready for a strictly read-only release.

The source includes issue creation, requests write:jira-work, and exposes an issue-creation route. These capabilities must be removed, restricted, or otherwise proven unreachable under the approved release policy.

Production approval also depends on verified OAuth security, per-user credential isolation, cache isolation, route protection, and repeatable functional and authorization tests.


Documentation maintenance: Update this page whenever Jira tool definitions, OAuth scopes, authentication modes, API routes, caching behavior, or release permissions change. Keep implementation claims aligned with inspected source and recorded test evidence.