Overview
The analytics layer answers the questions you actually want answered:
- What breaks if this connector group dies?
- Which policies overlap or contradict each other?
- Which segments have nobody covering them?
- Which domains are duplicated across segments and is the action consistent?
- Which connector groups are doing all the work?
- Which SCIM groups have the keys to everything?
Six reports. All computed from the in-memory index. No SDK calls past the initial fetch.
The reports
| Report | Endpoint | Answers |
|---|---|---|
| Blast radius | GET /api/v1/analytics/blast-radius?id=&type= | ”If this dies, what fails?” |
| Policy shadows | GET /api/v1/analytics/policy-shadows | ”Which rules step on each other?” |
| Orphan clusters | GET /api/v1/analytics/orphan-clusters | ”Which segment groups are dead weight?” |
| Domain overlaps | GET /api/v1/analytics/domain-overlaps | ”Where does the same hostname appear twice?” |
| Connector load | GET /api/v1/analytics/connector-load | ”Which connector groups carry the most?” |
| SCIM reach | GET /api/v1/analytics/scim-reach | ”Which user groups have the broadest access?” |
Common shape
Most reports share NamedRef:
type NamedRef struct { ID string `json:"id"` Name string `json:"name"`}When a name cannot be resolved (deleted or stale reference), the ID is used as the name so the row is still useful. We never silently drop entries.
When to recompute
The reports run on every request against whatever the index has. The index is built once per process (cold-start), so to refresh against new ZPA state you currently restart the binary or container. Daemon-mode periodic refresh is on the roadmap; see architecture.