Skip to content

feat: add PostHog telemetry events for secrets management features#5730

Merged
0xArshdeep merged 13 commits intomainfrom
devin/1773710913-add-posthog-telemetry-events
Mar 19, 2026
Merged

feat: add PostHog telemetry events for secrets management features#5730
0xArshdeep merged 13 commits intomainfrom
devin/1773710913-add-posthog-telemetry-events

Conversation

@devin-ai-integration
Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration bot commented Mar 17, 2026

Context

Adds PostHog telemetry tracking for 8 secrets management features that previously had audit log coverage but no product analytics instrumentation. These events were identified from a gap analysis of the secrets management surface area, filtered to only high-signal, user-initiated actions.

New events:

Event Route Handler(s) Signal
Secret Folder Created v2/secret-folder-router, ee/v1/pit-router (/batch/commit) Adoption depth
Secret Import Created v2/secret-import-router Architecture maturity
Secret Shared v1/secret-sharing-router Virality / top-of-funnel
Shared Secret Viewed v1/secret-sharing-router Viral reach
Secret Rollback Performed ee/v1/pit-router Incident/compliance signal
Webhook Created v1/webhook-router External automation lock-in
Secret Reminder Created v4/secret-router, v1/reminder-routers/secret-reminder-router Security hygiene
Environment Created v1/project-env-router Growth trajectory

All events follow the existing pattern: fire after the audit log call, using getTelemetryDistinctId(req) and req.permission.orgId.

Updates since last revision

