Jira connector¶
Built-in jira connector (Jira Software issues). Floh stays the ticket of record. A Jira issue is created only when a catalog (or other) workflow includes an explicit connector step: type jira, command createWorkItem. There is no automatic create on every Floh ticket, and there is no inbound sync from Jira in this story.
This is not Jira Service Management. Floh is intake; Jira is the engineering work tracker (POST /rest/api/3/issue). A JSM request-type connector would use the reserved jira_sm link value and is out of scope.
Connection fields¶
| Field | Required | Notes |
|---|---|---|
baseUrl |
yes | Jira Cloud origin, e.g. https://{site}.atlassian.net. Optional /rest/api/3 suffix is stripped. No embedded credentials. Private hosts require the flag below. |
email |
yes | Atlassian account email used with the API token. |
apiToken |
yes | Atlassian API token. Encrypted at rest. Sent only as HTTP Basic password. Never logged or returned in API errors. |
projectKey |
yes | Jira project key that receives issues (allowlisted [A-Z][A-Z0-9_]+, 2–32 chars). Must be at least two characters so returned issue keys match the runtime parser. |
issueType |
yes | Issue type name in that project (e.g. Task or Service Request (IT)). Non-empty, max 60 chars; sent as JSON issuetype.name only (parentheses/Unicode allowed). |
allowPrivateNetworkEndpoint |
no | Allow baseUrl to target localhost / RFC1918 / Docker-internal hosts. |
Do not put a webhook secret on this connector. Inbound webhooks are out of scope — Phase 3 v1 is one-way and opt-in.
Commands¶
| Command | Purpose |
|---|---|
test |
Probe the configured project with the API token (GET /rest/api/3/project/{key}). |
createWorkItem |
Create (or adopt by label floh-{ticketUuid} via POST /rest/api/3/search/jql) a Software issue. |
Catalog setup¶
- Create a built-in connector instance of type
jiraand fill origin / email / API token / project / issue type. Use Test to confirm. - On the catalog workflow, keep
create_ticketso a Floh ticket is created. - Add a Connector step after
create_ticket(or rely on the reserved{{ticket.*}}snapshot injected at catalog submit): - Connector: the
jirainstance - Command:
createWorkItem name: e.g.{{title}}description: optionalpriority: optional (criticalmaps to JiraHighest)externalId:{{ticket.id}}ticketNumber:{{ticket.ticketNumber}}
The engine overwrites interpolated externalId / ticketNumber from the reserved {{ticket.*}} snapshot before calling Jira. Missing or non-UUID ticket.id fails the step with no outbound POST.
If a jira row already exists for that Floh ticket, the step completes with the stored issue id / key and does not call Jira again.
On success the step writes ticket_external_link (external_system = jira) including a snapshot browse URL ({origin}/browse/{key}). Admin ticket detail lists every stored link (Plane, Jira, ServiceNow). Email inbound and POST /api/tickets do not create Jira issues.
Local e2e (option A)¶
Use a Jira Cloud free site. There is no Docker Compose peer in this repo.
What this story does not do¶
- Automatic Jira create for every Floh ticket
- Jira Service Management request APIs (
/rest/servicedeskapi/request) - OAuth / Atlassian Connect
- Inbound Jira webhooks / CSRF-exempt routes
- Outbound status or comment sync
- Assignee or attachments
Rollback¶
- Migration
down()restores the previousexternal_systemCHECK (fails if anyjirarows exist). - Remove the Jira connector step from the catalog workflow, or disable the connector instance, to stop new Jira creates. Existing Floh tickets and stored snapshot URLs are unchanged.
Requester¶
The issue creator stays the API-token account. Floh also writes Requested by: {name} <{email}> into the description, next to the Floh ticket number, whenever the reserved snapshot has a name or an email.
When that email matches exactly one Jira user whose emailAddress is visible, Floh sets Reporter after the issue exists (PUT /rest/api/3/issue/{id}). The match is case-insensitive. A name-only search hit is not used — Jira Cloud often redacts email. Zero matches, two matches, any email-redacted row, or a failed lookup leave Reporter unset. A redacted row is logged as redacted even when the same page also contains visible emails that do not match; none means every returned row exposed an email and none matched.
The token needs Browse users and groups and Modify Reporter. A failed lookup or reporter update does not fail the create. Floh does not create or invite a Jira user and does not use a placeholder account.
Already-linked Floh tickets are not updated. A local ticket_external_link returns the stored issue and does not call Jira.
Security¶
- Outbound HTTP uses
connectorHttpRequestonly (auth: basic, no rawfetch()). baseUrlis validated like Vault/S3 (validateConnectorEndpoint): http/https only, no userinfo, private nets require the flag.- Structured logs carry connector id, ticket id, Jira issue id / key, and a requester
reason— never email, display name, summary, description, or the API token.