Treat reporting access as a layered problem. Each layer is a separate gate; data leaks through the weakest one.
- Field-Level Security (FLS) — the foundation. Hide sensitive fields from any profile/permission set that shouldn't see them. FLS applies to reports too: a hidden field doesn't appear in the report builder field picker for that user. This is the primary line of defence.
- Report Folder Sharing — keep sensitive reports in folders shared only with the right audience (e.g., "HR Reports" folder shared only with the HR public group with Manager access; everyone else can't see the folder).
- Custom Report Types — for advanced control, create a custom report type that includes only safe fields. Then deny access to the standard report types that expose the sensitive fields. This is harder to bypass than FLS alone.
- Object-level OWD and sharing — even if FLS is correct, if the underlying records are visible org-wide, a user might piece together aggregates. For HR data, set OWD to Private on the relevant object.
- Field-Level Encryption (Shield Platform Encryption) — for the most sensitive fields, encrypt at rest. Encrypted fields render as masked unless the user has the "View Encrypted Data" permission.
- Disable Export for non-trusted profiles — the system permission "Export Reports" is granted by default. Revoke it for users who shouldn't be able to download CSVs.
- Event Monitoring + Transaction Security — log every report run; alert on anomalous access patterns. Salesforce Shield's Event Monitoring captures
ReportEventrows showing who ran what report when.
Common mistake: relying on Folder Sharing alone. A user who isn't shared the folder can still build their own report against the same data, since FLS is the actual gate. Always start with FLS, then layer.
Audit cadence: quarterly review of who has View All Data, Export Reports, and access to "All Reports" folders.
