Skip to main content

Jira

Visualize Jira projects, users, and issues, map Jira users to employees, and monitor changes through queries and alerts.

The same integration can also ingest your Jira Service Management Assets (CMDB) objects, such as laptops, servers and applications, and link each asset to the Jira user who owns it. If you already use this integration for Jira projects and issues, you do not need a separate integration: upload an Assets mapping file to your existing instance. See Assets (CMDB) Configuration.

Installation​

To use this integration, JupiterOne requires the hostname for your Jira organization, credentials for API access, and optionally an Assets mapping configuration for CMDB ingestion.

note

The integration supports Jira Cloud with Jira API v3 and Jira Data Center with Jira API v2. Other setups may work.

Configure a Jira User​

Create or designate a Jira user for the JupiterOne integration:

Option 1: Create a New Service Account (Recommended)

  1. Log in to Jira as an administrator
  2. Navigate to User Management
  3. Create a new user (e.g., jupiterone-integration@yourcompany.com)
  4. Grant the necessary permissions (see User Permissions below)

Option 2: Use an Existing User

Verify the user has the required permissions and that you can log in to generate an API token.

User Permissions​

The Jira user needs the following permissions:

  1. Browse Users - Grant the "Browse Users" global permission to read groups and users
  2. Project Access - Authorize browse access to projects using Jira permission features
  3. Create Issues (optional) - Required only if using JupiterOne Alert Rules to create Jira issues
  4. Assets Access (optional) - Required for CMDB ingestion. The user must have access to Jira Service Management Assets.
tip

For read-only access, see How to Create a Read Only User.

Authentication Methods​

The integration supports two authentication methods. Choose the one that fits your organization:

  • API Token (Basic) — a user email plus an API token (or password). The simplest option.
  • OAuth 2.0 (Service account) — an OAuth 2.0 service account credential (Client ID + Client Secret). Recommended when your organization is restricting or disabling API tokens.

Create an API Token​

Follow these steps for the API Token (Basic) method.

  1. Log in to Jira as the JupiterOne integration user
  2. Go to Atlassian Account Settings > API Tokens
  3. Click Create API token
  4. Give it a descriptive label (e.g., "JupiterOne Integration")
  5. Copy and save the token value
warning

The token is only shown once. Store it securely.

Create OAuth 2.0 Credentials (Service Account)​

Follow these steps for the OAuth 2.0 (Service account) method. The integration uses the OAuth 2.0 client_credentials grant, so no interactive browser authorization is required.

  1. Log in to Atlassian administration as an organization admin
  2. Go to Service accounts and create or select a service account
  3. Create an OAuth 2.0 credential for the service account
  4. Grant the credential the following Jira scopes:
    • read:jira-user
    • read:jira-work
    • For Assets (CMDB) ingestion, also grant: read:cmdb-object:jira, read:cmdb-attribute:jira, read:cmdb-schema:jira, read:cmdb-type:jira
  5. Ensure the service account has access to the site and projects you intend to ingest
  6. Copy and save the Client ID and Client Secret
warning

The Client Secret is only shown once. Store it securely.

note

OAuth access tokens are valid for 60 minutes. The integration requests and refreshes them automatically. For details, see Atlassian's Create an OAuth 2.0 credential for service accounts.

Assets (CMDB) Requirements​

To ingest Jira Assets (CMDB), the integration credentials must have:

  • Access to Jira Service Management
  • Permission to view Assets in your Jira organization

For API Token (Basic), the token must belong to a user with these permissions. For OAuth 2.0 (Service account), the credential must be granted the read:cmdb-*:jira scopes listed above and the service account must have Assets access.

Configuration in JupiterOne​

Navigate to Integrations > Jira > New Instance, select your authentication method, and provide the common fields:

FieldDescription
Account NameIdentifier for this Jira account in JupiterOne
DescriptionOptional description
Polling IntervalHow often to sync data
HostnameYour Jira hostname (e.g., yourcompany.atlassian.net)
Project KeysComma-separated list of project keys to ingest. Keys must match existing projects the integration user can see; see Invalid project keys
User Account Types to IngestOptional. Which Atlassian account types to ingest as jira_user entities (see below). All types are selected by default
Assets MappingJSON file for CMDB ingestion (see below)

