JSM integration — requests, evidence and the audited write door
integrations:jira-service-management
Jira Service Management holds the ticket; OpsChain executes and governs
the change — and proves it. The JSM integration
(integrations:jira-service-management) binds the two: tickets become
typed references on governed changes, ticket events become triggers,
every OpsChain-side JSM write goes through one audited door, and a
request resolved via OpsChain closes with the evidence links attached.
The full reference is opschain docs integrations-jsm.
1. Register the connection
An Atlassian cloud site authenticates as an account (email + API
token); Jira Data Center uses a personal access token as a bearer
(omit --auth-email). The token never rides the command line and no
read ever returns it:
JSM_TOKEN=... opschain admin jsm-connections create limepoint-jsm \
--base-url https://yoursite.atlassian.net \
--auth-email support-bot@example.com \
--project-keys SUP \
--api-token-env JSM_TOKEN
opschain admin jsm-connections test limepoint-jsm
--project-keys scopes the connection: a write to a request outside
those projects refuses by name. test validates the record without
calling JSM.
In the GUI: Administration → Operate → JSM (/admin/jsm) is
the same registry — create, edit, test, enable and delete connections,
with the API token / PAT write-only (type it once and the server holds
it encrypted at rest, or pin an existing secret-vault:// reference),
and Provision…
sets up Jira webhook ingestion, showing the generated signing secret
exactly once. On a change's page the Service desk tab lists the
requests bound to that change and carries the write verbs — comment,
transition, set fields and resolve with evidence — each refusing as the
server states it. Reference: opschain docs gui-operations.
2. Events in — tickets as triggers
Provision webhook ingestion on the signed inbound lane and point the Jira webhook (issue created/updated, comment created) at it:
opschain admin jsm-connections provision-webhook limepoint-jsm --service-account jsm-bot
Deliveries POST to /api/hooks/jsm-limepoint-jsm. Jira Data Center
signs natively — configure the shown secret as the webhook secret and
Jira sends a sha256 X-Hub-Signature. Each accepted delivery lands one
external:webhook:received event with typed fields under
event.data.jira, so a trigger can react to, say, every new support
request:
subject: external
events: [external:webhook:received]
conditions:
- event.data.jira.event eq jira:issue_created
- event.data.jira.project eq SUP
Every firing executes as the connection's service account — never with ambient authority.
3. Bind changes to tickets
A governed change carries the ticket as a typed reference on its governance metadata block:
opschain approvals set-metadata <run-id> --ref jsm:request:SUP-123
opschain admin jsm-requests links --request SUP-123
links answers the other direction — which OpsChain subjects carry
this ticket — filtered to the subjects you may read. Approval policies
with require_change_reference count these references, so "no change
without a ticket" works for Atlassian shops out of the box.
4. Write back through the audited door
All OpsChain-side JSM writes go through one entitlement-gated, project-scoped, evented door:
opschain admin jsm-requests comment SUP-123 --body "Change scheduled for tonight's window."
opschain admin jsm-requests transition SUP-123 "In Progress"
opschain admin jsm-requests set-fields SUP-123 --add-label opschain
Comments are always JSM internal notes — there is deliberately no customer-visible-comment capability on this surface, so drafted customer replies stay internal until a human posts them as themselves.
5. Resolve with evidence
When the change lands, close the ticket with the proof attached:
opschain admin jsm-requests resolve SUP-123 \
--run <run-id> --transition Resolve \
--evidence-url https://opschain.example/changes/<run-id>
One audited write records the jsm:request reference (relationship
resolves) on the change's governance block, posts the internal
evidence comment, and performs the resolving transition. The OpsChain
ledger stays the source of truth; JSM holds a copy with provenance.
Where to look when something refuses
Everything refuses by name: the missing entitlement, the project scope,
a disabled connection, an unknown transition (listing what is
available), an unresolvable credential. Every write and every refusal
that matters is on the event stream — opschain events list --type 'info:jsm:*' tells the story.