Skip to content

Stop setting statsig_stable_id as cookie #65673

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: staging
Choose a base branch
from

Conversation

nicklathe
Copy link
Contributor

@nicklathe nicklathe commented May 5, 2025

📝 PR Overview

This PR updates how we capture signed-out user metrics in order to align with our cookie policy and fix a OneTrust integration issue.

🔍 Background

Previously, we used a statsig_stable_id cookie to uniquely identify user sessions for Statsig. This allowed Statsig to stitch anonymous events (signed-out users) and associate them with a signed-in user later.

However:

  • This broke OneTrust functionality (Jira ticket)
  • It did not comply with our cookie policy, which requires user consent for cookies we set

✅ What this PR changes

To address the above, we now:

  • Store the statsig_stable_id in the server-side session (instead of a cookie)
  • Pass the stable ID to the frontend via a <script> tag, following established conventions

This approach preserves the ability to capture anonymous user metrics without violating cookie restrictions or breaking OneTrust.

Links

Testing story

Deployment strategy

Follow-up work

Privacy

Security

Caching

PR Checklist:

  • Tests provide adequate coverage
  • Privacy and Security impacts have been assessed
  • Code is well-commented
  • New features are translatable or updates will not break translations
  • Relevant documentation has been added or updated
  • User impact is well-understood and desirable
  • Pull Request is labeled appropriately
  • Follow-up work items (including potential tech debt) are tracked and linked

@@ -51,6 +51,7 @@ def link_email
user: existing_user,
event_name: 'lti_user_signin',
metadata: metadata,
session: session,
Copy link
Contributor Author

@nicklathe nicklathe May 6, 2025

Choose a reason for hiding this comment

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

Passing in session here to extract the statsig_stable_id. We are not including a stable ID in a lot of the LTI related event logs, however given that this functionality links a user who launched from an LMS to an existing user account, I think it could be helpful to include a stable ID in the log. Or maybe not 🤷‍♂️

Copy link
Member

Choose a reason for hiding this comment

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

Did you check to make sure there isn't a security or privacy issue with logging the whole session? How big is the session? I think we were having issues for a long time because we were storing too much data in Cookies, so we moved it to the session. Now I'm concerned we are dumping a lot more data into this event. I think it's a little risky for "may be useful". If there is a lot of data, this code could instead be specific about which data from the session is being logged.

Copy link
Contributor Author

@nicklathe nicklathe May 7, 2025

Choose a reason for hiding this comment

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

I think my comment is confusing, I've re-worded it.

It doesn't log the session. We persist the statsig_stable_id in session (in the application_controller.rb above), then inside of Metrics::Events.log_event, we dig it out of the session (link to below). In order to access session from a non-controller (I.e. the Metrics::Events module), we have to pass in session as it doesn't have access to it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Basically what this functionality does is, if you want to include the stable ID in the event you're logging, you pass in the session to the log_event method, and it will extract it. If you don't care about including a stable ID, you can chose to not pass in the session. There are a lot of places where were weren't including the stable ID in the event, because we already have a signed-in user (therefore a user ID). However this account linking step is the case where a user launches from an LMS, and they can chose to continue with creating a new user or link to an existing account. I figured it could be helpful to include the stable ID in this step, which is why I added it.

@nicklathe nicklathe marked this pull request as ready for review May 6, 2025 21:05
Copy link
Member

@daynew daynew left a comment

Choose a reason for hiding this comment

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

Looks good, although I have one blocking concern related to logging the whole session.

@@ -13,15 +11,8 @@ export function getUserType() {
}

export function findOrCreateStableId() {
Copy link
Member

Choose a reason for hiding this comment

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

nit This doesn't "Create" a stable ID anymore.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good call. Actually now I'm wondering if I should have it create a stable ID in the case it doesn't get one passed to it from the backend 🤔

Copy link
Contributor Author

@nicklathe nicklathe May 7, 2025

Choose a reason for hiding this comment

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

Well, except that we wouldn't have anywhere to store it if we created one here (can't use a cookie like before). This would run on each page load and generate a new ID each time, which would not be very "stable". I think I'll just change the name and expect that it will be passed from the backend.

@@ -51,6 +51,7 @@ def link_email
user: existing_user,
event_name: 'lti_user_signin',
metadata: metadata,
session: session,
Copy link
Member

Choose a reason for hiding this comment

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

Did you check to make sure there isn't a security or privacy issue with logging the whole session? How big is the session? I think we were having issues for a long time because we were storing too much data in Cookies, so we moved it to the session. Now I'm concerned we are dumping a lot more data into this event. I think it's a little risky for "may be useful". If there is a lot of data, this code could instead be specific about which data from the session is being logged.

nicklathe added 4 commits May 7, 2025 12:32
  - Set statsig_stable_id in session
  - Pass id to frontend via script tag functionality

Signed-off-by: Nick Lathe <[email protected]>
  - Session was added to Metrcis::Events.log_event in places that are
    unecessary, due to having a signed_in user
  - .dig for statsig_stable_id from session with safe navigation
  operator
  - Remove unecessary line that clears cookies during logout
@nicklathe nicklathe force-pushed the P20-1505/remove-statsig-stable-id-cookie branch from 16e4995 to 5d981b9 Compare May 7, 2025 19:33
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.

2 participants