For the API Token (Basic) method, also provide:

FieldDescription
User EmailEmail of the Jira integration user
API TokenThe API token created above

For the OAuth 2.0 (Service account) method, also provide:

FieldDescription
Client IDThe Client ID of the OAuth 2.0 service account credential
Client SecretThe Client Secret of the OAuth 2.0 service account credential

Filtering Users by Account Type​

Every Jira user has an Atlassian account type:

Account typeWho it covers
AtlassianLicensed users of your Jira site
AppBots and integrations
CustomerJira Service Management portal accounts, created for anyone who raises a request through a service desk portal
UnknownAccounts Jira does not classify

On a busy service desk, Customer accounts can outnumber licensed users many times over. Deselect Customer under User Account Types to Ingest to skip them and keep them from counting against your entity limit.

Jira's API cannot filter users by account type, so the integration still reads every user and discards the deselected types before ingesting them. This lowers the number of jira_user entities but does not shorten the time the job takes. Users of a deselected type that were ingested earlier are removed from JupiterOne after the next successful run.

note

Skipping an account type also skips the jira_user CREATED, REPORTED and ASSIGNED jira_issue relationships for those users. For example, deselecting Customer means issues raised through a service desk portal have no reporter relationship.

Assets (CMDB) Configuration​

To ingest assets from Jira Service Management Assets, upload a JSON mapping configuration that defines which object types to ingest and how to map their attributes to JupiterOne entities.

Mapping Structure​

{
"version": "1.0",
"description": "My organization's asset mappings",
"objectTypes": [
{
"objectTypeId": "15",
"objectTypeName": "Laptop",
"_class": "Device",
"enabled": true,
"propertyToAttributeMap": {
"hostname": { "attributeId": "135", "attributeName": "Hostname" },
"serial": { "attributeId": "136", "attributeName": "Serial Number" },
"category": { "attributeId": null, "default": "laptop" }
}
}
]
}

Object Type Configuration​

PropertyTypeRequiredDescription
objectTypeNamestringYesJira Object Type name (generates entity _type automatically)
objectTypeIdstringNoJira Object Type ID (more stable for queries)
_classstring or string[]YesJupiterOne entity class
enabledbooleanYesWhether to ingest this object type
filterstringNoAdditional AQL filter (e.g., Status = Active)
propertyToAttributeMapobjectYesMaps J1 properties to Jira attributes
ownerEmailPropertystringNoDeprecated — use ownerProperties. Name of a property in propertyToAttributeMap containing the owner's email. Builds a generic jira_user OWNS mapped relationship.
ownerPropertiesarrayNoOwner sources, each with a role (business, technical, or generic) that builds a typed jira_user OWNS mapped relationship.
referenceRelationshipsarrayNoDirect relationships to other Jira Assets objects this object references through an Object reference attribute (e.g. Function, Process, Information Category, ICT Supplier).
targetRelationshipsarrayNoRelationships built from attribute values to any entity in the JupiterOne graph — not only to other Assets objects. Use this for text attributes, multi-value attributes, delimited lists, and JSON blobs.

Attribute Mapping​

PropertyTypeRequiredDescription
attributeIdstring or nullYesJira attribute ID. Use null for default-only values
attributeNamestringNoHuman-readable name (documentation only)
typestringNoType conversion: string, number, boolean, date, array
defaultstring, number, boolean, or string[]NoDefault value when attribute is missing
transformstringNoTransform: lowercase, uppercase, trim, slug
patternstringNoRegex pattern to extract value
caution

Do not use "type": "json" on a property. It parses the attribute into a nested object, which the platform rejects when the entity is uploaded, and the object type fails to ingest. To read values out of a JSON blob attribute, use a value-based relationship with extract.format: "json", or map the individual fields you need as separate properties with pattern.

Complete Example: Devices and Servers​

This example maps laptops and servers from Jira Assets:

