Skip to content

Add high-cardinality telemetry protection: label budgets, redaction and log sampling (#214) - #382

Merged
github-actions[bot] merged 2 commits into
TRELLIS-STELLAR:mainfrom
OkeyAmy:feat/214-telemetry-protection
Oct 18, 2026
Merged

github-actions[bot] merged 2 commits into
TRELLIS-STELLAR:mainfrom
OkeyAmy:feat/214-telemetry-protection

Conversation

@OkeyAmy

@OkeyAmy OkeyAmy commented Oct 18, 2026

Copy link
Copy Markdown
Contributor

What

Closes #214 with a small, well-tested vertical slice: a TelemetryGuard sitting between callers and TelemetryService's telemetry sinks.

  • Unsafe labels are rejected as-is — every metric label value is normalized (tokens/secrets → __sensitive__, UUID/email/address/hash identifiers → placeholders, charset bounded, 64-char cap) and counted against a per metric :: label cardinality budget (default 128). Values beyond the budget collapse into __over_budget__; observations are never dropped, so totals stay exact. Every collapse increments trellis_telemetry_label_rejections_total{metric,label,reason} so operators can find the leaking caller.
  • Redaction on the log path — the serialized log line runs through the existing sensitive-data mask with length-capped free-text fields and a 2 KB metadata cap; the event returned to callers keeps its original values.
  • Deterministic sampling — non-failure log lines are sampled at TELEMETRY_LOG_SAMPLE_RATE (default 1 = previous behaviour); failures always emit; suppressed lines are counted in trellis_telemetry_log_events_suppressed_total{kind}. Metrics series are never sampled.

Why

recordOperation labels come from caller-influenced sources — the @Telemetry decorator reads actor_type from token claims and error_code from thrown errors. One Prometheus series per distinct value means unbounded memory growth and unusable dashboards under abusive input; logs had no volume or payload control at all.

Impact

  • New: src/observability/telemetry-guard.ts + spec (18 tests)
  • Changed: src/observability/telemetry.service.ts (guard wiring, sampled/capped log emission, guarded funnel logging) + spec (6 new integration tests; all 15 pre-existing tests unchanged and green)
  • New: docs/TELEMETRY_PROTECTION.md — configuration, operational edge cases, failure modes, rollback/recovery

Compatibility

Public APIs and event schemas are unchanged. Default configuration (budget 128, rate 1) is behaviour-compatible: legitimate operation/actor/error values pass through verbatim, so existing dashboards and alerts keep matching. Gauges are deliberately not routed through the guard (stateful budget vs inc/dec pairing) — documented as a follow-up, along with the per-request timing log line.

Verification

  • npx jest src/observability/telemetry.service.spec.ts src/observability/telemetry-guard.spec.ts → 39/39 green, repeated ×3
  • Observability directory plus external consumers (submission-verifier, reconciliation, monitoring): green except two suites that fail identically on upstream/main (missing enums/sensitive-action-event-type.enum — pre-existing baseline red, verified via git stash)
  • npx tsc --noEmit filtered to observability/ paths → clean (repo baseline has pre-existing errors elsewhere)

…sive volume (TRELLIS-STELLAR#214)

TelemetryGuard rejects unsafe label values as-is before they reach
Prometheus: identifiers/tokens collapse to placeholders, charset and
length are bounded, and a per metric::label cardinality budget
(default 128) aggregates new values into __over_budget__ so totals stay
exact. Rejections are counted in a bounded counter
(trellis_telemetry_label_rejections_total{metric,label,reason}).

Log lines run through the sensitive-data mask with length-capped fields
and a metadata size cap (originals untouched on returned events), and
non-failure lines are deterministically sampled at
TELEMETRY_LOG_SAMPLE_RATE (default 1 = previous behaviour); failures
always emit, suppressed lines are counted, metrics are never sampled.
Log serialization failures degrade to a warning instead of throwing.
@drips-wave

drips-wave Bot commented Oct 18, 2026

Copy link
Copy Markdown

@OkeyAmy Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@github-actions

Copy link
Copy Markdown

Code Review & Auto-Merge — @dorismaduegbunam 🚀

Thank you @OkeyAmy for your contribution!

Verified code changes and repository requirements. Merging pull request.

@github-actions
github-actions Bot merged commit 77ae9c8 into TRELLIS-STELLAR:main Oct 18, 2026
1 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Trellis API: Add high-cardinality telemetry protection with redaction and sampling rules

1 participant