Skip to content

Security and data access

Detailed page. Use “On this page” to jump directly to the section you need.

Use this reference to understand who can run Checks and which data they can see.

Use this page to decide which Permission Set to assign, understand whose Salesforce access a Check uses, and review what custom Apex, Platform Events, diagnostics, and action links can expose.

Record Health Check reads Salesforce data with the access of the user who starts the run. It does not grant access to a record or field the user cannot already read. A standard Check does not change the checked record.

The package protects six separate areas:

AreaProtection
Starting a runRequires the Record Health Check Run Custom Permission and access to the appropriate Apex entry point
Reading customer dataEvaluation queries use WITH USER_MODE and package classes use with sharing
Reading Check definitionsAfter Run authorization succeeds, packaged Custom Metadata definitions load in system mode; this does not grant access to business records or configuration editing
Managing readiness receiptsAfter Admin plus Run authorization, a bounded with-sharing service manages private package-owned evidence; it never elevates customer-record evaluation
Viewing troubleshooting detailRequires both the Check Set setting and a direct packaged Admin or Diagnostics Viewer Permission Set assignment
Publishing or receiving eventsRequires Platform Event permissions and an explicit publication choice or setting

This checkout defines seven Permission Sets; see version availability for the published package. Record Health Check Run (rhc__Record_Health_Check_Run) is a Custom Permission included in the four runner Permission Sets; it is not a Permission Set by itself.

For the complete capability matrix, API names, and assignment steps, see Permission Sets. For the two authorization gates, see Custom Permissions.

To assign one, go to Setup → Permission Sets, open the installed Permission Set, select Manage Assignments, and then select Add Assignments. Do not search for a Permission Set named Record Health Check Run; that name belongs to the Custom Permission contained in the installed Permission Sets.

Installed Permission SetWhat it providesAssign it to
Record Health Check Card User (rhc__Record_Health_Check_Card_User)Run Custom Permission, Lightning controller and App Builder picker classes, and Create access for card lifecycle eventsPeople who only configure or run the record-page card; this is the least-privilege default for interactive users and supports explicitly enabled card publication
Record Health Check User (rhc__Record_Health_Check_User)Run Custom Permission; access to Lightning, Apex, Flow, Agentforce, REST, Queueable, Batch, and Scheduled entry classes; read access to both Custom Metadata Types; create/read access for Set Run and Check Result eventsAutomation principals that use those broader entry points; not the default card-only assignment
Record Health Check Admin (rhc__Record_Health_Check_Admin)Runner access plus diagnostics, Custom Metadata type visibility, validation, and App Builder picklist accessAdministrators who maintain or troubleshoot Checks; creating Custom Metadata also requires Salesforce Customize Application or equivalent access
Record Health Check MCP Integration (rhc__Record_Health_Check_MCP_Integration)Run Custom Permission, the versioned Apex REST adapter, and read access to both Custom Metadata Types; excludes UI, Flow, Agentforce, async Apex, lifecycle events, and diagnosticsDedicated least-privilege MCP integration users
Record Health Check Diagnostics Viewer (rhc__Record_Health_Check_Diagnostics_Viewer)Diagnostics authorization only; no Run permission, Apex, metadata, object, field, or event accessAffected Card User or User assignments that need temporary diagnostic visibility without Admin access
Record Health Check Error Log Publisher (rhc__Record_Health_Check_Error_Log_Publisher)Create and Read access to the restricted Log Platform Event (Salesforce requires Read with Create)Narrowly selected runners whose Check Sets enable error-log publication; assignees must be trusted with restricted error data
Record Health Check Readiness Auditor (rhc__Record_Health_Check_Readiness_Auditor)Read-only access to bounded private readiness receipts; no Run, Preview, cleanup, diagnostic, or metadata accessReviewers who inspect saved verification evidence without administering or executing Record Health Check

Do not assign the Admin Permission Set merely because a person needs to run a Check. Diagnostic detail can include formula text, SOQL text, and specific access problems.

The four runner Permission Sets do not grant access to Record_Health_Check_Log__e. Assign Record Health Check Error Log Publisher separately and only to the Flow, Apex code, integration user, or monitoring tool that needs restricted troubleshooting details.

The user who starts each Salesforce transaction supplies the access used in that transaction.

