You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Run the integration the other way: export Identity Atlas's correlated, multi-system authorization graph as BloodHound OpenGraph JSON, so BloodHound can compute attack paths over our superset — on top of, or as a replacement for, its own collected data.
This is 3 of 3 companion feature requests from a feasibility study (docs/architecture/bloodhound-integration-feasibility.md,`` §5.6 / Option E). The three are related but independently buildable.
Why this is more than "the same thing backwards" — it's the platform play
Identity Atlas is a normalizing, identity-correlating superset: our Account Linking engine resolves accounts across systems to real people. BloodHound does not correlate identity across sources — it holds an AD graph, an Entra graph, a GitHub graph, an AWS graph as separate islands.
If we export our nodes/edges as OpenGraph with our identity links as the bridging edges, BloodHound can compute cross-system attack paths it structurally cannot derive on its own, e.g.:
"This GitHub identity is the same person (our link) as this Entra admin who holds GenericAll (our control edge) over an on-prem tier-zero group."
BloodHound alone can't draw that first hop; we can. This reframes Identity Atlas as the authorization system-of-record / shared graph, with our governance analytics and BloodHound's attack-path analytics as two consumers of one substrate — the concrete expression of "if we do our job right, we already have more data from more systems than any single collector."
Constraints to respect: ≤ 3 kinds per node, property values primitives or homogeneous arrays (no null), edge kind matches ^[A-Za-z0-9_]+$, objectid = our stable id (dedup key → idempotent re-ingestion).
Define custom OpenGraph node/edge kinds for our governance concepts (identities, business roles, governed assignments, our control edges), plus the identity-correlation bridge edges (e.g. a SameIdentity / member-of-Identity edge) that stitch the per-source graphs.
Deliver to BloodHound via file ingest (drop the JSON) or the /api/v2 upload API. Optionally register an OpenGraph extension-definition (custom kinds + icons + traversal rules) so our nodes render/traverse natively.
Support both modes: augment BloodHound's existing collected data, or replace it (be the sole source).
The gate — why this shares a dependency with #939 (but stays independent)
To feed BloodHound useful attack paths, our exported graph must carry the control edges at fidelity (GenericAll vs WriteDacl changes what's abusable). A coarse "has access" flag exports nodes and memberships but no abuse-relevant edges. So this depends on the fine-grained control-edge modelling (PrincipalRelationships / migration 057 + object-as-resource control assignments) — the same investment that lets #939 absorb control data. Model the control edges once; both directions light up. The exporter itself is independently buildable and can ship first for the membership/role/ownership subset.
Acceptance criteria
An OpenGraph exporter: Identity Atlas graph → valid OpenGraph JSON (kinds ≤ 3, primitives-only, no null, stable ids).
Output validated against the OpenGraph spec and ingestible by BloodHound CE (file ingest and/or /api/v2).
Augment and replace modes.
Demonstrated cross-system path enabled by our identity correlation (the multi-source bridge) that BloodHound could not derive from its own collectors alone.
Tests per repo conventions (coverage ratchet respected).
References
Feasibility study §5.6 (Option E), §4.3 (control-edge modelling), §4.4 (correlation is ours).
Summary
Run the integration the other way: export Identity Atlas's correlated, multi-system authorization graph as BloodHound OpenGraph JSON, so BloodHound can compute attack paths over our superset — on top of, or as a replacement for, its own collected data.
Why this is more than "the same thing backwards" — it's the platform play
Identity Atlas is a normalizing, identity-correlating superset: our Account Linking engine resolves accounts across systems to real people. BloodHound does not correlate identity across sources — it holds an AD graph, an Entra graph, a GitHub graph, an AWS graph as separate islands.
If we export our nodes/edges as OpenGraph with our identity links as the bridging edges, BloodHound can compute cross-system attack paths it structurally cannot derive on its own, e.g.:
BloodHound alone can't draw that first hop; we can. This reframes Identity Atlas as the authorization system-of-record / shared graph, with our governance analytics and BloodHound's attack-path analytics as two consumers of one substrate — the concrete expression of "if we do our job right, we already have more data from more systems than any single collector."
How
{ "graph": { "nodes":[…], "edges":[…] }, "metadata": { "source_kind": … } }.{ id, kinds:[…], properties:{…} }; edges:{ kind, start:{value,match_by}, end:{…}, properties }.kindsper node, property values primitives or homogeneous arrays (nonull), edgekindmatches^[A-Za-z0-9_]+$,objectid= our stable id (dedup key → idempotent re-ingestion).SameIdentity/ member-of-Identity edge) that stitch the per-source graphs./api/v2upload API. Optionally register an OpenGraph extension-definition (custom kinds + icons + traversal rules) so our nodes render/traverse natively.The gate — why this shares a dependency with #939 (but stays independent)
To feed BloodHound useful attack paths, our exported graph must carry the control edges at fidelity (
GenericAllvsWriteDaclchanges what's abusable). A coarse "has access" flag exports nodes and memberships but no abuse-relevant edges. So this depends on the fine-grained control-edge modelling (PrincipalRelationships/ migration 057 + object-as-resource control assignments) — the same investment that lets #939 absorb control data. Model the control edges once; both directions light up. The exporter itself is independently buildable and can ship first for the membership/role/ownership subset.Acceptance criteria
null, stable ids)./api/v2).References
p0dalirius/bhopengraph;SpecterOps/OpenHound; BloodHound OpenGraph docs.Related feature requests (BloodHound integration set — independent, not interdependent)
attack-pathrisk plugin (external data) #940.Cross-links in a comment below.