Security & data handling¶
This page summarizes graph2otel's operational security posture — what data it handles,
where that data goes, and the configuration levers available to reduce exposure. For the
canonical, authoritative version (kept alongside the code, not duplicated content) plus
vulnerability reporting instructions, see
SECURITY.md in the
repo.
Reporting a vulnerability¶
Report privately via GitHub's private vulnerability reporting — do not open a public issue for a security bug:
https://github.com/rknightion/graph2otel/security/advisories/new
See SECURITY.md for the full disclosure process, timelines, and scope.
Telemetry payload sensitivity¶
graph2otel exports identity and device management data from every tenant it's configured against. Depending on which collectors are enabled, that includes user principal names / email addresses and user object IDs; device names, serial numbers, IMEIs, and other hardware identifiers; sign-in IP addresses, geographic locations, and client application identifiers; directory/group/role membership and app credential metadata; device compliance and configuration policy state; opaque correlation/request/ incident/job/cycle/change identifiers; certificate identifiers (thumbprints, serial numbers, subject/issuer names); security alert and risk-detection details; and sign-in/ provisioning source/target identity IDs and display names.
This list is confirmed against the actual collector emission by the pre-1.0 PII & cardinality audit — see docs/pii-cardinality-audit.md — not just design intent. That audit also confirmed the boundary rule below holds in code: all of the above per-entity data is confined to the logs pipeline as structured attributes; no metric label anywhere is keyed by a user, device, or per-event identity. One deliberate protection worth calling out: the Intune audit-event stream emits the names of changed properties but never their old/new values, which can carry credentials, certificates, or PII.
All of this is exported over OTLP to the configured backend (for example Grafana Cloud). Treat the OTLP backend as a trusted data sink — anyone with read access to it can see this metadata for every configured tenant. Scope backend credentials and Graph API app registration permissions accordingly.
The cardinality boundary rule¶
High-cardinality, per-entity data (per-user, per-device, per-sign-in event data — UPNs, device IDs, IP addresses, correlation IDs) is never attached as an OTEL metric label. That data belongs in the logs pipeline (sign-in logs, audit logs, provisioning logs, Intune audit events) as structured log attributes, not as metric label dimensions. Metrics carry only bounded, tenant-shaped aggregates — counts by compliance state, by operating system, by policy, by risk level — never a metric series keyed by user or device identity. This is a hard modeling rule, not a tuning knob: a metric series whose cardinality grows with tenant size is a bug, not a feature request. See Signals for how this maps onto the emitted namespaces.
Levers to reduce exposure¶
- Enable only the collectors you need per tenant (
collectors:in Configuration) — a disabled collector makes zero Graph API calls and exports zero data for that domain. - Use least-privilege, read-only Graph API application permissions — never grant write
scopes beyond what the Intune reports export API unavoidably requires for that one
feature. Run
graph2otel checkto confirm your app registration's grants match what your enabled collectors actually need before your first real poll — see Getting Started. - Where a domain has both a snapshot/aggregate signal and a raw per-entity export, prefer the aggregate; per-entity detail should be pulled on demand, not mirrored wholesale into metric label sets.
Secrets handling¶
- Auth material (client secret / client certificate path) is supplied via
environment variables consumed by
azidentity.DefaultAzureCredential(AZURE_TENANT_ID,AZURE_CLIENT_ID,AZURE_CLIENT_SECRET, orAZURE_CLIENT_CERTIFICATE_PATH) — never as literal values in YAML. Thetenantslist in config only carriestenant_id/client_idand per-domain collector toggles.config.local.yamland.envare gitignored for this reason. - Secrets are never logged. A code path that logs a secret or a full OAuth token is a vulnerability — report it per the process above.
Related pages¶
- docs/pii-cardinality-audit.md — the collector-by-collector audit that confirmed the boundary rule above holds against actual emitted telemetry.
- docs/scale-validation.md — validation of the throttle limiters and watermark/checkpoint durability under load, the mechanisms this project's scale claims depend on.
License¶
graph2otel is licensed under the GNU Affero General Public License v3.0 only
(AGPL-3.0-only) — see
LICENSE.