Skip to content

Design principles

Section 1 · From docs/INVENTORY_INTERNALS.md on GitHub

  1. Declare, don't resolve. A collector knows only the identifier of what an asset talks to (a role ARN, a queue URL, an image URI, a subnet ID). It records that identifier as a relation on the asset. Resolution into an edge happens once, in the linker, over the whole inventory, so a function in account A that reads a queue in account B in another region links correctly no matter which collector ran first.
  2. No scanner, no writes. Mapping runs only read-only Describe* / List* / Get* calls (plus the Kubernetes API GETs and the Resource Graph / Cloud Asset Inventory queries). It never runs a security scanner; findings can be overlaid later.
  3. Breadth with precedence. Deep collectors produce detailed assets; breadth sweeps (AWS Cloud Control and Tagging API, Azure ARM sweep, GCP Cloud Asset Inventory) make sure nothing is missing; deduplication keeps the richest copy.
  4. Absence is data. A security service that is not enabled becomes a placeholder asset with enabled: false; a reference to an unmapped account becomes an external account node; a reference to nothing is listed as unresolved. Gaps show on the map instead of disappearing.
  5. No secret ever enters the inventory. Values that could be secret are dropped at collection time, not filtered at export time.
  6. One model for three clouds. AWS, Azure and GCP produce the same CloudAsset / NetworkEdge model, the same relation objects, and go through the same linker.