Skip to main content

CROSS_SCOPE sync mode

CROSS_SCOPE exists to solve one specific problem: connecting entities that live in different scopes. Each managed integration owns its own scope, so a relationship between, say, an Okta user and a Jamf laptop can't be created by either integration on its own — neither side owns both the from and to entities.

CROSS_SCOPE is the bridge. It accepts only relationships, requires you to label both the from and to entities with their respective scopes, and never creates or deletes entities.

When to use CROSS_SCOPE

  • Both the from and to entities of the relationship already exist in the graph, sourced from different integrations or sync jobs.
  • You only need to create relationships, not entities.
  • The relationships can change over time, and you want a single sync job that owns them.

If the entities in question are in the same scope, use DIFF or PATCH. If you also need to create entities, use the appropriate mode for the scope that owns them and let CROSS_SCOPE handle the cross-cutting edges separately.

Example use cases

Okta users to Jamf laptops

You want to ask "show me every laptop assigned to a member of the SRE Okta group." Okta produces User entities in the Okta scope; Jamf produces Device entities in the Jamf scope. Neither integration produces the OWNS edge between them.

  • Scope: okta-jamf-ownership
  • Mode: CROSS_SCOPE
  • Why CROSS_SCOPE: The relationship spans two integrations. You own the mapping (probably from a separate inventory system), so you push only the edges.
POST /persister/synchronization/jobs
{
"source": "api",
"syncMode": "CROSS_SCOPE",
"scope": "okta-jamf-ownership"
}
POST /persister/synchronization/jobs/{jobId}/upload
{
"relationships": [
{
"_key": "okta-user:alice|owns|jamf-device:laptop-001",
"_type": "user_owns_device",
"_class": "OWNS",
"_fromEntityKey": "okta-user:alice",
"_toEntityKey": "jamf-device:laptop-001",
"_fromEntityScope": "okta-instance-id",
"_toEntityScope": "jamf-instance-id"
}
]
}

GitHub repositories to deployed AWS resources

You want to query "for this S3 bucket, which repository deploys it?" The AWS integration produces the bucket. The GitHub integration produces the repo. Your CI/CD metadata maps deployments to repos.

  • Scope: repo-deployment-edges
  • Mode: CROSS_SCOPE
  • Why CROSS_SCOPE: The from and to entities come from different integrations. The mapping changes when teams move services between repos, so you re-run this sync job whenever your deployment manifests change.

IAM roles to the applications that assume them

You want to track which applications (modeled in your custom CMDB scope) assume which AWS IAM roles (in the AWS scope). This drives blast-radius queries during incident response.

  • Scope: app-iam-assumption
  • Mode: CROSS_SCOPE

Restrictions

  • Entities are rejected. CROSS_SCOPE only accepts relationships. The from and to entities must already exist in the graph from another sync job or integration.
  • The related entities must live outside the sync job's scope. Neither _fromEntityScope nor _toEntityScope may equal the sync job's scope. The two entity scopes can equal each other (for example, two entities from the same AWS integration linked by an external mapping) — the constraint is only that neither may match the CROSS_SCOPE job's own scope. If both entities belong to the sync job's scope, write that relationship from the sync job that owns the scope instead.
  • source must be api.

Required relationship fields

In addition to the standard relationship fields, CROSS_SCOPE relationships need:

PropertyTypeDescription
_fromEntityScopestringScope identifier of the source entity. For managed integrations, this is the _integrationInstanceId.
_toEntityScopestringScope identifier of the target entity.

The from and to entities can be referenced by either _fromEntityKey/_toEntityKey or _fromEntityId/_toEntityId — whichever you have available.

Example: CROSS_SCOPE sync job

POST /persister/synchronization/jobs
{
"source": "api",
"syncMode": "CROSS_SCOPE",
"scope": "repo-deployment-edges"
}
POST /persister/synchronization/jobs/{jobId}/upload
{
"relationships": [
{
"_key": "github-repo:platform-api|deploys|s3-bucket:platform-assets",
"_type": "repo_deploys_bucket",
"_class": "DEPLOYS",
"_fromEntityKey": "github-repo:platform-api",
"_toEntityKey": "s3-bucket:platform-assets",
"_fromEntityScope": "github-instance-id",
"_toEntityScope": "aws-instance-id"
}
]
}
POST /persister/synchronization/jobs/{jobId}/finalize

Operational notes

  • The entities must exist at finalize time. If either entity is missing or has been soft-deleted, the relationship is not created.
  • CROSS_SCOPE behaves like DIFF for its own scope. Relationships you previously created in this scope and don't include in the new upload are deleted. Use a stable scope so your edge set reconciles cleanly.
  • One CROSS_SCOPE job per logical mapping. Putting unrelated cross-scope edge sets in the same scope mixes their lifecycles.

Common errors

ErrorCauseFix
Entities cannot be uploaded in CROSS_SCOPE modeTried to upload entities.Create entities in their owning scope; use CROSS_SCOPE only for edges.
Same-scope relationships rejected_fromEntityScope equals _toEntityScope.Use the owning scope's sync job for these edges.
Relationship missing after finalizeAn entity referenced by the relationship did not exist (or was soft-deleted).Confirm both entities are in the graph; check their _id/_key and scope.

See the API reference for the complete error table.