Skip to content

fix: Redact SSO PII before deletion#38425

Merged
robrap merged 27 commits into
openedx:masterfrom
ktyagiapphelix2u:ktyagi/SSOPII
May 15, 2026
Merged

fix: Redact SSO PII before deletion#38425
robrap merged 27 commits into
openedx:masterfrom
ktyagiapphelix2u:ktyagi/SSOPII

Conversation

@ktyagiapphelix2u
Copy link
Copy Markdown
Contributor

@ktyagiapphelix2u ktyagiapphelix2u commented Apr 23, 2026

Description

Implements automatic PII redaction for UserSocialAuth records before deletion to prevent personally identifiable information from persisting after records are removed.

Jira Ticket

https://2u-internal.atlassian.net/browse/BOMS-514

@ktyagiapphelix2u ktyagiapphelix2u marked this pull request as ready for review April 23, 2026 11:29
@ktyagiapphelix2u ktyagiapphelix2u requested a review from a team as a code owner April 23, 2026 11:29
Comment thread openedx/core/djangoapps/user_api/accounts/tests/test_utils.py Outdated
Comment thread openedx/core/djangoapps/user_api/accounts/tests/test_utils.py Outdated
Comment thread openedx/core/djangoapps/user_api/accounts/utils.py Outdated
Comment thread openedx/core/djangoapps/user_api/accounts/signals.py Outdated
Comment thread openedx/core/djangoapps/user_api/management/tests/test_retire_user.py Outdated
Comment thread openedx/core/djangoapps/user_api/management/commands/retire_user.py Outdated
Comment thread openedx/core/djangoapps/user_api/accounts/signals.py Outdated
@ktyagiapphelix2u
Copy link
Copy Markdown
Contributor Author

@robrap We’re dealing with multiple ways SSO records can get deleted through Django admin, user actions like unlinking accounts, bulk retirement scripts. The challenge is that we don’t control all of these paths, so we can’t reliably add PII redaction directly into each one.

Instead, we’ve set up a two-layer approach.

The first layer is a Django signal that runs automatically right before any SSO record is deleted. This acts as a safety net. No matter how the deletion is triggered whether it’s from admin, user action, the signal ensures sensitive fields like the UID and extra data are redacted. It’s centralized, consistent, so it won’t cause issues if it runs more than once.

The second layer is used only in cases we fully control, like user retirement flows. There, we proactively run a bulk redaction step before deleting records. This is much faster because it uses efficient database operations. When the delete happens afterward, the signal still fires, but it detects that the data is already redacted and simply exits without doing extra work.

Together, these two layers cover both safety and performance. The signal guarantees we never miss redaction, even in code we don’t control, while the explicit bulk step keeps large-scale operations efficient.

Comment thread openedx/core/djangoapps/user_api/accounts/signals.py Outdated
Comment thread openedx/core/djangoapps/user_api/management/commands/retire_user.py Outdated
Comment thread openedx/core/djangoapps/user_api/management/commands/retire_user.py Outdated
Comment thread openedx/core/djangoapps/user_api/accounts/utils.py Outdated
Comment thread openedx/core/djangoapps/user_api/management/commands/retire_user.py Outdated
Comment thread openedx/core/djangoapps/user_api/accounts/signals.py Outdated
Comment thread openedx/core/djangoapps/user_api/accounts/signals.py Outdated
Comment thread openedx/core/djangoapps/user_api/accounts/signals.py Outdated
Copy link
Copy Markdown
Contributor

@robrap robrap left a comment

Choose a reason for hiding this comment

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

Mostly test clean-up comments at this point.

Comment thread openedx/core/djangoapps/user_api/accounts/tests/test_utils.py Outdated
Comment thread openedx/core/djangoapps/user_api/accounts/tests/test_utils.py Outdated
Comment thread openedx/core/djangoapps/user_api/accounts/signals.py Outdated
Comment thread openedx/core/djangoapps/user_api/accounts/utils.py Outdated
Comment thread openedx/core/djangoapps/user_api/accounts/utils.py
Comment thread openedx/core/djangoapps/user_api/accounts/utils.py Outdated
Comment thread openedx/core/djangoapps/user_api/accounts/tests/test_utils.py Outdated
Comment thread openedx/core/djangoapps/user_api/management/tests/test_retire_user.py Outdated
@ktyagiapphelix2u ktyagiapphelix2u force-pushed the ktyagi/SSOPII branch 3 times, most recently from 3f3977a to 667de73 Compare May 11, 2026 07:46
@ktyagiapphelix2u ktyagiapphelix2u force-pushed the ktyagi/SSOPII branch 3 times, most recently from 7fc7ec0 to ebb2f96 Compare May 11, 2026 10:06
Comment thread openedx/core/djangoapps/user_api/accounts/tests/test_utils.py
Comment thread openedx/core/djangoapps/user_api/accounts/utils.py
Copy link
Copy Markdown
Contributor

@robrap robrap left a comment

Choose a reason for hiding this comment

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

More test fun.

Comment thread openedx/core/djangoapps/user_api/accounts/tests/test_signals.py Outdated
Comment thread openedx/core/djangoapps/user_api/accounts/tests/test_utils.py Outdated
Comment thread openedx/core/djangoapps/user_api/accounts/tests/test_utils.py Outdated
Comment thread openedx/core/djangoapps/user_api/accounts/tests/test_utils.py Outdated
Comment thread openedx/core/djangoapps/user_api/accounts/tests/test_utils.py Outdated
Comment thread openedx/core/djangoapps/user_api/management/tests/test_retire_user.py Outdated
@ttak-apphelix
Copy link
Copy Markdown
Contributor

LGTM

@robrap robrap enabled auto-merge (squash) May 15, 2026 23:07
@robrap robrap merged commit 80dbbfa into openedx:master May 15, 2026
40 of 41 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.

5 participants