{
"version": "1.0",
"description": "IT Asset inventory mapping",
"objectTypes": [
{
"objectTypeId": "15",
"objectTypeName": "Laptop",
"_class": "Device",
"enabled": true,
"propertyToAttributeMap": {
"hostname": { "attributeId": "135", "attributeName": "Hostname" },
"serial": { "attributeId": "136", "attributeName": "Serial Number" },
"make": { "attributeId": "137", "attributeName": "Manufacturer" },
"model": { "attributeId": "138", "attributeName": "Model" },
"macAddress": { "attributeId": "139", "attributeName": "MAC Address" },
"osName": { "attributeId": "141", "attributeName": "Operating System" },
"osVersion": { "attributeId": "142", "attributeName": "OS Version" },
"deviceId": { "attributeId": "144", "attributeName": "Asset Tag" },
"category": { "attributeId": null, "default": "laptop" }
}
},
{
"objectTypeId": "17",
"objectTypeName": "Server",
"_class": "Host",
"enabled": true,
"filter": "Status != Decommissioned",
"propertyToAttributeMap": {
"hostname": { "attributeId": "201", "attributeName": "Hostname" },
"fqdn": { "attributeId": "202", "attributeName": "FQDN" },
"serial": { "attributeId": "203", "attributeName": "Serial Number" },
"make": { "attributeId": "204", "attributeName": "Manufacturer" },
"model": { "attributeId": "205", "attributeName": "Model" },
"ipAddress": { "attributeId": "207", "attributeName": "IP Address" },
"osName": { "attributeId": "210", "attributeName": "Operating System" },
"osVersion": { "attributeId": "211", "attributeName": "OS Version" },
"category": { "attributeId": null, "default": "server" }
}
}
]
}

Additional Examples​

Load Balancer (Gateway class with array defaults):

{
"objectTypeName": "Load Balancer",
"_class": "Gateway",
"enabled": true,
"propertyToAttributeMap": {
"category": { "attributeId": null, "default": ["network"] },
"function": { "attributeId": null, "default": ["load-balancing"] },
"public": { "attributeId": "301", "attributeName": "Public Facing", "type": "boolean" }
}
}

Cloud Account (Account class with strictly required vendor):

{
"objectTypeName": "AWS Account",
"_class": "Account",
"enabled": true,
"propertyToAttributeMap": {
"vendor": { "attributeId": null, "default": "Amazon Web Services" },
"accountId": { "attributeId": "501", "attributeName": "Account ID" }
}
}

Physical Firewall (combined classes):

{
"objectTypeName": "Firewall",
"_class": ["Device", "Firewall"],
"enabled": true,
"propertyToAttributeMap": {
"category": { "attributeId": null, "default": ["network"] },
"hostname": { "attributeId": "601", "attributeName": "Hostname" },
"serial": { "attributeId": "602", "attributeName": "Serial Number" },
"make": { "attributeId": "603", "attributeName": "Vendor" }
}
}

Asset Ownership Relationships​

Ownership relationships answer "who owns this asset?". For each asset, the integration reads the owner attribute you point it at (an email address, a Jira user, or a display name) and links the matching Jira user to the asset, so a query like FIND jira_user THAT OWNS jira_assets_laptop returns each laptop with its owner.

You can build these jira_user OWNS jira_assets_* relationships by specifying which mapped property contains the asset owner's email. Add ownerEmailProperty to an object type, pointing to the property name in propertyToAttributeMap:

{
"objectTypeId": "15",
"objectTypeName": "Laptop",
"_class": "Device",
"enabled": true,
"ownerEmailProperty": "ownerEmail",
"propertyToAttributeMap": {
"hostname": { "attributeId": "135", "attributeName": "Hostname" },
"serial": { "attributeId": "136", "attributeName": "Serial Number" },
"ownerEmail": { "attributeId": "157", "attributeName": "Owner" },
"category": { "attributeId": null, "default": "laptop" }
}
}

The integration matches the email value against existing jira_user entities. For Jira User-type attributes (where the value is a reference to a Jira user), the integration automatically extracts the email address.

note

This ingestion source is disabled by default. Enable the user-owns-asset ingestion source in the integration configuration. The jira_user entity must already exist — no placeholder is created.

Multiple Owners (Business Owner / Technical Owner)​

When an object type has more than one owner role — for example a "System" with both a Business Owner and a Technical Owner — use ownerProperties instead of the singular ownerEmailProperty:

