Prometheus doesn’t have a built-in mechanism to scrub Personally Identifiable Information (PII) from your metrics, which means you’re responsible for ensuring compliance before data even hits your Prometheus server.

Let’s watch a typical metric flow and see where the problem lies. Imagine you’re tracking user activity with a metric like this:

user_login_success{user_id="alice123", ip_address="192.168.1.100", country="US"} 1

Here, user_id and ip_address are PII. If this metric is scraped by Prometheus and stored, you’ve just logged sensitive user data. The challenge is that Prometheus’s primary function is to collect and store metrics as they are, not to sanitize them.

This means the responsibility for PII scrubbing falls on the application emitting the metrics, or on an intermediary agent before the metrics reach Prometheus.

Common Causes and Solutions for PII in Metrics:

  1. Directly Embedding PII in Metric Labels:

    • Diagnosis: Review your application code where metrics are generated. Look for instances where user_id, email, ip_address, or any other unique user identifier is used as a label value.
    • Cause: Developers might, for simplicity or debugging, directly add identifiers to labels.
    • Fix: Replace PII labels with anonymized or pseudonymous identifiers. For example, instead of user_id="alice123", use user_session_id="a7f3b9d1-e8c2-4a0d-8b1e-5c9a2d6f0b4e" (a UUID generated per session) or a salted hash of the user_id.
    • Why it works: Prometheus will store the anonymized ID, which cannot be directly linked back to the individual without the original salt or mapping.
  2. Including PII in Metric Names or Values:

    • Diagnosis: Search your codebase for metric names that might inadvertently include PII (e.g., user_alice123_login_count) or metric values that are directly set to PII.
    • Cause: Less common than labels, but can occur if metric generation is highly dynamic and not properly constrained.
    • Fix: Ensure metric names are generic and stable. If a value needs to be logged, consider logging it to a separate, secure audit log system instead of embedding it in a Prometheus metric. If it must be a metric, anonymize it using the same techniques as for labels.
    • Why it works: Standardizing metric names prevents dynamic PII inclusion, and anonymizing values ensures they are not directly identifiable.
  3. Third-Party Libraries Exposing PII:

    • Diagnosis: If you’re using a metrics library (e.g., prometheus_client for Python, micrometer for Java), examine its default behavior. Some libraries might auto-register metrics that inadvertently include system-level identifiers that could be considered PII in certain contexts.
    • Cause: Libraries might expose internal IDs or hostnames that could, when combined with other data, identify a specific user or environment.
    • Fix: Configure your metrics library to exclude specific labels or metrics known to contain PII. For instance, in Python’s prometheus_client, you might use REGISTRY.unregister(metric) or carefully construct metrics to avoid default problematic labels.
    • Why it works: By explicitly removing or avoiding the problematic metrics/labels at the source, they never reach Prometheus.
  4. Exposing Sensitive Data via Service Discovery:

    • Diagnosis: If you use Prometheus’s service discovery mechanisms (e.g., Consul, Kubernetes SD), check the metadata or labels that service discovery injects into targets.
    • Cause: Service discovery might add labels like __meta_kubernetes_pod_annotation_prometheus_io_some_sensitive_data that can propagate to your metrics.
    • Fix: Configure Prometheus scrape configurations to relabel_configs that drop or modify these meta-labels before they are used as metric labels. For example:
      relabel_configs:
        - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_sensitive]
          action: drop
      
    • Why it works: Relabeling rules allow Prometheus to manipulate labels during the scraping process, before data is stored, effectively removing sensitive metadata.
  5. Unsanitized Data in textfile Collector:

    • Diagnosis: If you use the node_exporter’s textfile collector to pull metrics from custom files, inspect the contents of those files.
    • Cause: Scripts or processes writing to these files might not be sanitizing their output.
    • Fix: Ensure any script generating .prom files for the textfile collector explicitly scrubs PII from labels or metric values before writing them.
    • Why it works: The textfile collector simply reads and exposes whatever is in the files; sanitization must happen during file creation.
  6. Aggregating Metrics without Anonymization:

    • Diagnosis: Look at your recording rules or alert rules in Prometheus. Are you aggregating metrics that still contain PII?
    • Cause: You might have successfully anonymized individual metrics but then aggregated them in a way that re-introduces identifiability. For example, sum by (user_session_id) is fine, but sum by (original_user_id) would be problematic if original_user_id was still present.
    • Fix: Ensure all aggregation (using sum by, avg by, etc.) is performed on anonymized or pseudonymized labels. Avoid aggregating by any label that could be directly linked to an individual.
    • Why it works: Aggregation preserves the labels it groups by. If those labels are sensitive, the aggregated metric is also sensitive.

After implementing these fixes, the next potential issue you might encounter is understanding the scope of your anonymization. For instance, you might find that while individual user IDs are gone, patterns in aggregated metrics (e.g., login times, geographic distribution) could still, in conjunction with external data, allow for re-identification, leading to the next challenge of differential privacy.

Want structured learning?

Take the full Observability & Monitoring course →