Skip to content

The relation object (metadata["relations"])

Section 7 · From docs/INVENTORY_REFERENCE.md on GitHub

Collectors never create edges between assets of different services directly. They declare what an asset talks to, by identifier, in metadata["relations"], and the linker resolves the identifiers and creates the edges. Relations stay on the asset in the exported map.

Built by cloudg.inventory.aws_services._base.rel() (also used by the Azure and GCP extractors):

rel(target, edge, relationship=None, *, reverse=False, description=None, **properties)
    -> dict | None
Key Type Present Meaning
target str always Any identifier of the other asset (formats). rel() returns None (and callers drop it) for an empty or non-string target.
edge str always An EdgeType value. An unknown value is linked as REFERENCES.
relationship str when given A RelationType name.
reverse bool only when true The edge goes from target to the declaring asset. Used when the declaring side is the passive one ("my queue triggers me", "this subnet contains me", "this principal is granted access to me").
description str when given Copied to the edge's description.
properties dict when any non-empty Extra keyword arguments, with None, "", [] and {} values dropped. Copied to the edge's properties.

Example, a resource policy grant declared on a queue: the account 555555555555 may send messages. With reverse: true, the resulting edge is account GRANTS_ACCESS queue.

{
  "target": "arn:aws:iam::555555555555:root",
  "edge": "GRANTS_ACCESS",
  "relationship": "POLICY_ALLOWS_ACTION",
  "reverse": true,
  "description": "resource policy grant",
  "properties": {"cross_account": true}
}

A relation that resolves to nothing is reported in unresolved_references unless its target is in an account that was not mapped, in which case an external account placeholder is created and the edge points there (properties.external_reference keeps the original target).