Uh oh!
There was an error while loading. Please reload this page.
feat(jsm): add Atlassian Assets (Insight/CMDB) tools for asset management - #5072
Conversation
…ment
Add nine JSM Assets tools so workflows can read and write Atlassian Assets
(Insight/CMDB) objects — the foundation for keeping JSM asset tables in sync
for software/hardware asset management.
Tools (wired into the Jira Service Management block):
- jsm_list_object_schemas, jsm_get_object_schema
- jsm_list_object_types, jsm_get_object_type_attributes
- jsm_search_objects_aql (AQL search with pagination)
- jsm_get_object, jsm_create_object, jsm_update_object, jsm_delete_object
Each tool proxies through an internal route that resolves the Jira cloudId and
the Assets workspaceId, then calls the Assets API via the OAuth 2.0 (3LO)
gateway form (/ex/jira/{cloudId}/jsm/assets/workspace/{workspaceId}/v1).
Adds the CMDB OAuth scopes to the jira provider (read/write/delete cmdb-object,
read cmdb-schema/type/attribute) with descriptions, contract schemas for each
route, and block operations/subBlocks/outputs. Bumps the API-validation route
baseline for the nine new routes.The latest updates on your projects. Learn more about Vercel for GitHub. |
PR SummaryMedium Risk Overview Each operation is exposed as a tool and backed by a new authenticated internal route under The Jira Service Management block gains matching operations, conditional asset-specific inputs (including optional AQL/attribute wand helpers), and new outputs. OAuth for the Reviewed by Cursor Bugbot for commit 3933d55. Configure here. |
waleedlatif1
commented
Jun 15, 2026
@greptile review |
waleedlatif1
commented
Jun 15, 2026
@cursor review |
Uh oh!
There was an error while loading. Please reload this page.
Greptile SummaryAdds nine Atlassian Assets (Insight/CMDB) tools to the JSM integration, covering schema discovery, object type inspection, AQL search, and full CRUD on objects. Each tool follows the established JSM proxy pattern: a Zod-validated internal route resolves
Confidence Score: 4/5Safe to merge with one fix: the search tool's The nine new tools follow every established security and architectural pattern: internal-auth gating, Zod request validation, apps/sim/blocks/blocks/jira_service_management.ts — the Important Files Changed
Sequence Diagram%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant Block as JiraServiceManagement Block
participant Route as /api/tools/jsm/assets/* Route
participant Auth as checkInternalAuth
participant Validate as Input Validation
participant Resolver as resolveAssetsContext
participant AtlassianDisc as api.atlassian.com (workspace discovery)
participant AtlassianAssets as api.atlassian.com (Assets API)
Block->>Route: "POST { domain, accessToken, workspaceId?, ...params }"
Route->>Auth: checkInternalAuth(request)
Auth-->>Route: "{ success, userId }"
Route->>Route: parseRequest(contract, body)
Route->>Resolver: resolveAssetsContext(domain, token, cloudId?, workspaceId?)
Resolver->>AtlassianDisc: "GET /ex/jira/{cloudId}/rest/servicedeskapi/assets/workspace"
AtlassianDisc-->>Resolver: "{ values: [{ workspaceId }] }"
Resolver-->>Route: "{ cloudId, workspaceId }"
Route->>Validate: validateJiraCloudId(cloudId)
Route->>Validate: validateAssetsWorkspaceId(workspaceId)
Validate-->>Route: isValid
Route->>AtlassianAssets: "GET/POST/PUT/DELETE /ex/jira/{cloudId}/jsm/assets/workspace/{workspaceId}/v1/..."
AtlassianAssets-->>Route: response data
Route-->>Block: "{ success, output: { ts, ...data } }"
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant Block as JiraServiceManagement Block
participant Route as /api/tools/jsm/assets/* Route
participant Auth as checkInternalAuth
participant Validate as Input Validation
participant Resolver as resolveAssetsContext
participant AtlassianDisc as api.atlassian.com (workspace discovery)
participant AtlassianAssets as api.atlassian.com (Assets API)
Block->>Route: "POST { domain, accessToken, workspaceId?, ...params }"
Route->>Auth: checkInternalAuth(request)
Auth-->>Route: "{ success, userId }"
Route->>Route: parseRequest(contract, body)
Route->>Resolver: resolveAssetsContext(domain, token, cloudId?, workspaceId?)
Resolver->>AtlassianDisc: "GET /ex/jira/{cloudId}/rest/servicedeskapi/assets/workspace"
AtlassianDisc-->>Resolver: "{ values: [{ workspaceId }] }"
Resolver-->>Route: "{ cloudId, workspaceId }"
Route->>Validate: validateJiraCloudId(cloudId)
Route->>Validate: validateAssetsWorkspaceId(workspaceId)
Validate-->>Route: isValid
Route->>AtlassianAssets: "GET/POST/PUT/DELETE /ex/jira/{cloudId}/jsm/assets/workspace/{workspaceId}/v1/..."
AtlassianAssets-->>Route: response data
Route-->>Block: "{ success, output: { ts, ...data } }"
Reviews (5): Last reviewed commit: "refactor(jsm): include Assets responses ..." | Re-trigger Greptile |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
- Add toOptionalInt helper so non-numeric pagination inputs never emit NaN into the Assets query string (startAt/maxResults/page/resultsPerPage) - Replace Record<string, any> in mapAssetObject with typed Raw* interfaces
Greptile SummaryAdds nine Atlassian Assets (Insight/CMDB) tools to the existing JSM block, covering the full CRUD lifecycle for objects plus schema/type/attribute discovery. The implementation follows the established JSM proxy-route pattern — each tool POSTs to an internal Next.js route that resolves
Confidence Score: 3/5Safe to merge once workspaceId path validation is added; all routes are internally authenticated and the scope of any traversal is bounded to api.atlassian.com. The nine new route handlers consistently validate cloudId with validateJiraCloudId, but workspaceId — which is also interpolated into the URL path — receives no equivalent check. An authenticated user could craft a workspaceId with path-traversal segments to reach unintended Atlassian API paths. This needs to be fixed before the routes are live, but the fix is a small addition of a validatePathSegment call. apps/sim/tools/jsm/utils.ts (getAssetsApiBaseUrl uses workspaceId without validation) and all nine route handlers that call resolveAssetsContext without subsequently validating workspaceId.
|
| Filename | Overview |
|---|---|
| apps/sim/tools/jsm/utils.ts | Adds resolveAssetsContext, getAssetsApiBaseUrl, getAssetsWorkspaceId, and mapAssetObject helpers. workspaceId is interpolated into URLs without the same path-segment validation applied to cloudId. |
| apps/sim/app/api/tools/jsm/assets/object/create/route.ts | New POST handler proxying object creation to the Assets API; follows existing JSM route patterns, checks internal auth, and validates cloudId but not workspaceId. |
| apps/sim/app/api/tools/jsm/assets/search/route.ts | AQL search proxy; toNumber coercion and includeAttributes boolean handling look correct. workspaceId validation gap is inherited from utils.ts. |
| apps/sim/blocks/blocks/jira_service_management.ts | Wires nine new Assets operations into the JSM block. The deleted boolean is returned by the tool but not declared in the block's outputs section. |
| apps/sim/lib/api/contracts/selectors/jsm.ts | Adds nine new Zod-validated contracts for the Assets endpoints; schemas are correct and consistent with the existing base schema pattern. |
| apps/sim/lib/oauth/oauth.ts | Adds six CMDB OAuth scopes to the jira provider. Scopes match documented Atlassian Assets 3LO requirements. |
| apps/sim/tools/jsm/types.ts | Adds comprehensive TypeScript types for all new Assets tools; interfaces and ASSET_OBJECT_PROPERTIES constant are well-structured and reused correctly. |
Sequence Diagram
%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant UI as Block / Tool
participant Route as Next.js API Route
participant Auth as checkInternalAuth
participant Util as resolveAssetsContext
participant AtlJira as api.atlassian.com /ex/jira/{cloudId}
participant AtlAssets as Assets API /workspace/{workspaceId}/v1
UI->>Route: "POST /api/tools/jsm/assets/{operation}"
Route->>Auth: checkInternalAuth(request)
Auth-->>Route: "{ success, userId }"
Route->>Util: resolveAssetsContext(domain, accessToken, cloudId?, workspaceId?)
Util->>AtlJira: GET /rest/api/2/serverInfo
AtlJira-->>Util: cloudId
Util->>AtlJira: GET /rest/servicedeskapi/assets/workspace
AtlJira-->>Util: workspaceId
Util-->>Route: "{ cloudId, workspaceId }"
Route->>Route: validateJiraCloudId(cloudId) ok / validateWorkspaceId missing
Route->>AtlAssets: "GET/POST/PUT/DELETE /{resource}"
AtlAssets-->>Route: response
Route-->>UI: "{ success, output }"
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant UI as Block / Tool
participant Route as Next.js API Route
participant Auth as checkInternalAuth
participant Util as resolveAssetsContext
participant AtlJira as api.atlassian.com /ex/jira/{cloudId}
participant AtlAssets as Assets API /workspace/{workspaceId}/v1
UI->>Route: "POST /api/tools/jsm/assets/{operation}"
Route->>Auth: checkInternalAuth(request)
Auth-->>Route: "{ success, userId }"
Route->>Util: resolveAssetsContext(domain, accessToken, cloudId?, workspaceId?)
Util->>AtlJira: GET /rest/api/2/serverInfo
AtlJira-->>Util: cloudId
Util->>AtlJira: GET /rest/servicedeskapi/assets/workspace
AtlJira-->>Util: workspaceId
Util-->>Route: "{ cloudId, workspaceId }"
Route->>Route: validateJiraCloudId(cloudId) ok / validateWorkspaceId missing
Route->>AtlAssets: "GET/POST/PUT/DELETE /{resource}"
AtlAssets-->>Route: response
Route-->>UI: "{ success, output }"
Comments Outside Diff (1)
apps/sim/blocks/blocks/jira_service_management.ts, line 1558-1590 (link)deletedboolean missing from block output declarationsThe
jsm_delete_objecttool returns{ ts, objectId, deleted }(seeJsmDeleteObjectResponse), but the block's outputs section only declaresobjectId. Downstream blocks that referenceoutput.deletedto branch on success vs. no-op will getundefinedrather thantrue. Addingdeleted: { type: 'boolean', description: 'Whether the delete succeeded' }alongsideobjectIdfixes this.
Reviews (2): Last reviewed commit: "refactor(jsm): harden Assets param coerc..." | Re-trigger Greptile
Uh oh!
There was an error while loading. Please reload this page.
Address review findings on the Assets tools: - Add validateAssetsWorkspaceId and guard the workspaceId in every Assets route before it is interpolated into the API path (mirrors the existing cloudId guard) — prevents a crafted workspaceId from escaping the workspace-scoped path - Object schema list now falls back to the `last` flag when `isLast` is absent, so pagination doesn't stop early
waleedlatif1
commented
Jun 15, 2026
@greptile review |
waleedlatif1
commented
Jun 15, 2026
@cursor review |
Uh oh!
There was an error while loading. Please reload this page.
Atlassian provisions one Assets workspace per site, so workspace discovery uses values[0] by design. For the rare multi-workspace site, expose an advanced "Assets Workspace ID" override on the block that flows through to every Assets operation, and document the single-workspace assumption.
d22bee2 to
e7054cdComparewaleedlatif1
commented
Jun 15, 2026
@greptile review |
waleedlatif1
commented
Jun 15, 2026
@cursor review |
Uh oh!
There was an error while loading. Please reload this page.
Append the nine Assets tool response types to JsmResponse for completeness and consistency with the rest of the JSM tool surface.
waleedlatif1
commented
Jun 15, 2026
@greptile review |
waleedlatif1
commented
Jun 15, 2026
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 3933d55. Configure here.
What
Adds nine JSM Assets (Atlassian Assets / Insight / CMDB) tools to the existing Jira Service Management integration, so workflows can read and write Atlassian Assets objects. This is the foundation for keeping JSM asset tables in sync (software/hardware asset management).
Tools
jsm_list_object_schemasGET /objectschema/listjsm_get_object_schemaGET /objectschema/{id}jsm_list_object_typesGET /objectschema/{id}/objecttypesjsm_get_object_type_attributesGET /objecttype/{id}/attributesjsm_search_objects_aqlPOST /object/aql(paginated)jsm_get_objectGET /object/{id}jsm_create_objectPOST /object/createjsm_update_objectPUT /object/{id}jsm_delete_objectDELETE /object/{id}How
cloudIdand the AssetsworkspaceId, then calls the Assets API via the OAuth 2.0 (3LO) gateway form:https://api.atlassian.com/ex/jira/{cloudId}/jsm/assets/workspace/{workspaceId}/v1/...— consistent withgetJsmApiBaseUrl.workspaceIdis discovered viaGET /rest/servicedeskapi/assets/workspace(uses the already-grantedread:servicedesk-requestscope).jira_service_managementblock (dropdown, subBlocks with conditions/required,tools.access,tool()selector,params()mapping, outputs, inputs).OAuth scopes added (
jiraprovider)read:cmdb-object:jira,write:cmdb-object:jira,delete:cmdb-object:jira,read:cmdb-schema:jira,read:cmdb-type:jira,read:cmdb-attribute:jira— each with a description inSCOPE_DESCRIPTIONS.Validation
tscclean,biomeclean,check:api-validationpasses (route baseline bumped 828→837).Notes
POST /object/aqlcarries no OAuth exclusion (unlike the removedGET /aql/objects), but a real-token check is wise.Pre-merge verification gates (do not skip)
Static validation is complete (tsc/biome/api-validation green; spec parity + internal semantics verified by multiple passes; 4 clean review rounds). The following require a live JSM+Assets instance and are not certifiable from code:
read:cmdb-object:jira(and write/delete for mutations). The 6 scope strings are verified correct and documented as OAuth 2.0 (3LO)-grantable, but enabling them on the registered app + user re-consent is an operational step.jsm_search_objects_aqlagainst a real workspace and confirmPOST /object/aqlreturns results over 3LO (the deprecatedGET /aql/objectswas OAuth-blocked; the replacement is documented as accessible, but worth one live call)./ex/jira/{cloudId}/jsm/assets/...gateway host.