Skip to content

Conversation

@philprime
Copy link
Member

@philprime philprime commented Oct 31, 2025

This PR contains a document and work-in-progress files from prototyping alternative masking approaches.

We are only going to merge the document develop-docs/VIEW_MASKING_STRATEGIES.md and all other files are just for context.

Please only review the document

#skip-changelog

@philprime philprime self-assigned this Oct 31, 2025
@github-actions
Copy link
Contributor

github-actions bot commented Oct 31, 2025

Fails
🚫 Please consider adding a changelog entry for the next release.
Messages
📖 Do not forget to update Sentry-docs with your feature once the pull request gets approved.

Instructions and example for changelog

Please add an entry to CHANGELOG.md to the "Unreleased" section. Make sure the entry includes this PR's number.

Example:

## Unreleased

### Features

- Add alternative masking strategies ([#6619](https://github.com/getsentry/sentry-cocoa/pull/6619))

If none of the above apply, you can opt out of this check by adding #skip-changelog to the PR description or adding a skip-changelog label.

Generated by 🚫 dangerJS against 1cc1958

@codecov
Copy link

codecov bot commented Oct 31, 2025

⚠️ JUnit XML file not found

The CLI was unable to find any JUnit XML files to upload.
For more help, visit our troubleshooting guide.

@philprime philprime force-pushed the philprime/masking-dev-docs branch 2 times, most recently from 83b0f8c to c887b99 Compare October 31, 2025 13:36
@philprime philprime force-pushed the philprime/masking-dev-docs branch from c887b99 to c73f441 Compare October 31, 2025 13:44
@philprime
Copy link
Member Author

philprime commented Nov 5, 2025

Also consider these approaches:

  • Defensive-programming approach, masking everything unless there is a 100% certainty an area can be unmasked safely (safest but most complicated approach)
  • Rebuilding a wireframe using colored rectangles based on the view hierarchy, without calling draw methods (should also result in performance improvement)
  • Draw the view into a PDF context, then use PDF manipulation to remove all images (probably not possible because the rendered view is an image by itself)

@philprime philprime marked this pull request as ready for review November 17, 2025 09:02
Copy link
Member

@philipphofmann philipphofmann left a comment

Choose a reason for hiding this comment

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

Thanks for the great summary


### Goals

- Detect and mask sensitive regions without requiring app developer annotations.
Copy link
Member

Choose a reason for hiding this comment

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

l: It's unclear to me what app developer annotations are exactly.

Copy link
Contributor

Choose a reason for hiding this comment

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

q: Would developer annotations help deterministically mask SwiftUI views? If that's the case, would a hybrid approach using viewhierarchy for UIKit and dev annotations for swift UI be acceptable?


- No private APIs in production App Store builds.
- No dependence on globally toggled system services (e.g., VoiceOver) in production.
- Work reliably in background-capable scenarios and during animations (e.g., during view transitions).
Copy link
Member

@philipphofmann philipphofmann Nov 17, 2025

Choose a reason for hiding this comment

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

m: I'm not 100% sure what background-capable scenarios are. Can you give an example? Do you mean for example a phone call or the app suddenly moving to the background?

Comment on lines +31 to +42
The process when taking a screenshot or session replay frame is as follows:

```mermaid
flowchart TD
A[**Root View/Window**]
B[**Full-Screen Screenshot**<br/>UIImage from root view/window]
C[**Region Detection Engine**<br/>Accessibility, View Hierarchy, ML]
D[**Mask Renderer**<br/>Solid overlay of redact regions]
E[**Masked Output Image**]

A --> B --> C --> D --> E
```
Copy link
Member

Choose a reason for hiding this comment

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

Thanks for the diagram. Makes it easier to understand.

Comment on lines +65 to +66
> ![INFO]
> As of Nov 13th, 2025, this is the default implementation for identifying which areas of a view hierarchy should be masked during screenshot or session replay capture.
Copy link
Member

Choose a reason for hiding this comment

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

l: I'm unsure if that's the formatting you want to have
Image

> ![INFO]
> As of Nov 13th, 2025, this is the default implementation for identifying which areas of a view hierarchy should be masked during screenshot or session replay capture.

The `SentryUIRedactBuilder` is the current default implementation for identifying which areas of a view hierarchy should be masked during screenshot or session replay capture.
Copy link
Member

Choose a reason for hiding this comment

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

l: Maybe you could link to the class in the repo here.


- A typical YOLO-style detection model can be 3-5MB, directly adding to the app's download size and increasing SDK install size
- Cannot improve detection accuracy without shipping a new SDK version, as model updates require SDK updates
- All users download the model regardless of whether they use session replay
Copy link
Member

Choose a reason for hiding this comment

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

m: We could solve this by putting SR into an extra package. Or maybe even an extra package or repository just for this. I would start with an extra repo or package. It's the easiest option IMO. We can also change it later.


**Known Issues:**

During initial testing, generated output geometry did not work correctly when using a real device, requiring additional debugging and coordinate system validation. The implementation uses Vision framework's coordinate normalization to help mitigate these issues, but careful testing across device types and orientations is essential.
Copy link
Member

Choose a reason for hiding this comment

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

h: It's not 100% clear to me what generated output geometry did not work correctly exactly means. So when this doesn't work correctly, does it mean that masking is broken or that the output doesn't work at all? Or to rephrase: if this doesn't work correctly, do we potentially leak PII? Can we detect if it doesn't work?


**Performance Concerns:**

Devices without Neural Engine (iPhone 7 and earlier) will fall back to CPU-only inference, which may be considerably slower. Continuous ML inference during session replay may impact battery life and trigger thermal throttling on older devices. These concerns require benchmarking across device generations to establish performance baselines.
Copy link
Member

Choose a reason for hiding this comment

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

m: One option to solve this would be simply turning it off on older device or to add an opt in.

Comment on lines +768 to +770
**Bring-Your-Own-Model (BYOM) Approach:**

To enable domain-specific optimization, a repository with training setup will be provided so customers can clone, edit, and build their own models. Customers can add domain-specific test data from their own apps (e.g., banking apps with credit card forms) and train specialized models optimized for their specific UI patterns and sensitive content types. The training setup can also be used to derive models compatible for Android, enabling cross-platform model sharing.
Copy link
Member

Choose a reason for hiding this comment

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

m: It's great that we have this here. I would maybe add a note that this could significantly complicate debugging masking issues.


### Limitations and Considerations

**Best-Effort Approach:**
Copy link
Member

Choose a reason for hiding this comment

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

Since we changed our official approach towards masking to best effort, I think that's OK.

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.

4 participants