# massyn/posture architecture

> Architecture diagram of the GitHub repository massyn/posture, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-11-14). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/massyn/posture
- Repository: https://github.com/massyn/posture

## Overview

Posture is a runtime-agnostic continuous-control-monitoring library: callers select a source and resource, collect a complete or paginated pandas DataFrame, and can write results through a pluggable storage backend. Its main stages are source selection, vendor collection, parsing and pagination, and durable output; catalog and CLI capabilities provide discovery and a bulk-extraction interface. The source index supports the shared collector, parser, cache, and storage relationships shown here; many individual collectors and backend implementations were not inspected, so their internal links are omitted.

Main entry points: [`src/posture/base.py`](https://github.com/massyn/posture/blob/main/src/posture/base.py) (Collector lifecycle), [`src/posture/storage/__init__.py`](https://github.com/massyn/posture/blob/main/src/posture/storage/__init__.py) (Storage API), [`src/posture/__init__.py`](https://github.com/massyn/posture/blob/main/src/posture/__init__.py) (CCM API), [`src/posture/collectors`](https://github.com/massyn/posture/tree/main/src/posture/collectors) (Vendor collectors)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_api["Public API"]
  node_ccm["CCM API<br/>[__init__.py]"]
  node_catalog["Source catalog<br/>[__init__.py]"]
end

subgraph group_collection["Collection"]
  node_collector_base["Collector lifecycle<br/>[base.py]"]
  node_collector_registry["Collector registry<br/>[__init__.py]"]
  node_vendor_collectors["Vendor collectors"]
  node_cloudflare["Cloudflare collector<br/>[cloudflare.py]"]
  node_crowdstrike["CrowdStrike collector<br/>[crowdstrike.py]"]
  node_intune["Intune collector<br/>[intune.py]"]
  node_azure_oauth["Azure OAuth<br/>[_azure_oauth.py]"]
  node_qualys_fo["Qualys FO client<br/>[fo_api.py]"]
  node_parser["Record parser<br/>[parse.py]"]
  node_cache["Page spill cache<br/>[_spill.py]"]
  node_exceptions["Error taxonomy<br/>[exceptions.py]"]
end

subgraph group_output["Storage"]
  node_storage_api["Storage API<br/>[__init__.py]"]
  node_storage_base["Storage contracts<br/>[base.py]"]
  node_json_storage["JSON backend<br/>[json.py]"]
  node_storage_backends["Other backends"]
end

subgraph group_interfaces["Interfaces"]
  node_cli["Bulk extract CLI<br/>[cli.py]"]
end

node_caller(("Python caller"))
node_vendor_apis{{"Vendor APIs"}}
node_dataframe["DataFrame result"]

node_caller -->|"selects source"| node_ccm
node_ccm -->|"constructs collector"| node_collector_registry
node_collector_registry -->|"registers sources"| node_vendor_collectors
node_ccm -->|"discovers sources"| node_catalog
node_vendor_collectors -.->|"implements lifecycle"| node_collector_base
node_collector_base -->|"parses records"| node_parser
node_collector_base -->|"spills pages"| node_cache
node_collector_base -->|"uses spill format"| node_json_storage
node_cloudflare -->|"extends"| node_collector_base
node_crowdstrike -->|"extends"| node_collector_base
node_intune -->|"extends"| node_collector_base
node_intune -->|"uses authentication"| node_azure_oauth
node_qualys_fo -.->|"requests XML data"| node_vendor_apis
node_vendor_collectors -.->|"fetches source data"| node_vendor_apis
node_collector_base -->|"returns pages"| node_dataframe
node_caller -->|"opens backend"| node_storage_api
node_storage_api -->|"resolves backends"| node_storage_base
node_storage_api -->|"selects backend"| node_json_storage
node_storage_api -->|"loads backend"| node_storage_backends
node_storage_base -->|"writes frames"| node_dataframe
node_caller -->|"runs extraction"| node_cli
node_cli -->|"collects resources"| node_ccm
node_cli -->|"writes parquet"| node_storage_backends

click node_ccm "https://github.com/massyn/posture/blob/main/src/posture/__init__.py"
click node_catalog "https://github.com/massyn/posture/blob/main/src/posture/__init__.py"
click node_collector_base "https://github.com/massyn/posture/blob/main/src/posture/base.py"
click node_collector_registry "https://github.com/massyn/posture/blob/main/src/posture/__init__.py"
click node_vendor_collectors "https://github.com/massyn/posture/tree/main/src/posture/collectors"
click node_cloudflare "https://github.com/massyn/posture/blob/main/src/posture/collectors/cloudflare.py"
click node_crowdstrike "https://github.com/massyn/posture/blob/main/src/posture/collectors/crowdstrike.py"
click node_intune "https://github.com/massyn/posture/blob/main/src/posture/collectors/intune.py"
click node_azure_oauth "https://github.com/massyn/posture/blob/main/src/posture/collectors/_azure_oauth.py"
click node_qualys_fo "https://github.com/massyn/posture/blob/main/src/posture/collectors/qualys/fo_api.py"
click node_parser "https://github.com/massyn/posture/blob/main/src/posture/parse.py"
click node_cache "https://github.com/massyn/posture/blob/main/src/posture/_spill.py"
click node_exceptions "https://github.com/massyn/posture/blob/main/src/posture/exceptions.py"
click node_storage_api "https://github.com/massyn/posture/blob/main/src/posture/storage/__init__.py"
click node_storage_base "https://github.com/massyn/posture/blob/main/src/posture/storage/base.py"
click node_json_storage "https://github.com/massyn/posture/blob/main/src/posture/storage/json.py"
click node_storage_backends "https://github.com/massyn/posture/tree/main/src/posture/storage"
click node_cli "https://github.com/massyn/posture/blob/main/src/posture/cli.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_ccm,node_catalog toneBlue
class node_collector_base,node_collector_registry,node_vendor_collectors,node_cloudflare,node_crowdstrike,node_intune,node_azure_oauth,node_qualys_fo,node_parser,node_cache,node_exceptions toneAmber
class node_storage_api,node_storage_base,node_json_storage,node_storage_backends,node_vendor_apis toneMint
class node_cli toneRose
class node_caller,node_dataframe toneIndigo
```

## Components

### Public API

- [CCM API](https://github.com/massyn/posture/blob/main/src/posture/__init__.py): `src/posture/__init__.py`
- [Source catalog](https://github.com/massyn/posture/blob/main/src/posture/__init__.py): `src/posture/__init__.py`

### Collection

- [Collector lifecycle](https://github.com/massyn/posture/blob/main/src/posture/base.py): `src/posture/base.py`
- [Collector registry](https://github.com/massyn/posture/blob/main/src/posture/__init__.py): `src/posture/__init__.py`
- [Vendor collectors](https://github.com/massyn/posture/tree/main/src/posture/collectors): `src/posture/collectors`
- [Cloudflare collector](https://github.com/massyn/posture/blob/main/src/posture/collectors/cloudflare.py): `src/posture/collectors/cloudflare.py`
- [CrowdStrike collector](https://github.com/massyn/posture/blob/main/src/posture/collectors/crowdstrike.py): `src/posture/collectors/crowdstrike.py`
- [Intune collector](https://github.com/massyn/posture/blob/main/src/posture/collectors/intune.py): `src/posture/collectors/intune.py`
- [Azure OAuth](https://github.com/massyn/posture/blob/main/src/posture/collectors/_azure_oauth.py): `src/posture/collectors/_azure_oauth.py`
- [Qualys FO client](https://github.com/massyn/posture/blob/main/src/posture/collectors/qualys/fo_api.py): `src/posture/collectors/qualys/fo_api.py`
- [Record parser](https://github.com/massyn/posture/blob/main/src/posture/parse.py): `src/posture/parse.py`
- [Page spill cache](https://github.com/massyn/posture/blob/main/src/posture/_spill.py): `src/posture/_spill.py`
- [Error taxonomy](https://github.com/massyn/posture/blob/main/src/posture/exceptions.py): `src/posture/exceptions.py`

### Storage

- [Storage API](https://github.com/massyn/posture/blob/main/src/posture/storage/__init__.py): `src/posture/storage/__init__.py`
- [Storage contracts](https://github.com/massyn/posture/blob/main/src/posture/storage/base.py): `src/posture/storage/base.py`
- [JSON backend](https://github.com/massyn/posture/blob/main/src/posture/storage/json.py): `src/posture/storage/json.py`
- [Other backends](https://github.com/massyn/posture/tree/main/src/posture/storage): `src/posture/storage`

### Interfaces

- [Bulk extract CLI](https://github.com/massyn/posture/blob/main/src/posture/cli.py): `src/posture/cli.py`

### Other components

- **Python caller**
- **Vendor APIs**
- **DataFrame result**

## Connections

- Python caller → CCM API: selects source
- CCM API → Collector registry: constructs collector (evidence: `src/posture/__init__.py`)
- Collector registry → Vendor collectors: registers sources (evidence: `src/posture/__init__.py`)
- CCM API → Source catalog: discovers sources (evidence: `src/posture/__init__.py`)
- Vendor collectors → Collector lifecycle: implements lifecycle (evidence: `src/posture/collectors/servicenow.py`)
- Collector lifecycle → Record parser: parses records (evidence: `src/posture/base.py`)
- Collector lifecycle → Page spill cache: spills pages (evidence: `src/posture/base.py`)
- Collector lifecycle → JSON backend: uses spill format (evidence: `src/posture/base.py`)
- Cloudflare collector → Collector lifecycle: extends (evidence: `src/posture/collectors/cloudflare.py`)
- CrowdStrike collector → Collector lifecycle: extends (evidence: `src/posture/collectors/crowdstrike.py`)
- Intune collector → Collector lifecycle: extends (evidence: `src/posture/collectors/intune.py`)
- Intune collector → Azure OAuth: uses authentication (evidence: `src/posture/collectors/intune.py`)
- Qualys FO client → Vendor APIs: requests XML data
- Vendor collectors → Vendor APIs: fetches source data
- Collector lifecycle → DataFrame result: returns pages
- Python caller → Storage API: opens backend
- Storage API → Storage contracts: resolves backends (evidence: `src/posture/storage/__init__.py`)
- Storage API → JSON backend: selects backend (evidence: `src/posture/storage/__init__.py`)
- Storage API → Other backends: loads backend (evidence: `src/posture/storage/__init__.py`)
- Storage contracts → DataFrame result: writes frames
- Python caller → Bulk extract CLI: runs extraction (evidence: `src/posture/cli.py`)
- Bulk extract CLI → CCM API: collects resources (evidence: `src/posture/cli.py`)
- Bulk extract CLI → Other backends: writes parquet (evidence: `src/posture/cli.py`)
