Task · GCI-0018.01

Publish unbounded-cardinality label names as a risk finding, over the payload the collector already holds

Description

The unbounded-cardinality half of GCI-0018, commissioned separately because it needs no new source contract. The identity-bearing half stays parked on the parent.

The input already exists

collector/sources/dataplane.py cardinality() calls Mimir /api/prom/api/v1/cardinality/label_names per stack and returns top_labels: a list of {label, values} where label is a label NAME and values is a count. No label value is fetched, and that file’s own comment records the privacy decision - offender names go to Loki and S3 and never become a metric label.

collector/pillars/cost.py cost_cardinality_outliers consumes only top_labels[0] as Worst label and discards the rest. The remaining names are already in the scan envelope and are thrown away at view time.

Wave 1 parked the parent on a finding that no key-only label-name payload existed. That finding was wrong; it checked only collector/sources/signal_inventory.py. See the parent’s correction note.

What this task must NOT claim

The payload is Mimir only, and it is the top N by cardinality rather than a complete label-name set. So:

Absolute rules, inherited from the parent

Where it lands

Pillar E, risk and hygiene, beside the existing public-dashboard and access-policy findings.

New output:

The pattern set

Generic unbounded-cardinality label-name patterns, none derived from any one estate:

uuid, guid, id
trace_id, traceid, span_id, spanid, request_id, requestid, correlation_id
run_id, job_id, build_id, task_id, container_id, pod_template_hash, pid
timestamp, epoch, time, datetime
url, path, full_path, query, querystring, endpoint, route, uri

Classify endpoint, route and path as possible rather than high-confidence: a parameterised route label is legitimate and common.

Acceptance Criteria

Definition of Done

Implementation Plan

Lane 1 implements the versioned generic pattern data, pure key-only classifier, risk-pillar view composition, and focused tests within its frozen ownership. Root then wires the bounded catalogue metrics, hydration ownership and dependencies, Loki publication, scan envelope, and dashboard row; an independent security lane reviews the integrated privacy boundary before the final gate.

Final Summary

Delivered at a8c745bab901fbd0c4ae85202b791ccd70ef6557. The collector classifies only the existing Mimir top-20 label-name payload with a versioned generic pattern set, publishes the measured view and separate bounded high-confidence and possible counts, forwards identity-bearing detail only in S3 and Loki bodies, and adds a Mimir-only risk dashboard row with its measured-stack denominator. No source read or remediation path was added. Independent security review found no privacy or cardinality issue. CodeRabbit reviewed all changed files; its valid dashboard-isolation and budget-record findings were fixed, while its remaining mutable-test-fixture style suggestion was left because the fixture is never mutated and this repository has no Ruff gate. Exact-SHA just check: 1480 passed, 2 existing skips, 7273 subtests; peak RSS 232.7 MiB; both Terraform roots valid; customer identifiers clean.

View the source file on GitHub