JSM integration (integrations:jira-service-management)
integrations:jira-service-management
The Jira Service Management integration binds OpsChain's governed changes to the JSM requests they serve: requests and issues become typed references on governance metadata, request lifecycle writes flow through one audited door, inbound JSM webhooks ride the signed inbound lane as trigger sources, and a request resolved via OpsChain closes with the evidence links attached — the OpsChain ledger stays the source of truth, and what JSM receives is a copy with provenance.
The pieces
- JSM connection (
opschain admin jsm-connections): the per-site registration — an Atlassian cloud site or a Jira Data Center base URL, optionally scoped to named project keys (a write to a request outside them refuses by name). Authentication is cloud-style basic (account email + API token) or a Data Center personal access token sent as a bearer. The credential is held reference-first (api_token_ref, asecret-vault://address; the record never stores the token).testvalidates the record without calling JSM. - Typed references (
jsm/jirasystems,request/issuerecord types) on the governance metadata block every funnel subject carries — recorded withopschain approvals set-metadata, at run creation withopschain runs create … --ref, or by the resolution verb.opschain admin jsm-requests linksreads them back joined to their subjects, serving only subjects the caller may read. Therequire_change_referencepolicy lever counts them for Atlassian shops exactly as for any ITSM. - The outbound write door (
opschain admin jsm-requests): internal comments, workflow transitions, label/field writes and the evidence-linked resolution — every write entitlement-gated, project-scope checked, and recorded as aninfo:jsm:*event. The comment capability is internal notes only: the wire call hardwires the JSM internal flag and no verb on the surface carries a visibility parameter, so a customer-visible comment cannot be expressed through OpsChain — drafted replies stay internal until a human posts them as themselves. - Webhook ingestion (
opschain admin jsm-connections provision-webhook): one signed inbound-webhook connection on the generic inbound lane — Jira deliveries POST to/api/hooks/jsm-<code>, dedup on the verified signature, and execute (when a trigger matches) as the named service account. Request created/updated/commented events expose a normalised typed field set underevent.data.jira(key, project, status, summary, priority, labels, comment id and the internal-note flag) for trigger conditions; the raw payload stays underevent.data.payload. Jira Data Center signs natively (a webhook secret emitsX-Hub-Signature, sha256 HMAC — the lane honours only the sha256 shape, never sha1); an unsigned source must be fronted by a signer adding the genericX-OpsChain-Signature+ timestamp shape. - Evidence-linked resolution (
opschain admin jsm-requests resolve): one audited write that records thejsm:requesttyped reference (relationshipresolves) on the resolving change or workflow run's governance block, posts one internal evidence comment (provenance + evidence links), and performs the resolving transition.
Authority stays home
Visibility flows out; approval authority is never delegated. A JSM approval never satisfies an OpsChain quorum, and nothing on this surface consumes JSM state as an approval condition. The write door is the only JSM write path OpsChain offers, so any OpsChain-side agent or automation that touches JSM funnels through the same audited, capability-gated verbs.
Audit trail
Connection writes are audited as api:jsm_connections:* (the
api_token_ref pointer, never a value, and never the account email —
an auth_mode marker carries the shape). Every outbound write lands
one event: info:jsm:internal_comment (comment id and length — never
the note's content), info:jsm:transition, info:jsm:fields (field
names, never values) and info:jsm:resolution (the subject, the
request, the transition, the evidence links and the recorded
reference). Webhook provisioning lands
api:jsm_connections:provision_webhook. No event, response or error
ever carries token or signing-secret material.
Authorisation — per-verb rule paths
Every JSM procedure except the links read authorises as an updatable
determination on its own rule path under /admin:
| Rule path | Covers |
|---|---|
/admin/integrations/jsm/connections | connection CRUD, test, provision-webhook, connection reads |
/admin/integrations/jsm/requests/comment | the internal-note write |
/admin/integrations/jsm/requests/transition | request transitions |
/admin/integrations/jsm/requests/fields | label/field writes |
/admin/integrations/jsm/requests/resolve | the evidence-linked resolution |
Rule paths match as segment-boundary prefixes, so a plain /admin
updatable rule (the admin plane) covers the whole surface unchanged —
nothing changes for existing administrators. The deepened paths exist so
a principal can be granted exactly one verb: a support agent's
service account granted only the comment path can post internal notes
and nothing else, and a principal never granted the resolve path can
never resolve a ticket — "never resolves" as a grant shape, not agent
behaviour. The links read (admin jsm-requests links) stays per-row
node-path read pushdown with no admin gate.
Usage telemetry
Every request the integration makes is counted on the connection's
usage row (opschain docs provider-usage): api_calls with its latency
and api_errors (an unreachable site or a non-2xx answer), and on the
connection's provisioned inbound webhook webhooks_received and
signature_failures. opschain admin providers usage --kind jsm --code <code> reads them; the connection's record opens its operational
dashboard.
Entitlement
The server-side capability is gated on
integrations:jira-service-management (Enterprise-weighted; never
in the Basic-tier defaults). Expiry degrades politely, never
destructively: new registrations, enabling writes and every outbound
request write refuse with a named licence message, stored configuration
is retained untouched, deletion stays open, and everything lights back
up on upgrade.
Wiring it up
- Register the connection (
opschain admin jsm-connections create) with the site URL, auth and project scope;testit. - Provision webhook ingestion and configure the Jira webhook (issue
created/updated + comment created) with the signing secret shown at
provisioning; point a trigger at
external:webhook:receivedwithevent.data.jira.*conditions. - Bind changes to requests:
opschain approvals set-metadata <run> --ref jsm:request:SUP-123(orruns create … --ref). - Work the ticket through the door:
comment,transition,set-fields— and close it withresolve, evidence attached.
See also
opschain docs cli/admin-jsm-connections— the connection verbs.opschain docs cli/admin-jsm-requests— the write door and the links read.opschain docs change-governance— the governance metadata block.opschain docs entitlements— the feature vocabulary.opschain docs triggers— inbound events as automation.