{
"objectTypeId": "5",
"objectTypeName": "Systems",
"_class": "Application",
"enabled": true,
"ownerProperties": [
{ "property": "businessOwner", "role": "business" },
{ "property": "technicalOwner", "role": "technical" }
],
"propertyToAttributeMap": {
"businessOwner": { "attributeId": "301", "attributeName": "Business Owner" },
"technicalOwner": { "attributeId": "302", "attributeName": "Technical Owner" }
}
}
roleRelationship _type
businessjira_user_business_owns_asset
technicaljira_user_technical_owns_asset
generic (default)jira_user_owns_asset

ownerProperties and ownerEmailProperty can be combined — the singular field is treated as an additional generic owner.

Owner Property Fields​

PropertyTypeRequiredDescription
propertystringYes*Key of propertyToAttributeMap holding the owner value. Mutually exclusive with attributeId.
attributeIdstringYes*Jira attribute ID to read the owner from directly, bypassing propertyToAttributeMap. Recommended for User-type attributes. Mutually exclusive with property.
rolestringNobusiness, technical, or generic (default)
valueFieldstringNoWhich part of a raw attribute value to use: userEmail, userDisplayName, userName, displayValue, value. Defaults to auto. Only meaningful with attributeId.
matchPropertystringNoThe jira_user property to match against: email (default), name, or displayName

* Exactly one of property or attributeId is required.

Matching Owners by Display Name​

If your owner fields hold display names rather than email addresses, match on jira_user.name instead. Read the attribute directly so the display name is used even when Atlassian hides the user's email address:

"ownerProperties": [
{
"attributeId": "301",
"role": "business",
"valueField": "userDisplayName",
"matchProperty": "name"
}
]

jira_user.name is user.name || user.displayName, so on Jira Cloud it is the display name. Values matched against email are lowercased automatically; values matched against name or displayName are not, because those properties preserve the casing of the source system.

note

Relationship keys include the ownership role and the matched value, so the same person appearing in two owner fields on one asset is supported. If you previously reduced an object type to a single owner to avoid a duplicate-key error, you can configure all the roles you need again.

Asset Reference Relationships​

Jira Assets objects often reference other objects — for example a System that references its Function, Process, Information Category, and ICT Supplier. Configure referenceRelationships to turn these references into direct relationships between the asset entities:

{
"objectTypeId": "5",
"objectTypeName": "Systems",
"_class": "Application",
"enabled": true,
"referenceRelationships": [
{ "attributeId": "310", "attributeName": "Function", "targetObjectType": "Function", "_class": "USES" },
{ "attributeId": "311", "attributeName": "Process", "targetObjectType": "Process", "_class": "USES" },
{ "attributeId": "312", "attributeName": "Information Category", "targetObjectType": "Information Category", "_class": "HAS" },
{ "attributeId": "313", "attributeName": "ICT Supplier", "targetObjectType": "Supplier", "_class": "HAS" }
],
"propertyToAttributeMap": { }
}
PropertyTypeRequiredDescription
attributeIdstringYesJira attribute ID holding the reference to the target object
attributeNamestringNoHuman-readable name (documentation only)
targetObjectTypestringYesJira Assets Object Type Name of the referenced object (e.g. "Supplier")
_classstringYesJupiterOne relationship class (e.g. HAS, USES, ASSIGNED)
caution

referenceRelationships only works with Jira Object reference attributes — attributes whose value is a link to another Assets object. Pointed at a text attribute it produces no relationships at all.

This is a common surprise when your CMDB is synced from another system: tools such as Device42 or ServiceNow typically write foreign keys and object names into plain text attributes (device_fk, Device Name, App), which look like references but are not. To build relationships from those, use value-based relationships instead, which match on the attribute's value.

To check an attribute's type, open the Object Type in Jira, click Attributes, and look at the attribute's Type column — it must read Object, not Text.

note

The referenced object type (e.g. Supplier) must also be configured and enabled in objectTypes — otherwise the target entity doesn't exist and the relationship is skipped. If a reference attribute holds multiple values (e.g. multiple suppliers), a relationship is created for each referenced object.

Value-Based Relationships​

