2026-04-28 16:36:54 +00:00
# Jira REST API Use Cases — STEAM Security Dashboard
## Overview
The STEAM Security Dashboard is a self-hosted vulnerability management tool used by the NTS-AEO-STEAM and NTS-AEO-ACCESS-ENG teams. It integrates with Jira Data Center to create, track, and sync vulnerability remediation tickets linked to CVE records.
All API calls are made from a single Node.js backend process. The integration uses Basic Auth with a service account and enforces Charter's posted rate limits client-side.
---
## Charter Compliance Summary
| Requirement | Implementation |
|---|---|
| Authentication | Basic Auth with service account (`JIRA_API_USER` + `JIRA_API_TOKEN` ) |
| Rate limit — daily | Client-side enforced: 1 440 requests/day max |
| Rate limit — burst | Client-side enforced: 60 requests/minute max |
| Inter-request delay — GETs | 1 second minimum between GET requests |
| Inter-request delay — writes | 2 seconds minimum between PUT/POST/DELETE requests |
| Explicit field lists | Every GET includes `?fields=` parameter; `/rest/api/2/field` is blocked |
| No bulk updates | Issues are updated one at a time; `/rest/api/2/issue/bulk` is blocked |
2026-05-05 11:04:53 -06:00
| Bulk reads via JQL | Multi-ticket sync uses a single `GET /rest/api/2/search` with predefined key-based JQL query parameters, not per-issue GETs; no arbitrary JQL passthrough |
2026-04-29 14:12:04 +00:00
| Single-issue fetch via JQL | `GET /rest/api/2/search?jql=key="KEY" AND project=<KEY>&fields=...&maxResults=1` |
2026-05-05 11:04:53 -06:00
| JQL scoping | All recurring JQL queries use predefined scoped patterns with `updated >= -72h` clause and `project = <KEY>` scoping; no arbitrary JQL passthrough |
2026-04-28 16:36:54 +00:00
| `maxResults` cap | Search queries capped at 1 000 results per page |
---
## Use Cases
### 1. Connection Test
| | |
|---|---|
| **Endpoint ** | `GET /rest/api/2/myself` |
| **Trigger ** | Admin clicks "Test Connection" on the Jira settings panel |
| **Frequency ** | Manual, infrequent (a few times per day at most) |
| **Purpose ** | Verify service account credentials and connectivity |
| **Fields requested ** | Default (myself endpoint returns user profile) |
### 2. Create Issue
| | |
|---|---|
| **Endpoint ** | `POST /rest/api/2/issue` |
| **Trigger ** | User clicks "Create in Jira" from a CVE detail panel |
| **Frequency ** | Manual, estimated 5– 20 per day |
| **Purpose ** | Create a vulnerability remediation ticket linked to a CVE/vendor pair |
| **Fields sent ** | `project.key` , `summary` , `issuetype.name` , `description` |
| **Notes ** | A local record is also created in the dashboard database linking the Jira key to the CVE |
### 3. Get Single Issue
| | |
|---|---|
2026-04-29 14:12:04 +00:00
| **Endpoint ** | `GET /rest/api/2/search?jql=key="ISSUE-KEY" AND project=<KEY>&fields=summary,status,assignee,created,updated,priority,issuetype,project,resolution&maxResults=1` |
2026-04-28 16:36:54 +00:00
| **Trigger ** | User clicks "Sync" on a single Jira ticket row |
| **Frequency ** | Manual, estimated 10– 30 per day |
2026-04-29 14:12:04 +00:00
| **Purpose ** | Refresh a single ticket's status and summary from Jira via JQL search |
| **Notes ** | Uses JQL-based lookup instead of single-issue GET per Charter compliance. Fields are always specified explicitly. |
2026-04-28 16:36:54 +00:00
### 4. Update Issue
| | |
|---|---|
| **Endpoint ** | `PUT /rest/api/2/issue/{issueKey}` |
| **Trigger ** | Future feature — local edits synced back to Jira |
| **Frequency ** | Manual, estimated 5– 10 per day when enabled |
| **Purpose ** | Update issue summary or other fields from the dashboard |
| **Notes ** | Issues are updated one at a time; bulk PUT is not used |
### 5. Add Comment
| | |
|---|---|
| **Endpoint ** | `POST /rest/api/2/issue/{issueKey}/comment` |
| **Trigger ** | Dashboard adds audit trail comments to linked tickets |
| **Frequency ** | Automated on certain actions, estimated 5– 15 per day |
| **Purpose ** | Maintain an audit trail on the Jira ticket for compliance visibility |
### 6. Get Transitions
| | |
|---|---|
| **Endpoint ** | `GET /rest/api/2/issue/{issueKey}/transitions` |
| **Trigger ** | Dashboard checks available workflow transitions before moving a ticket |
| **Frequency ** | Manual, paired with transition calls, estimated 5– 10 per day |
| **Purpose ** | Discover valid status transitions for the issue's current workflow state |
### 7. Transition Issue
| | |
|---|---|
| **Endpoint ** | `POST /rest/api/2/issue/{issueKey}/transitions` |
| **Trigger ** | User moves a ticket to a new status from the dashboard |
| **Frequency ** | Manual, estimated 5– 10 per day |
| **Purpose ** | Move ticket through workflow states (e.g., Open to In Progress to Closed) |
2026-05-05 11:04:53 -06:00
### 8. Scoped Bulk Sync via JQL
2026-04-28 16:36:54 +00:00
| | |
|---|---|
2026-04-29 14:12:04 +00:00
| **Endpoint ** | `GET /rest/api/2/search?jql=...&fields=...&maxResults=...&startAt=...` |
2026-04-28 16:36:54 +00:00
| **Trigger ** | Admin clicks "Sync All" on the Jira tickets panel |
| **Frequency ** | Manual, estimated 1– 3 times per day |
| **Purpose ** | Bulk-refresh all tracked tickets in a single request instead of per-issue GETs |
2026-05-05 11:04:53 -06:00
| **JQL pattern ** | `key in ("KEY-1", "KEY-2", ...) AND updated >= -72h AND project = <KEY>` |
2026-04-28 16:36:54 +00:00
| **Fields requested ** | `summary, status, assignee, created, updated, priority, issuetype, project, resolution` |
| **Batch size ** | 100 keys per JQL query; multiple batches if needed |
2026-05-05 11:04:53 -06:00
| **Notes ** | Uses GET with URL-encoded query parameters per Charter compliance. JQL is predefined and scoped — constructed from known tracked issue keys, a fixed 72-hour window, and the configured project key. No arbitrary JQL is accepted from the frontend. Stops early if rate limit budget is running low (burst remaining <= 5 or daily remaining <= 10) |
2026-04-28 16:36:54 +00:00
### 9. Issue Lookup
| | |
|---|---|
2026-04-29 14:12:04 +00:00
| **Endpoint ** | `GET /rest/api/2/search?jql=key="ISSUE-KEY" AND project=<KEY>&fields=...&maxResults=1` |
2026-04-28 16:36:54 +00:00
| **Trigger ** | User looks up a Jira issue by key from the dashboard search |
| **Frequency ** | Manual, estimated 5– 15 per day |
2026-04-29 14:12:04 +00:00
| **Purpose ** | Quick lookup of any Jira issue to view its current state via JQL search |
2026-04-28 16:36:54 +00:00
---
## Estimated Daily API Usage
| Operation | Estimated calls/day | Method | Delay enforced |
|---|---|---|---|
| Connection test | 2– 5 | GET | 1s |
| Create issue | 5– 20 | POST | 2s |
| Get single issue | 10– 30 | GET | 1s |
| Update issue | 5– 10 | PUT | 2s |
| Add comment | 5– 15 | POST | 2s |
| Get transitions | 5– 10 | GET | 1s |
| Transition issue | 5– 10 | POST | 2s |
2026-05-05 11:04:53 -06:00
| Scoped bulk sync | 1– 5 | GET | 1s |
2026-04-28 16:36:54 +00:00
| Issue lookup | 5– 15 | GET | 1s |
| **Total estimated ** | **43– 120 ** | | |
Well within the 1 440/day limit. Burst usage stays under 60/minute due to enforced inter-request delays.
---
## Blocked Endpoints
The integration explicitly blocks these endpoints to comply with Charter policy:
- `/rest/api/2/field` — field metadata is never queried; fields are specified in code
- `/rest/api/2/issue/bulk` — bulk updates are not used; issues are updated individually
2026-05-05 11:04:53 -06:00
- `POST /rest/api/2/search` — arbitrary JQL search via POST is not used; all searches use `GET /rest/api/2/search` with URL-encoded query parameters and predefined scoped JQL patterns
2026-04-28 16:36:54 +00:00
---
## Error Handling
- **429 responses**: Surfaced to the user as "Rate limit exceeded. Try again later." No automatic retry.
- **5xx responses**: Surfaced as "Jira API error" with the response body for debugging.
- **Network failures**: Caught and surfaced with the error message.
- **Timeout**: 15 second timeout per request; surfaced as a timeout error.
---
## UAT Test Evidence
The UAT test script (`backend/scripts/jira-uat-test.js` ) exercises all use cases listed above and produces a log file at `backend/scripts/jira-uat-test.log` . This log can be attached to or referenced in the ATLSUP approval ticket.
To run:
```bash
cd backend
node scripts/jira-uat-test.js
```