Infrastructure Lineage
Trace the full infrastructure stack for any CI from physical hardware to applications
Overview
Infrastructure lineage traces the full stack for any Configuration Item (CI), answering two fundamental questions: "What does this run on?" and "What runs on this?" Starting from any CI, the lineage engine walks relationships in both directions to build a complete picture from physical site down to application workloads.
This cross-layer visibility enables:
- Root cause analysis: A failing Kubernetes pod can be traced down through its node, VM, physical host, and rack to identify infrastructure-level causes
- Impact assessment: Before taking a physical node offline, see every VM, OS instance, and application workload that depends on it
- Infrastructure audit: Verify that production workloads have the expected physical backing and aren't running on under-provisioned hardware
- Change propagation: Understand which layers are affected when a storage pool is reconfigured or a network interface changes
- Inherited attribute discovery: Find IP addresses, FQDNs, hardware specs, and location data from ancestor CIs that the workload itself doesn't directly expose
How It Works
The lineage engine performs a bidirectional graph traversal from a seed CI. It walks in two directions simultaneously:
- Ancestor walk (toward physical infrastructure): follows
runs_on,hosted_by,located_in, and similar upward relationships to find the infrastructure stack beneath the seed CI - Descendant walk (toward logical workloads): follows
contains,hosts,manages, and similar downward relationships to find everything that depends on the seed CI
Each hop follows the relationship's own direction classification: the ancestor walk takes upward edges, the descendant walk takes downward edges, and the tier a CI sits in (its stack layer) is presentation only, not a traversal gate. A visited set prevents cycles, and a configurable depth limit controls how far the walk extends.
After the walk completes, the engine optionally aggregates inherited attributes from ancestor nodes. This surfaces information like IP addresses, hardware specs, and location data that a workload CI doesn't directly hold but can be inferred from its infrastructure chain.
The Tier System
Every CI type in Parascope is assigned to one of ten tiers, ordered from most physical to most logical. The tier ordering sets each CI's stack layer and the visual layout; relationship direction, not tier ordering, decides which edges lineage walks (see below).
Tier Hierarchy
| Index | Tier | Description | Example CI Types |
|---|---|---|---|
| 0 | Site | Geographic locations and facilities | netbox.site, netbox.location |
| 1 | Rack | Physical rack enclosures | netbox.rack |
| 2 | Physical | Bare-metal servers and hardware | netbox.device, proxmox.node |
| 3 | Network | Network interfaces, IPs, DNS | netbox.interface, netbox.ipaddress, dns.zone |
| 4 | Storage | Storage pools, volumes, disks | ceph.pool, ceph.osd, proxmox.storage, kubernetes.pv, kubernetes.pvc |
| 5 | Virtual | Virtual machines and hypervisor-level containers | proxmox.vm, proxmox.container, openstack.instance |
| 6 | OS | Operating system instances and Kubernetes nodes | os.linux, kubernetes.node |
| 7 | Application | Workloads, services, and software | kubernetes.pod, kubernetes.deployment, os.container, os.software, postgresql.database |
| 8 | Service | Logical service groupings | backstage.system, backstage.component |
| 9 | Product | Business domain groupings | backstage.domain |
Relationship Directions
Relationships have an inherent direction that the lineage engine uses to determine valid traversals:
| Direction | Relationship Types | Meaning |
|---|---|---|
| Upward | runs_on, hosted_by, installed_on, located_in, in_rack, in_site, part_of, member_of, runs_as | Source depends on target (toward physical) |
| Downward | contains, manages, owns, hosts, provides | Source provides for target (toward logical) |
| Lateral | correlates_with and similar equivalence links | No hosting direction; followed in both walks to stitch correlated CIs into the chain |
Direction Governs Traversal
Traversal is decided entirely by each relationship's direction classification (above), never by the tier ordering. Upward edges build the ancestor chain and downward edges build the descendant chain; lateral edges such as correlates_with are followed in both walks, which is how a confirmed correlation stitches a CI's chain across to the hardware it was matched to. Relationship types with no lineage direction (graph-only overlays such as monitors) are not walked by lineage at all, though they stay visible in the relationship graph.
A CI's tier still sets the layer shown on its row, but it no longer gates which edges are walked. In the tree, a laterally linked CI attaches as an aka: row rather than as a hosting step, so a correlation reads as the same thing seen from another source instead of implying one runs on the other. Lineage also stays within a single dimension: an infrastructure CI's owned_by link to an identity group is never walked as lineage, even though it shows in the graph.
Using the Lineage UI
The lineage visualization appears on every CI detail page, positioned between the header and the detail tabs. It provides two views that you can toggle between.
Compact Strip View
The default compact strip displays the ancestor chain as a horizontal sequence of connected pills:
- Pill badges: Each ancestor appears as a compact pill showing an icon, the CI name, its type, and a status indicator dot
- Connector lines: Horizontal lines between pills indicate the relationship. Hover over a connector to see the relationship type (e.g.,
runs_on,in_rack) - Branching indicators: When multiple CIs exist at the same depth, the strip shows the first one with a "+N" badge indicating additional nodes. Click the badge to expand
- Descendant summary: To the right of the seed CI, an arrow leads to a summary of descendant types. Each type badge shows the CI type and count (e.g.,
kubernetes.pod x3) - Navigation: Click any pill to navigate directly to that CI's detail page
Expanded Tree View
Click the expand button on the compact strip to switch to the full lineage tree. The tree lays out every node in the traversal as a hierarchy: the seed sits inside its ancestor chain, and descendants nest beneath it along the primary containment path.
- Node rows: Each CI is a row with its type glyph, name, a status dot, and a layer chip naming its position in the stack (Site, Rack, Physical, and so on). When a node attaches through a relationship that differs from what its same-type siblings share, that relationship is labeled inline (for example
via owned_by); the common containment case is left unlabeled, since the nesting already conveys it - Seed highlighting: The seed CI is anchored with an accent bar and a tinted background so you can locate it in the tree
- Fan-out groups: When five or more siblings share a type, they collapse into a single
N× typerow you can expand. A very wide group opens as a scrollable table, and each member shows a+N nestedcount for any subtree hidden beneath it +N linkschips: A node with relationships that fall outside its tree branch shows a+N linkschip; clicking it opens a popover listing those edges and their targetsaka:rows: Lateral relationships (equivalence links such ascorrelates_with) render asaka:rows, attaching a correlated CI to its partner rather than implying a hosting relationship- Truncation banners: Each direction shows a banner when its walk hit the 500-node cap, and a root whose chain may continue past what was fetched is marked
path incomplete - Inherited attributes panel: Below the tree, a collapsible panel displays inherited attributes grouped by category (location, hardware, network, and so on). Each attribute shows its value and a provenance link to the ancestor CI it came from
Switching Between Views
The compact strip is ideal for quick orientation: see the primary chain at a glance. Switch to the tree view when you need to see branching paths, all descendants, or the full inherited attributes with provenance tracking.
Real-World Examples
Example 1: Tracing a Kubernetes Pod
Starting from a kubernetes.pod named web-api-7f8b9c4d5-xk2mn, the lineage traces the complete infrastructure stack:
What the compact strip shows: A horizontal chain of seven pills from Primary Datacenter on the left through to the pod on the right, with connector tooltips showing each relationship type.
What the expanded tree shows: The ancestor chain nests from netbox.site at the top down to the pod, which is anchored as the seed. Each node carries a layer chip (Site, Rack, Physical, Virtual, Application). Because proxmox.node and netbox.device describe the same physical host, one attaches to the other as an aka: row linked by correlates_with.
Inherited attributes surfaced:
- Network: IP addresses
10.0.1.67(fromkubernetes.node), FQDNs from DNS records - Hardware: CPU model, 4 cores, serial number (from
netbox.device) - Compute: 4 vCPUs, 6144 MB memory (from
proxmox.vm) - Location: "Primary Datacenter", "Rack-A1" (from
netbox.siteandnetbox.rack)
Each attribute includes a provenance link. Clicking "from host-01" next to the serial number navigates to the Netbox device detail page.
Example 2: Impact From a Physical Node
Starting from proxmox.node named host-01, the descendant walk reveals everything running on this host:
- Virtual tier: 3 VMs (
worker-node-01,worker-node-02,dns-server) - OS tier:
os.linuxinstances for each VM - Application tier: Multiple pods per worker node, DNS software on the DNS server
The compact strip shows the ancestor chain (device, rack, site) with a descendant summary to the right: proxmox.vm x3, os.linux x3, kubernetes.pod x12, os.software x2. This immediately communicates the blast radius: taking host-01 offline impacts 3 VMs and 12 pods.
Inherited Attributes
Workload CIs often lack context about their physical infrastructure. A Kubernetes pod doesn't know what rack it's in or what CPU model runs beneath it. Inherited attributes solve this by aggregating information from ancestor CIs in the lineage chain.
Attribute Groups
| Group | Source Tier | Fields | Description |
|---|---|---|---|
| network | All ancestors | ip_addresses, fqdns, hostnames | Network identifiers collected and deduplicated from every ancestor |
| location | Site, Rack | name, physical_address, region, facility, u_height | Geographic and physical placement |
| hardware | Physical | serial, model, cpu_cores, cpu_model, memory_gb, status | Bare-metal hardware specifications |
| compute | Virtual | vcpu_count, cores, memory_mb, disk_size, vmid, status | VM-level resource allocation |
| operating_system | OS | os_distribution, os_version, kernel_version, uptime_seconds | OS-level details |
| application | Application | version, listening_ports, service_state, status | Application runtime information |
Provenance Tracking
Every inherited attribute records which CI it came from. This provenance tracking lets you trace any value back to its authoritative source:
{
"hardware": {
"value": {
"serial": "SN-ABC123",
"cpu_cores": 32,
"cpu_model": "Intel Xeon E-2388G"
},
"sources": {
"serial": { "ci_id": "...", "ci_type": "netbox.device", "name": "host-01" },
"cpu_cores": { "ci_id": "...", "ci_type": "netbox.device", "name": "host-01" },
"cpu_model": { "ci_id": "...", "ci_type": "netbox.device", "name": "host-01" }
}
}
}Aggregation Rules
- Network attributes (IPs, FQDNs, hostnames) are collected from all ancestors and deduplicated. This gives workloads a comprehensive picture of the network identities in their stack
- Tier-specific attributes (hardware, compute, etc.) use the closest ancestor of that tier. If multiple ancestors share a tier, the first one encountered during traversal is used
- Restricted CIs are skipped during attribute collection. Their data is not inherited by downstream nodes
- Each attribute value tracks its source CI independently, so a single group may have values from different CIs
API Reference
Endpoint
GET /api/v1/configuration-items/{ci_id}/lineageParameters
| Parameter | Type | Default | Description |
|---|---|---|---|
ci_id | UUID (path) | required | The CI to trace lineage from |
depth | integer | 5 | Maximum hops in each direction (1-10) |
include_attributes | boolean | true | Collect inherited attributes from ancestors |
relationship_types | string | all types | Comma-separated filter (e.g., runs_on,hosted_by) |
Authentication
Requires an API key via the X-API-Key header. See Authentication for details on obtaining keys.
Examples
Default lineage (depth 5, with attributes):
curl -H "X-API-Key: $API_KEY" \
"https://your-company.parascope.io/api/v1/configuration-items/{ci_id}/lineage"Shallow lineage (immediate neighbors only):
curl -H "X-API-Key: $API_KEY" \
"https://your-company.parascope.io/api/v1/configuration-items/{ci_id}/lineage?depth=1"Filtered by relationship type:
curl -H "X-API-Key: $API_KEY" \
"https://your-company.parascope.io/api/v1/configuration-items/{ci_id}/lineage?relationship_types=runs_on"Without inherited attributes:
curl -H "X-API-Key: $API_KEY" \
"https://your-company.parascope.io/api/v1/configuration-items/{ci_id}/lineage?include_attributes=false"Response Structure
{
"seed": {
"ci_id": "550e8400-e29b-41d4-a716-446655440000",
"name": "web-api-7f8b9c4d5-xk2mn",
"ci_type": "kubernetes.pod",
"tier": "application",
"status": "active",
"attributes": {
"ip_addresses": ["10.244.0.15"],
"hostnames": [],
"fqdns": [],
"scope_label": "production-cluster",
"type_specific": {}
}
},
"ancestors": [
{
"ci_id": "660e8400-e29b-41d4-a716-446655440001",
"name": "worker-node-01",
"ci_type": "kubernetes.node",
"tier": "physical",
"status": "active",
"relationship": {
"type": "runs_on",
"direction": "outgoing",
"properties": null
},
"depth": 1,
"attributes": {
"ip_addresses": ["10.0.1.67"],
"hostnames": ["worker-node-01"],
"fqdns": [],
"scope_label": "production-cluster",
"type_specific": {}
},
"restricted": false
}
],
"descendants": [],
"inherited_attributes": {
"network": {
"value": {
"ip_addresses": ["10.0.1.67", "10.244.0.15"],
"fqdns": ["worker-node-01.example.com"],
"hostnames": ["worker-node-01"]
},
"sources": {
"10.0.1.67": {
"ci_id": "660e8400-...",
"ci_type": "kubernetes.node",
"name": "worker-node-01"
}
}
},
"hardware": {
"value": {
"serial": "SN-ABC123",
"cpu_cores": 4,
"memory_gb": 6
},
"sources": {
"serial": {
"ci_id": "770e8400-...",
"ci_type": "netbox.device",
"name": "host-01"
}
}
}
}
}Error Responses
| Status | Condition | Response |
|---|---|---|
| 404 | CI not found | {"detail": "Configuration item not found"} |
| 400 / 422 | Invalid UUID or parameters | Validation error details |
RBAC Behavior
Lineage respects data scope restrictions. If a node in the lineage chain is outside the caller's data scope, it appears with restricted: true, its name replaced with [Restricted], and its attributes cleared. Restricted nodes are also excluded from inherited attribute collection.
Tips and Common Patterns
Start from the workload for troubleshooting. When investigating an issue, begin at the application-tier CI (pod, deployment, service) and read the ancestor chain downward. This traces the exact infrastructure path and often reveals the failing layer.
Expand the tree for branching stacks. The compact strip shows a single primary chain. When a physical node hosts multiple VMs, each running different workloads, the expanded tree shows the full fan-out, and same-type siblings collapse into an N× type group you can expand so a host with dozens of pods stays readable.
Tune depth for your use case. The default depth of 5 covers most stacks (pod → node → VM → host → rack). Increase to 8-10 when you need site-level context. Use depth 1-2 for a quick check of immediate neighbors without the full traversal.
Filter relationship types for focused views. Use relationship_types=runs_on to see only the compute hosting chain, filtering out storage and network relationships that may add noise.
Use inherited attributes for network debugging. When a pod's own IP is a cluster-internal address, inherited network attributes surface the node's external IPs, FQDNs, and hostnames, useful for correlating with external monitoring or firewall rules.
Cross-source lineage is automatic. Lineage chains naturally span source boundaries when correlation rules have created cross-system relationships. A chain might flow from kubernetes.pod (Kubernetes collector) through proxmox.vm (Proxmox collector) to netbox.device (Netbox collector) without any special configuration.
Related Documentation
- Correlation Engine: Creates the cross-system relationships that lineage chains traverse
- Criticality: Criticality scoring that considers infrastructure dependencies
- API Reference: Complete API endpoint documentation
- Architecture: System design and relationship model