Community
Questions Library
Docs
Blog
Events
Swag
Github
Slack
JupiterOne
Discussions
Release Notes
Contact Us
JupiterOne Entity Relationship Mappings - AskJ1 Community
<main> <article class="userContent"> <p>JupiterOne stores <a rel="nofollow" href="https://jupiterone.vanillacommunities.com/kb/articles/846-jupiterone-data-model">entities and relationships</a> representing your organization's critical resources, their configurations, and their relationships. Relationships between entities may be explicitly stated in the APIs of the systems that manage them, and the integrations with those systems will leverage that information to build relationships in JupiterOne. In other cases, relationships need to be inferred from properties common to a set of related entities. This inference can extend across entities from multiple systems so that relationships can be automatically mapped, given enough context about how entities are related through their common properties. In some cases, entities will be generated to represent a resource that doesn't exist as an explicit thing in your systems, but is implied, such as the Internet.</p> <p>Entity relationship mappings provide the context necessary to support this automatic relationship building.</p> <h2 data-id="how-does-it-work">How Does It Work</h2> <p>Mapping rules are maintained by the JupiterOne engineering team; they cannot be modified by customers today. However, it is still important to understand how the mapping rules work because:</p> <ol><li>Entities and relationships that mappings produce will exist in your data, though you will not be billed for these.</li> <li>Knowing about mappings allows you to leverage the entities and relationships they produce in J1 queries.</li> <li>Some mappings require customers to add properties to entities so that relationships can be inferred.</li> </ol><p>As entities are created and updated, the system will check to see if the entity matches a mapping rule. This entity is considered the source of the relationship to build. The target of the relationship is determined by performing a search according to the mapping's target filter parameters. When more than one entity matches the target filter, a relationship is established between the source and each target entity. No relationship is created when a target is not found. A single target entity will be created when no existing entities match, unless <code class="code codeInline code codeInline" spellcheck="false" tabindex="0">skipTargetCreation: true</code>.</p> <p>The mapping specifies the properties to transfer to a target created by the mapper. The values of those properties may be static, being explicitly defined in the rule, or the values may be transferred from the source entity. When multiple mapping rules resolve to the same mapper-created target entity, the target entity will accumulate the properties. This allows for a target to include properties from any mapped source entity.</p> <p>The mapper will produce operations to create, update, or delete the target entities and relationships it manages. The entities produced by the mapper may themselves match a mapping rule, leading to a cascading effect that builds a graph of relationships.</p> <p>Try this J1QL query to see entities produced by the mapper in your J1 account:</p> <pre class="code codeBlock" spellcheck="false" tabindex="0">FIND * WITH _source="system-mapper" LIMIT 10 </pre> <p>This query will show some relationships it created:</p> <pre class="code codeBlock" spellcheck="false" tabindex="0">FIND * THAT RELATES TO AS r Root WHERE r._source="system-mapper" RETURN r.* LIMIT 10 </pre> <h2 data-id="example-use-cases">Example Use Cases</h2> <h3 data-id="identifying-accounts-that-belong-to-a-person">Identifying Accounts That Belong to a Person</h3> <p>Integrations with an identity provider have mapping rules that cause the mapper to produce a <code class="code codeInline code codeInline" spellcheck="false" tabindex="0">Person</code> entity when the users of the IdP have properties that identify the record as a real person, not a bot or service account. Once that <code class="code codeInline code codeInline" spellcheck="false" tabindex="0">Person</code> entity exists, whenever a <code class="code codeInline code codeInline" spellcheck="false" tabindex="0">User</code> entity is produced by any system, the <code class="code codeInline code codeInline" spellcheck="false" tabindex="0">User</code> will be related to the <code class="code codeInline code codeInline" spellcheck="false" tabindex="0">Person</code> as well when there are properties that identify the account with the <code class="code codeInline code codeInline" spellcheck="false" tabindex="0">Person</code>, such as an <code class="code codeInline code codeInline" spellcheck="false" tabindex="0">email</code> or <code class="code codeInline code codeInline" spellcheck="false" tabindex="0">username</code>.</p> <p>If you have an IdP integration configured, such as Okta or OneLogin, you may find user accounts that belong to a person:</p> <pre class="code codeBlock" spellcheck="false" tabindex="0">FIND User AS u THAT RELATES TO Person AS p RETURN u.email, u._type, u.displayName, p.employeeType LIMIT 5 </pre> <h2 data-id="relationship-mapping-rules">Relationship Mapping Rules</h2> <p>Mapping rules are maintained by the JupiterOne engineering team, but it is instructive to see that rules take this basic form:</p> <pre class="code codeBlock" spellcheck="false" tabindex="0">{ "sourceFilter": { "_class": "Person" }, "relationshipProperties": { "_class": "IS" }, "relationshipDirection": "REVERSE", "targetFilterKeys": [ ["_class", "email"], ["_class", "username"] ], "propertyMappings": [ { "sourceProperty": "email", "targetProperty": "email" }, { "sourceProperty": "email", "targetProperty": "username" }, { "targetValue": "User", "targetProperty": "_class" } ], "skipTargetCreation": true } </pre> <ul><li><p><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">"sourceFilter"</code>: Declares the properties of the source entity that the rule matches</p></li> <li><p><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">"relationshipProperties"</code>: Declares the properties to place on generated relationships</p></li> <li><p><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">"relationshipDirection"</code>: Declares the directionality of the relationship</p></li> <li><p><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">"targetFilterKeys"</code>: Declares the properties to query when resolving the target entities</p></li> <li><p><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">"propertyMappings"</code>: Declares the properties to assign to target entities created by the mapper and provides the values used to search for the target entities</p></li> <li><p><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">"skipTargetCreation"</code>: Instructs the mapper to avoid creating the target entity when none already exist</p></li> </ul><h2 data-id="mappings">Mappings</h2> <p>The current mappings are summarized below. The <em>Global Mappings</em> apply to entities no matter how they are produced, whether by a managed integration or through the JupiterOne API. Each managed integration may also specify mappings that are applied only to entities managed by that integration.</p> <p>The summaries have a title taking the form <code class="code codeInline code codeInline" spellcheck="false" tabindex="0">SOURCE RELATIONSHIP TARGET</code>.</p> <ul><li><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">SOURCE</code> is always the entity that triggers the mapping configuration. The label is the <code class="code codeInline code codeInline" spellcheck="false" tabindex="0">_class</code> or <code class="code codeInline code codeInline" spellcheck="false" tabindex="0">_type</code> that will be matched. Other match properties are listed in the summary body.</li> <li><p><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">RELATIONSHIP</code> is relative to <code class="code codeInline code codeInline" spellcheck="false" tabindex="0">SOURCE</code>, and the label of comes from the <code class="code codeInline code codeInline" spellcheck="false" tabindex="0">_class</code>.</p> <ul><li>Forward: <code class="code codeInline code codeInline" spellcheck="false" tabindex="0">-CLASS-></code></li> <li>Reverse: <code class="code codeInline code codeInline" spellcheck="false" tabindex="0"><-CLASS-</code></li> </ul></li> <li><p><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">TARGET</code> is determined by a search, or one will be created when not found (unless <code class="code codeInline code codeInline" spellcheck="false" tabindex="0">skipTargetCreation: true</code>). The label is the <code class="code codeInline code codeInline" spellcheck="false" tabindex="0">_class</code> or <code class="code codeInline code codeInline" spellcheck="false" tabindex="0">_type</code> that will be matched. Other match properties are listed in the summary body.</p></li> </ul><p>It is important to remember:</p> <ul><li>Mapping rules are triggered when a <code class="code codeInline code codeInline" spellcheck="false" tabindex="0">SOURCE</code> entity matches. Rules are NOT automatically reversed so that relationships are updated when a <code class="code codeInline code codeInline" spellcheck="false" tabindex="0">TARGET</code> is created/updated.</li> <li>Any change to the <code class="code codeInline code codeInline" spellcheck="false" tabindex="0">SOURCE</code> entity triggers the mapping rule to be evaluated/re-evaluated.</li> <li>The <strong>Source Filters</strong> must match an entity or the rule will not trigger. It may be necessary to <em>add properties to entities</em> at the data source so that when they are ingested they will match the rule.</li> <li>A rule produces relationships to all <code class="code codeInline code codeInline" spellcheck="false" tabindex="0">TARGET</code> entities matching the <strong>Target filters</strong>. It may be necessary to <em>add properties to entities</em> at the data source so that when they are ingested they will match the rule.</li> <li><strong>Transferred Properties</strong> are listed only when the mapper will create a target entity if none are found (<code class="code codeInline code codeInline" spellcheck="false" tabindex="0">skipTargetCreation: false</code>).</li> </ul><h3 data-id="mappings-rules">Mappings Rules</h3> <ul><li><a rel="nofollow" href="https://jupiterone.vanillacommunities.com/kb/articles/796-global-mappings">Global Mapping Rules</a></li> <li><a rel="nofollow" href="https://jupiterone.vanillacommunities.com/kb/articles/797-integrations-mappings">Integration Specific Mapping Rules</a></li> </ul> </article> </main>