Skip to content

DependencyGraph results

Section 12 · From docs/INVENTORY_REFERENCE.md on GitHub

cloudg.inventory.DependencyGraph(assets, edges, include_hierarchy=False). Every edge with a known dependency direction (section 6) whose endpoints are both assets becomes one dependent → dependency arrow.

Method Returns
find(ref) CloudAsset \| None. Tries, in order: internal id; exact arn; name when exactly one asset has it; the last / segment of arn when exactly one asset matches.
depends_on(asset_id, max_depth=10) list[DependencyLink], everything the asset needs, breadth-first.
dependents(asset_id, max_depth=10) list[DependencyLink], everything that needs the asset (its blast radius), breadth-first.
direct_counts(asset_id) tuple[int, int]: (direct dependencies, direct dependents), counting parallel edges.
tree(asset_id, direction="both", max_depth=3) nested dict, 12.2.
shared_dependencies(top=25) list[dict], 12.3.
blast_radius(candidates=None, top=25) list[dict], 12.4.
Field Type Meaning
asset_id str The asset reached.
via_edge str edge_type of the edge used.
relationship str \| None relationship of that edge.
depth int Hops from the start, starting at 1.
parent_id str The asset it was reached from.

Each asset appears once per walk, at the depth and under the parent where the breadth-first search first reached it.

12.2 tree

graph.tree(asset_id, direction="both", max_depth=3) -> dict
Key Present Type Meaning
asset always asset descriptor The starting asset.
depends_on direction up or both list[node] What it needs.
dependents direction down or both list[node] What needs it.

An asset descriptor is {"id", "name", "arn", "type", "account_id", "region"} (type is the asset_type value). A node is an asset descriptor plus:

Key Type Meaning
via str Edge type that links this node to its parent.
relationship str \| None Relationship of that edge.
children list[node] The next level, empty at max_depth.

Example, the role orders-worker from the example run, direction="both", abridged:

{
  "asset": {
    "id": "1bd88609-88f3-46d7-868e-ac65ece6b65a",
    "name": "orders-worker",
    "arn": "arn:aws:iam::123456789012:role/orders-worker",
    "type": "IAM_ROLE",
    "account_id": "123456789012",
    "region": "global"
  },
  "depends_on": [
    {
      "id": "f26a0b92-407e-44d7-8644-f73f462fa7e6",
      "name": "arn:aws:iam::123456789012:policy/orders-queue-access",
      "arn": "arn:aws:iam::123456789012:policy/orders-queue-access",
      "type": "IAM_POLICY",
      "account_id": "123456789012",
      "region": "global",
      "via": "IAM_POLICY_ATTACHMENT",
      "relationship": "ROLE_HAS_POLICY",
      "children": []
    },
    {
      "id": "c612cd24-42db-4260-b755-3ee3a24da24f",
      "name": "orders",
      "arn": "arn:aws:sqs:us-east-1:123456789012:orders",
      "type": "MESSAGE_QUEUE",
      "account_id": "123456789012",
      "region": "us-east-1",
      "via": "GRANTS_ACCESS",
      "relationship": "POLICY_ALLOWS_ACTION",
      "children": [
        {"name": "289e9c59-…", "type": "KMS_KEY", "via": "REFERENCES", "relationship": "ENCRYPTED_BY_KMS", "children": [], "…": "…"},
        {"name": "orders-dlq", "type": "MESSAGE_QUEUE", "via": "REFERENCES", "relationship": "WRITES_TO", "children": [], "…": "…"},
        {"name": "order-events", "type": "NOTIFICATION_TOPIC", "via": "INVOKES", "relationship": "STREAMS_TO", "children": [], "…": "…"}
      ]
    }
  ],
  "dependents": [
    {
      "id": "60cac611-8a80-469e-bca6-ee3cf1cdc35b",
      "name": "orders-worker",
      "arn": "arn:aws:lambda:us-east-1:123456789012:function:orders-worker",
      "type": "LAMBDA_FUNCTION",
      "account_id": "123456789012",
      "region": "us-east-1",
      "via": "ASSUMES_ROLE",
      "relationship": "RUNS_ON",
      "children": [
        {"name": "orders-api", "type": "CONTAINER_SERVICE", "via": "REFERENCES", "relationship": "DEPENDS_ON", "children": [], "…": "…"}
      ]
    }
  ]
}

Reading it: the role needs its attached policy and the queue its policy grants access to; the queue in turn needs its KMS key and its DLQ, and depends on the topic that delivers into it (order-events INVOKES orders is a reverse-direction edge, so the queue depends on the topic). Downstream, the function runs as the role, and the ECS service references the function.

12.3 shared_dependencies

Assets that the most other assets depend on directly, ignoring CONTAINS and PEERING. Only assets with at least two such dependents are listed; sorted by descending count.

Key Type Meaning
asset descriptor keys id, name, arn, type, account_id, region
direct_dependents int Distinct assets with a direct functional dependency on it.
[
  {"id": "1bd88609-88f3-46d7-868e-ac65ece6b65a", "name": "orders-worker",
   "arn": "arn:aws:iam::123456789012:role/orders-worker", "type": "IAM_ROLE",
   "account_id": "123456789012", "region": "global", "direct_dependents": 8},
  {"id": "756b6990-690f-4136-98c1-69cfd2b7a71d", "name": "web",
   "arn": "arn:aws:ec2:us-east-1:123456789012:security-group/sg-05c9fb72915768cb5",
   "type": "SECURITY_GROUP", "account_id": "123456789012", "region": "us-east-1",
   "direct_dependents": 6}
]

12.4 blast_radius

The assets whose failure or change would affect the most others, transitively. Candidates are the 4 × top assets with the most direct dependents (or the candidates you pass); each is walked with dependents(max_depth=10). Assets with no dependents are dropped; sorted by descending transitive_dependents.

Key Type Meaning
asset descriptor keys id, name, arn, type, account_id, region
transitive_dependents int Assets that depend on it directly or indirectly (up to 10 hops).
accounts_affected int Distinct accounts among those dependents.
internet_exposed_dependents int Internet-exposed assets among them.
[
  {
    "id": "8d7d700b-7f64-4821-97b2-45577d1faf7a",
    "name": "FullAWSAccess",
    "arn": "arn:aws:organizations::123456789012:policy/o-1wietecbs4/service_control_policy/p-FullAWSAccess",
    "type": "ORG_POLICY",
    "account_id": "123456789012",
    "region": "global",
    "transitive_dependents": 38,
    "accounts_affected": 3,
    "internet_exposed_dependents": 4
  }
]

An SCP attached to the root topping the list is expected: everything in the governed accounts depends on it.