referenceRelationships links Assets objects to other Assets objects, and only through Object reference attributes. targetRelationships is more general: it reads an attribute's value and builds a relationship to any entity in the JupiterOne graph — a GitHub repository, a host from your EDR, a cloud account — by matching that value against a property of the target.

This is what you want when an attribute holds a name, an identifier, a comma-separated list, or a JSON document rather than a Jira object reference.

{
"objectTypeId": "314",
"objectTypeName": "BusinessApplication",
"_class": "Application",
"enabled": true,
"targetRelationships": [
{
"id": "repositories",
"attributeId": "2710",
"attributeName": "Repositories",
"_class": "USES",
"extract": { "format": "array" },
"transform": ["trim", "lowercase"],
"targetFilter": { "_type": "github_repo", "matchProperty": "fullName" },
"onNoMatch": "skip"
}
],
"propertyToAttributeMap": { }
}
PropertyTypeRequiredDescription
attributeIdstringYes*Jira attribute ID to read raw values from. Mutually exclusive with property.
propertystringYes*Key of propertyToAttributeMap to read the already-converted value from. Mutually exclusive with attributeId.
_classstringYesJupiterOne relationship class (e.g. USES, HAS, CONNECTS)
targetFilterobjectYesWhich entities to match, and on which property
extractobjectNoHow to expand the attribute into values. Defaults to { "format": "array" }.
transformstring or string[]Nolowercase, uppercase, trim, slug, applied in order to every value
directionstringNoFORWARD (default, asset → target) or REVERSE (target → asset)
idstringNoStable identifier for this definition. Defaults to attributeId/property. Changing it rebuilds the relationships.
relationshipTypestringNoExplicit relationship _type. Must begin with jira_.
attributeNamestringNoHuman-readable name (documentation only)
onNoMatchstringNoOnly "skip" is supported

* Exactly one of attributeId or property is required.

Extract Formats​

formatBehaviour
array (default)One relationship per value on a multi-value attribute
valueThe first value only
delimitedSplits the value on delimiter (e.g. "," for a comma-separated list)
jsonParses the value as JSON and reads jsonPath (e.g. "$.interfaces[*].fqdn")

extract.pattern optionally applies a regular expression to each extracted value, using the first capture group when one is present.

Target Filter​

PropertyTypeRequiredDescription
_typestringYes**Target entity _type (e.g. github_repo). Prefer this where you know it — it bounds how many entities can match.
_classstringYes**Target entity _class (e.g. Device). Use when the target may come from several integrations.
matchPropertystringYesThe target property each extracted value is matched against

** At least one of _type or _class is required.

"targetFilter": { "_type": "github_repo", "matchProperty": "fullName" }
"targetFilter": { "_class": "Device", "matchProperty": "name" }

Matching Behaviour​

Values are matched exactly and case-sensitively. Use transform only where you know the target property is stored in lower case:

Target propertyCasingUse transform: "lowercase"
github_repo.fullNamestored lower caseYes
Any User.emailstored lower caseYes
Device.name, Host.hostname, Host.fqdnsource casingNo
jira_user.name, jira_user.displayNamesource casingNo

When a value matches no entity, no relationship is created and no placeholder entity is invented. Definitions that produce values but no relationships are reported as warning events on the integration job, so a mapping that silently yields nothing is visible rather than invisible.

note

This ingestion source is disabled by default. Enable the asset-target-relationships ingestion source in the integration configuration.

Supported JupiterOne Classes​

ClassUse ForKey Properties
DeviceLaptops, desktops, phones, printers, camerashostname, serial, make, model, macAddress, category
HostServers, VMs, VDIhostname, fqdn, ipAddress, osName, osVersion, category
ApplicationSoftware applications, licensesname, version
ServiceBusiness servicescategory (array), function (array)
PersonEmployees, contractorsfirstName, lastName, email
SitePhysical locations, officesname
VendorThird-party vendorsname
NetworkNetwork segments, VLANs, subnetsCIDR, public, internal
CertificateSSL/TLS certificatesdomainName, expiresOn
AccountCloud accounts (AWS, Azure, GCP)vendor
IpAddressIP address resources (IPAM)ipAddress
GatewayLoad balancers, NAT gateways, proxiescategory (array), function (array), public
FirewallFirewall appliances, security groupscategory (array)
DiskStorage devices, volumesname
CryptoKeyEncryption keys, HSM devicesname