Addressed reviewer feedback from @carlosmonastyrski:

  1. SecretReminderCreated now covers one-time reminders. Added telemetry to the dedicated reminder router (secret-reminder-router.ts), which handles reminders set via nextReminderDate. The event includes an isOneTime boolean to distinguish one-time vs. recurring reminders. The > 0 guard in the v4 secret-router remains correct for that endpoint (recurring reminders only).
  2. SecretFolderCreated now fires from PIT /batch/commit. The commit endpoint creates folders in bulk but previously had no folder telemetry. Events now fire via Promise.all for each folder in changes.folders.create.
  3. TSecretReminderCreatedEvent type updated. reminderRepeatDays is now optional (one-time reminders don't have it); isOneTime flag added; redundant projectId/environment/secretPath removed (available via secretId lookup).
  4. TSecretFolderCreatedEvent type updated. folderId/folderPath made optional, folderName added — the PIT commit endpoint doesn't return created folder IDs.

Previous rounds addressed Greptile review feedback:

  1. SharedSecretViewed fires for public (no-org) secrets. Moved telemetry outside the if (sharedSecret.orgId) guard; organizationId uses ?? undefined for the null case.
  2. SecretReminderCreated PATCH guard tightened. Uses !== undefined && !== null so it only fires when the client explicitly includes secretReminderRepeatDays.
  3. organizationId naming follows the newer convention from TSecretRequestCreatedEvent / TSecretRequestDeletedEvent.
  4. WebhookType and SecretSharingAccessType enum precision. type property uses WebhookType instead of string; accessType uses SecretSharingAccessType with a cast for the DB value.
  5. SecretShared tracked on POST /public endpoint. Unauthenticated shared-secret creation now emits telemetry with anonymous-${sharedSecret.id} as distinctId and no organizationId.
  6. SecretReminderCreated > 0 guard added. Prevents the event from firing when secretReminderRepeatDays is 0, matching the service layer's truthy check that actually creates the reminder.
  7. Removed duplicated organizationId from event properties. The top-level organizationId field on TPostHogEvent already drives postHog.groupIdentify; the duplicate inside properties was unnecessary.

Steps to verify the change

  1. Confirm backend type check passes (npm run type:check — no new errors introduced)
  2. Review that each sendPostHogEvents call is placed after the corresponding createAuditLog call
  3. Verify the property types in telemetry-types.ts match what's passed in route handlers

Items for reviewer attention

  • SecretReminderCreated fires on both create (POST) and update (PATCH) in v4/secret-router.ts. The guard checks > 0 and !== undefined && !== null, but it cannot diff against the previous reminder value since updateSecretRaw returns the already-updated secret. Re-sending the same reminder value alongside other changes will still fire the event.
  • SharedSecretViewed uses anonymous-${req.params.id} as distinctId for unauthenticated viewers. This creates anonymous PostHog profiles keyed by shared secret ID.
  • sharedSecret.accessType as SecretSharingAccessType — type cast from the DB string value. If the DB contains a value outside the enum, this would silently pass at runtime.
  • PIT /batch/commit tracks folder creation but not secret creation. Carlos's comment mentioned both resources — verify whether SecretCreated telemetry is also needed for changes.secrets.create in this endpoint.
  • TSecretFolderCreatedEvent has all optional identifier fields (folderPath, folderId, folderName). The folder router sends folderPath + folderId; the PIT commit endpoint sends folderName. No call sends all three. Verify this is acceptable vs. requiring at least one.

Type

  • Fix
  • Feature
  • Improvement
  • Breaking
  • Docs
  • Chore

Checklist

Link to Devin session: https://app.devin.ai/sessions/bfcfbd16cf444133b7a4cbdfdbd815aa
Requested by: @0xArshdeep


Open with Devin

Add 8 new PostHog event types for tracking adoption and usage of:
- Secret folder creation
- Secret import creation
- Secret sharing (create + view)
- Webhook creation
- PIT rollback performed
- Secret reminder creation
- Environment creation

Co-Authored-By: arsh <[email protected]>
@devin-ai-integration
Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

@maidul98
Copy link
Copy Markdown
Collaborator

maidul98 commented Mar 17, 2026

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

Copy link
Copy Markdown
Contributor Author

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 3 additional findings.

Open in Devin Review

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 17, 2026

Greptile Summary

This PR adds PostHog telemetry instrumentation for 8 previously un-tracked secrets management actions: SecretFolderCreated, SecretImportCreated, SecretShared, SharedSecretViewed, SecretRollbackPerformed, WebhookCreated, SecretReminderCreated, and EnvironmentCreated. All events follow the established pattern of firing after the createAuditLog call, using getTelemetryDistinctId(req) and req.permission.orgId. After six rounds of review, all previously flagged issues have been addressed.

Key implementation details:

  • SharedSecretViewed correctly fires outside the orgId guard, covering both org-scoped and public shared secrets, with anonymous-${req.params.id} as the distinct ID for unauthenticated viewers
  • SecretShared is tracked on both the authenticated POST / and unauthenticated POST /public endpoints, with an anonymous distinct ID on the public path
  • SecretReminderCreated uses a !== undefined && !== null && > 0 guard on both POST and PATCH handlers, correctly matching the service layer's truthy check that actually creates reminders
  • TWebhookCreatedEvent.properties.type uses the WebhookType enum, and TSharedSecretViewedEvent/TSecretSharedEvent use SecretSharingAccessType — both previously flagged and now fixed
  • Known acknowledged trade-off: SecretReminderCreated can fire on PATCH updates where the same reminder value is re-sent, since there is no diff against the existing value available after updateSecretRaw returns the updated secret

Confidence Score: 4/5

  • Safe to merge — changes are additive telemetry only with no impact on business logic, API contracts, or data access control.
  • All 8 event additions follow the established pattern and have been thoroughly iterated through six prior review rounds. No new bugs or security concerns were identified. The one remaining known trade-off (reminder event firing on unmodified PATCH updates) is explicitly acknowledged in the PR description and is an inherent limitation of the current service API. Score of 4 rather than 5 reflects these minor acknowledged edge cases rather than any blocking issue.
  • No files require special attention. The most nuanced files are secret-sharing-router.ts (anonymous telemetry paths) and secret-router.ts (reminder create/update semantics), but both have been carefully reviewed and iterated upon.

Important Files Changed

Filename Overview
backend/src/services/telemetry/telemetry-types.ts Adds 8 new event types and corresponding TypeScript type definitions. Correct use of WebhookType enum and SecretSharingAccessType enum (previously flagged, now fixed). Types are well-structured and consistent with existing patterns.
backend/src/server/routes/v1/secret-sharing-router.ts Adds SecretShared (both public and authenticated paths) and SharedSecretViewed telemetry. SharedSecretViewed correctly fires outside the orgId guard for all views including public secrets. Anonymous distinct IDs used for unauthenticated paths as acknowledged in PR description.
backend/src/server/routes/v4/secret-router.ts Adds SecretReminderCreated to both POST and PATCH handlers. > 0 guard correctly aligns with service layer's truthy check. Event fires on updates with an unchanged reminder value (acknowledged limitation in PR description).
backend/src/ee/routes/v1/pit-router.ts Adds SecretRollbackPerformed telemetry after the audit log call. Uses `result.totalChanges
backend/src/server/routes/v1/webhook-router.ts Adds WebhookCreated telemetry. Uses req.body.type which always resolves to a valid WebhookType enum value via the Zod schema default (WebhookType.GENERAL). Clean implementation.
backend/src/server/routes/v2/secret-folder-router.ts Adds SecretFolderCreated telemetry cleanly after the audit log. Properties use the correct returned folder.id rather than re-deriving from request body.
backend/src/server/routes/v2/secret-import-router.ts Adds SecretImportCreated telemetry with both import source and destination metadata. Uses the returned secretImport object for importEnv.slug, which is the server-validated value.
backend/src/server/routes/v1/project-env-router.ts Adds EnvironmentCreated telemetry. Uses the returned environment object for both name and slug, which is the correct server-authoritative approach.

Last reviewed commit: 05db8b2

greptile-apps[bot]

This comment was marked as resolved.

@0xArshdeep
Copy link
Copy Markdown
Contributor

@greptileai

greptile-apps[bot]

This comment was marked as resolved.

@0xArshdeep
Copy link
Copy Markdown
Contributor

@greptileai

greptile-apps[bot]

This comment was marked as resolved.

@devin-ai-integration
Copy link
Copy Markdown
Contributor Author

Addressed latest Greptile comment in 8bbaba4: Updated both TSecretSharedEvent and TSharedSecretViewedEvent to use SecretSharingAccessType enum instead of string for accessType, consistent with the WebhookType fix applied earlier. Import added from @app/lib/types.

@0xArshdeep
Copy link
Copy Markdown
Contributor

@greptileai

greptile-apps[bot]

This comment was marked as resolved.

@devin-ai-integration
Copy link
Copy Markdown
Contributor Author

Addressed latest Greptile comment (SecretShared not tracked for /public endpoint) in bf0822d:

  • Added SecretShared telemetry to the POST /public handler using the same anonymous identity pattern (anonymous-${sharedSecret.id}) as SharedSecretViewed
  • Access type hardcoded to SecretSharingAccessType.Anyone since that's always the case for public shares
  • Made organizationId optional in TSecretSharedEvent since public shares have no org

@0xArshdeep
Copy link
Copy Markdown
Contributor

@greptileai

greptile-apps[bot]

This comment was marked as resolved.

@0xArshdeep
Copy link
Copy Markdown
Contributor

@greptileai

greptile-apps[bot]

This comment was marked as resolved.

@0xArshdeep
Copy link
Copy Markdown
Contributor

@greptileai

devin-ai-integration bot and others added 3 commits March 17, 2026 21:39
…endpoint

- Add SecretReminderCreated telemetry to secret-reminder-router.ts POST handler
  covering one-time reminders (via nextReminderDate) and recurring reminders
- Add SecretFolderCreated telemetry to PIT /batch/commit endpoint for bulk
  folder creation
- Update TSecretReminderCreatedEvent type: add isOneTime flag, make
  reminderRepeatDays optional, remove redundant location fields
- Update TSecretFolderCreatedEvent type: make folderId/folderPath optional,
  add folderName for PIT commit context
- Update v4 secret-router to match new type shape

Co-Authored-By: arsh <[email protected]>
@0xArshdeep 0xArshdeep merged commit 20a20f3 into main Mar 19, 2026
12 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.

3 participants