How the run startsWhich user’s access applies?
Person opens or runs the Lightning cardThat person’s access
Screen FlowThe interactive user and execution context Salesforce gives that Flow transaction
Record-triggered or autolaunched FlowThe user and execution context Salesforce gives that Flow transaction; do not assume system context bypasses package authorization or user-mode data reads
ApexThe user running the Apex transaction
Queueable ApexThe user under whom Salesforce executes the queued transaction; investigate its AsyncApexJob separately from submission
Batch ApexThe user under whom Salesforce executes the Batch transaction
Scheduled ApexThe scheduling user; the packaged scheduler rechecks authorization and starts Batch Apex

Record Health Check queries business records with WITH USER_MODE. Salesforce therefore enforces object access, field access, record sharing, restriction rules, scoping rules, and future user-mode visibility controls for that user.

The Admin Permission Set grants Record Health Check administration capabilities. It does not grant access to Account, Opportunity, Case, or any other business object or field. Grant those permissions through your organization’s normal profiles and permission sets.

The Flow action still checks the Record Health Check Run Custom Permission. Confirm that the user who causes or executes the Flow has an installed runner Permission Set, and test the Flow in its actual execution context rather than assuming a system-context Flow bypasses the package check.

Query outcomes describe only the rows visible in that transaction. Zero returned rows do not prove that no matching rows exist elsewhere in the org; they prove that the configured user-mode query found no visible rows. Record Health Check never runs an elevated comparison query to distinguish a truly empty dataset from rows hidden by sharing, restriction rules, or scoping rules. Doing so would leak the existence of data the running user cannot access. Choose the Check’s configured no-rows policy with that visible-scope meaning in mind. Org-wide completeness requires a separately authorized administrative design outside the ordinary evaluator.

If the initial record query cannot return a requested record, its result uses RECORD_NOT_VISIBLE. A field-access problem is returned publicly as CANNOT_EVALUATE; an authorized administrator can see the more specific FIELD_NOT_ACCESSIBLE diagnostic. An invalid request or a missing Run Custom Permission can stop the request before individual results exist.

Before rollout, test with a real user from each intended access group. An administrator’s successful test does not prove that a sales or service user can read every field required by the Check.

Preview readiness receipts are package-owned operational evidence, not customer business records or saved health-result history. Every Preview and expired-receipt cleanup request first requires the packaged Admin and Run authorizations. Only after that check does the with-sharing readiness service use its reviewed system-mode operations: two queries and one delete. Current-receipt lookup binds the running actor, org, Check, Set, definition fingerprint, and normalized scope digest, returns at most 200 rows, and does not return representative record IDs or business values. Cleanup requires explicit confirmation, selects only expired rows, and deletes at most 200 at a time.

The Admin Permission Set grants Read plus the Edit/Delete object combination Salesforce requires, but receipt fields are read-only and a validation rule rejects updates. Receipt creation remains a service operation. The Readiness Auditor Permission Set is read-only and does not authorize Preview, cleanup, or Check execution. These narrow exceptions do not change the rule that every Account, Opportunity, Case, or other customer-record query used for evaluation runs in user mode.

Formula globals such as $User are not a supported way to branch a Formula Check by caller. For a page-versus-automation incident, use the execution-context troubleshooting guide to distinguish access, identity, timezone, and asynchronous transaction boundaries before changing the Check.

Source Query, Comparison Query, and applicability count query text is inspected before it runs.

Query conditionPackage behavior
Contains WITH SYSTEM_MODERejects the query as INVALID_SOQL_TEMPLATE
Contains a data-changing keyword such as INSERT, UPDATE, DELETE, UPSERT, or MERGERejects the query as INVALID_SOQL_TEMPLATE
Does not contain WITH USER_MODEAdds WITH USER_MODE in the supported location
Requests an outer LIMIT above 2,000Lowers that outer limit to 2,000
Uses a merge token other than record.*Rejects the query

Merge-token values are converted to the Salesforce data type required by the field and safely inserted into the query. A missing or invalid value returns a documented Reason Code instead of running altered SOQL. See Merge tokens.

A custom Apex Check implements rhc.RecordHealthCheckPlugin. It is code created by your team, so it must receive the same security review as any other Apex class in your org.

The custom class must:

  • declare with sharing;
  • use WITH USER_MODE for SOQL;
  • check any additional object and field access required by its logic;
  • avoid changing records, making callouts, sending email, publishing events, or starting asynchronous Apex; and
  • return exactly one result for every record ID it receives.

