Compare commits

...
Author SHA1 Message Date
nighttrek f59ef0c43c refactor(telemetry): Remove email from user identification
To enhance user privacy and avoid sending unnecessary Personally Identifiable Information (PII), the user's email address is no longer included in telemetry identification events.

The `TelemetryService` now strips the `email` property from the user information object before passing it to the various telemetry providers.

This change includes:
- Introducing an `AnonymousClineAccountUserInfo` type that omits the `email` field.
- Updating the `ITelemetryProvider` interface and its implementations (PostHog, OpenTelemetry) to use this new anonymous type for user identification calls.
2025-11-03 13:03:40 -08:00
4 changed files with 21 additions and 10 deletions
+4 -1
View File
@@ -393,10 +393,13 @@ export class TelemetryService {
...this.telemetryMetadata,
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { email, ...anonymousUserInfo } = userInfo
// Update all providers with error isolation
this.providers.forEach((provider) => {
try {
provider.identifyUser(userInfo, propertiesWithMetadata)
provider.identifyUser(anonymousUserInfo, propertiesWithMetadata)
} catch (error) {
console.error(`[TelemetryService] Provider failed for user identification:`, error)
}
@@ -5,6 +5,8 @@
import type { ClineAccountUserInfo } from "../../auth/AuthService"
export type AnonymousClineAccountUserInfo = Omit<ClineAccountUserInfo, "email">
/**
* JSON-serializable primitive types for telemetry properties
*/
@@ -68,7 +70,7 @@ export interface ITelemetryProvider {
* @param userInfo The user's information
* @param properties Optional additional JSON-serializable properties
*/
identifyUser(userInfo: ClineAccountUserInfo, properties?: TelemetryProperties): void
identifyUser(userInfo: AnonymousClineAccountUserInfo, properties?: TelemetryProperties): void
/**
* Update telemetry opt-in/out status
@@ -4,8 +4,12 @@ import * as vscode from "vscode"
import { HostProvider } from "@/hosts/host-provider"
import { getDistinctId, setDistinctId } from "@/services/logging/distinctId"
import { Setting } from "@/shared/proto/index.host"
import type { ClineAccountUserInfo } from "../../../auth/AuthService"
import type { ITelemetryProvider, TelemetryProperties, TelemetrySettings } from "../ITelemetryProvider"
import type {
AnonymousClineAccountUserInfo,
ITelemetryProvider,
TelemetryProperties,
TelemetrySettings,
} from "../ITelemetryProvider"
import { OpenTelemetryClientProvider } from "./OpenTelemetryClientProvider"
/**
@@ -113,14 +117,13 @@ export class OpenTelemetryTelemetryProvider implements ITelemetryProvider {
}
}
public identifyUser(userInfo: ClineAccountUserInfo, properties: TelemetryProperties = {}): void {
public identifyUser(userInfo: AnonymousClineAccountUserInfo, properties: TelemetryProperties = {}): void {
const distinctId = getDistinctId()
// Only identify user if telemetry is enabled and user ID is different than the currently set distinct ID
if (this.isEnabled() && userInfo && userInfo?.id !== distinctId) {
// Store user attributes for future events
this.userAttributes = {
user_id: userInfo.id,
user_email: userInfo.email || "",
user_name: userInfo.displayName || "",
...this.flattenProperties(properties),
}
@@ -4,8 +4,12 @@ import { HostProvider } from "@/hosts/host-provider"
import { getDistinctId, setDistinctId } from "@/services/logging/distinctId"
import { Setting } from "@/shared/proto/index.host"
import { posthogConfig } from "../../../../shared/services/config/posthog-config"
import type { ClineAccountUserInfo } from "../../../auth/AuthService"
import type { ITelemetryProvider, TelemetryProperties, TelemetrySettings } from "../ITelemetryProvider"
import type {
AnonymousClineAccountUserInfo,
ITelemetryProvider,
TelemetryProperties,
TelemetrySettings,
} from "../ITelemetryProvider"
/**
* PostHog implementation of the telemetry provider interface
* Handles PostHog-specific analytics tracking
@@ -90,7 +94,7 @@ export class PostHogTelemetryProvider implements ITelemetryProvider {
})
}
public identifyUser(userInfo: ClineAccountUserInfo, properties: TelemetryProperties = {}): void {
public identifyUser(userInfo: AnonymousClineAccountUserInfo, properties: TelemetryProperties = {}): void {
const distinctId = getDistinctId()
// Only identify user if telemetry is enabled and user ID is different than the currently set distinct ID
if (this.isEnabled() && userInfo && userInfo?.id !== distinctId) {
@@ -98,7 +102,6 @@ export class PostHogTelemetryProvider implements ITelemetryProvider {
distinctId: userInfo.id,
properties: {
uuid: userInfo.id,
email: userInfo.email,
name: userInfo.displayName,
...properties,
alias: distinctId,