Part of #74. Deferred from PR #111 (called out in its description).
The JS and Node metric paths both run a defensive filter (isForbiddenMetric, shared regex list in src/sentry-scrub.ts + backend/before-send.js) that drops any metric emission carrying a forbidden attribute (raw device model, project id, coordinate-shaped values, etc.).
The Kotlin and Swift layers do not have an equivalent: SentryFgsBridge.countMetric (Android) and SentryNativeBridge.countMetric (iOS) forward attributes to the Sentry SDK unfiltered. Today the only native metric is comapeo.app.exit, whose attributes are low-cardinality by construction, so exposure is minimal — but any future native metric would ship without the belt-and-suspenders check the other two layers have.
Done when
Part of #74. Deferred from PR #111 (called out in its description).
The JS and Node metric paths both run a defensive filter (
isForbiddenMetric, shared regex list insrc/sentry-scrub.ts+backend/before-send.js) that drops any metric emission carrying a forbidden attribute (raw device model, project id, coordinate-shaped values, etc.).The Kotlin and Swift layers do not have an equivalent:
SentryFgsBridge.countMetric(Android) andSentryNativeBridge.countMetric(iOS) forward attributes to the Sentry SDK unfiltered. Today the only native metric iscomapeo.app.exit, whose attributes are low-cardinality by construction, so exposure is minimal — but any future native metric would ship without the belt-and-suspenders check the other two layers have.Done when
Sentry.metrics()/SentrySDK.metricscalls on both platforms, mirroring the JS list (the list is short and changes rarely; a hand-mirrored copy with a pointer comment matches how the event scrubbers are kept in sync)