Record Health Check places a savepoint around construction and evaluation. It detects changes to Apex counters for record changes, callouts, Queueable jobs, future methods, and email. When detected, it stops the run; record changes and queued work can be rolled back, but an already-sent callout or email cannot be undone.

Apex does not expose a reliable counter for every effect. In particular, the package cannot prove at run time that custom code did not publish a Platform Event or start Batch or Scheduled Apex. Code review, static analysis, and the supplied contract tests must enforce those restrictions. The package also cannot correct an unsafe query written inside the custom class.

See Create a custom Apex Check for the required review and tests. Administrators only paste the reviewed class API name into the Check record in Setup.

Detailed troubleshooting appears only when both conditions are true:

  1. Show Diagnostics is selected on the Check Set.
  2. The running user has a direct, active assignment of Record Health Check Admin (rhc__Record_Health_Check_Admin) or Record Health Check Diagnostics Viewer (rhc__Record_Health_Check_Diagnostics_Viewer).

There is no diagnostics Custom Permission. The assignment itself is the authorization, so an installation profile grant, a cloned Permission Set, or Permission Set Group membership alone does not authorize diagnostics. The Card User, User, and MCP Integration Permission Sets do not authorize it either. Diagnostics Viewer is additive: the affected user still needs the appropriate runner Permission Set.

Turn Show Diagnostics off after troubleshooting. It applies to the whole Check Set, so every person who also has the diagnostics permission can see the details while it remains enabled.

Public results hide specific field-access details behind CANNOT_EVALUATE. Authorized diagnostics can show the more specific reason and relevant configuration. This helps an administrator fix the Check without telling a normal user which hidden field or record caused the problem.

Does Record Health Check save sensitive values?

Section titled “Does Record Health Check save sensitive values?”

The package does not install a result-history object and does not write Found or Expected values back to the checked record.

InformationSaved by Record Health Check?
Status, Reason Code, Found, and Expected in the returned responseNo; returned to the current Apex, Flow, or Lightning caller
Checked record changesNo
Check Set and Check configurationYes; stored as Custom Metadata
Explicit Preview readiness receiptYes; stores identities, fingerprint, aggregate counts, capability state, actor/org, scope digest, and expiry, but no record IDs/values
[RHC] linesPresent only in Salesforce debug logs according to the org’s log retention
Error details waiting for logger flush()Held only for the current transaction, then published or discarded

When history is required, create a custom object owned by your team and save only the returned fields that the business needs. Apply object, field, sharing, and retention controls to that object. See Data model.

The health-result events contain identifiers and result classifications, not the displayed business values.

Record_Health_Check_Result__e and Record_Health_Check_Set_Run__e can contain:

  • Run ID, event ID, source, occurrence time, and contract/package version;
  • Check or Check Set Qualified API Name;
  • checked record ID;
  • Status, Reason Code, and Severity for a Check result; and
  • final counts for a Check Set result.

They do not contain the running user’s ID, Found, Expected, Check messages, SOQL, formula text, stack trace, or diagnostics. ContainsRestrictedDetail__c on the Check Result event is always false in the current implementation.

Record_Health_Check_Log__e is different. It can contain the user ID, record ID, error message, exception type, and stack trace. Treat access to it like access to a restricted error log. See Lifecycle events.

After merge tokens are resolved, Record Health Check accepts:

  • a same-org path beginning with /, including /lightning/...; or
  • an external URL beginning with https://.

It rejects http://, javascript:, data:, mailto:, a protocol-relative URL beginning with //, a backslash, or a value longer than 2,000 characters. Apex checks the URL before returning it, and the Lightning component checks it again before displaying a link.

Opening an allowed link does not save a record automatically. The destination page can still let a user edit and save data according to that user’s Salesforce access. See Configure action links.

  • Assign the User Permission Set to runners and reserve the Admin Permission Set for Check authors and troubleshooters.
  • Test every Check with representative non-administrator users.
  • Review stored SOQL and every custom Apex Check in source control.
  • Keep Show Diagnostics off except during an investigation.
  • Grant Error Log event access separately and narrowly.
  • Store returned results only in a custom object with reviewed access and retention.
  • Review every external https:// Action URL and every Flow or Apex process that receives a Platform Event.
  • Report suspected vulnerabilities privately through the process in .github/SECURITY.md.