You can combine multiple classes: "_class": ["Device", "Firewall"]

note

Some classes have strictly required properties that must be mapped (e.g., vendor for Account, ipAddress for IpAddress). Other classes like Device and Host have nullable required properties that will default to null if not mapped. The integration validates your mapping against the JupiterOne data model and will report errors for missing required properties.

Finding Object Type and Attribute IDs​

To find the IDs needed for your mapping configuration:

Finding Object Type ID:

  1. Go to Jira Service Management > Assets
  2. Click on an Object Schema
  3. Click on an Object Type (e.g., "Laptop")
  4. The Object Type ID is in the URL: .../object-type/{objectTypeId}

Finding Attribute IDs:

  1. From the Object Type page, click Attributes
  2. Click on an attribute to see its details
  3. The Attribute ID is in the URL or settings panel
tip

Use your browser's network inspector when viewing an asset to see the API responses with all IDs.

Auto-Generated Properties​

These properties are automatically set by the integration and don't need mapping:

  • _key, _type, _class - Entity identifiers
  • name, displayName - From Jira object label
  • id - Jira object ID
  • webLink - Link to asset in Jira
  • createdOn, updatedOn - Timestamps
  • objectKey, objectTypeName, objectTypeId - Jira metadata

Entities Created​

Assets ingestion creates:

Entity_type_class
Assets Workspacejira_assets_workspaceRepository
Asset Objectsjira_assets_{objectTypeName}As configured

For example, objectTypeName: "Laptop" creates entities with _type: jira_assets_laptop.

The Assets Workspace entity stands for the Assets workspace of your Jira site. It uses the Repository class because it is a container: it holds no asset data itself. Its workspaceId property is the workspace ID Jira assigns to your site, and every Asset object the integration ingests is linked to it with a HAS relationship. You do not need to configure it; it appears automatically once an Assets mapping is uploaded.

Relationships Created​

SourceRelationshipTarget
jira_accountHASjira_assets_workspace
jira_assets_workspaceHASjira_assets_*
jira_userOWNSjira_assets_* (generic, via ownerEmailProperty or a generic entry in ownerProperties)
jira_userOWNSjira_assets_* (Business Owner, via ownerProperties with role: "business")
jira_userOWNSjira_assets_* (Technical Owner, via ownerProperties with role: "technical")
jira_assets_*as configuredjira_assets_* (via referenceRelationships, e.g. Function, Process, Information Category, ICT Supplier)
jira_assets_*as configuredAny entity _type or _class (via targetRelationships, e.g. github_repo, Device, Host)

Relationships built from targetRelationships depend on your mapping, so they do not appear in the integration's published data model. Where the target is another Assets object type you have configured and enabled, a direct relationship is created; otherwise the relationship is matched against the wider JupiterOne graph.

Troubleshooting​

Invalid project keys​

If a run fails with There is a problem with the Jira configuration, the project key(s) are invalid: ["KEY"], one or more keys in the Project Keys field do not match a project the integration can see. The error names the key(s) at fault.

  1. In Jira, open Projects > View all projects and check whether each named key still exists. Projects that were deleted, moved to trash, or renamed to a new key no longer match.
  2. If the project is gone or you no longer want to ingest it, edit the integration instance in JupiterOne and remove that key from Project Keys. If the project was renamed, replace the old key with the new one.
  3. If the project exists and the key is correct, the integration user (or OAuth service account) cannot see it. Grant that account Browse Projects permission on the project, then run the integration again.

Project keys are matched without regard to case, so secops and SECOPS refer to the same project.

Ownership or value-based relationships are not created​

The Build User Owns Asset Relationships and Build Asset Target Relationships data sources are disabled by default, even when your Assets mapping sets ownerProperties, ownerEmailProperty or targetRelationships. Enable them in the instance's Data Sources settings, then run the integration again. Owner matches also require the owning jira_user to be ingested; no placeholder user is created.

Next Steps​

Now that your integration instance has been configured, it will begin running on the polling interval you provided, populating data within JupiterOne. Continue on to our Instance management guide to learn more about working with and editing integration instances.