Architecture
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.
Security summary
Section titled “Security summary”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:
| Area | Protection |
|---|---|
| Starting a run | Requires the Record Health Check Run Custom Permission and access to the appropriate Apex entry point |
| Reading customer data | Evaluation queries use WITH USER_MODE and package classes use with sharing |
| Reading Check definitions | After Run authorization succeeds, packaged Custom Metadata definitions load in system mode; this does not grant access to business records or configuration editing |
| Managing readiness receipts | After Admin plus Run authorization, a bounded with-sharing service manages private package-owned evidence; it never elevates customer-record evaluation |
| Viewing troubleshooting detail | Requires both the Check Set setting and a direct packaged Admin or Diagnostics Viewer Permission Set assignment |
| Publishing or receiving events | Requires Platform Event permissions and an explicit publication choice or setting |
Choose the correct Permission Set
Section titled “Choose the correct Permission Set”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 Set | What it provides | Assign 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 events | People 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 events | Automation 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 access | Administrators 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 diagnostics | Dedicated 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 access | Affected 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 access | Reviewers 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.
Whose record and field access is used?
Section titled “Whose record and field access is used?”The user who starts each Salesforce transaction supplies the access used in that transaction.
| How the run starts | Which user’s access applies? |
|---|---|
| Person opens or runs the Lightning card | That person’s access |
| Screen Flow | The interactive user and execution context Salesforce gives that Flow transaction |
| Record-triggered or autolaunched Flow | The user and execution context Salesforce gives that Flow transaction; do not assume system context bypasses package authorization or user-mode data reads |
| Apex | The user running the Apex transaction |
| Queueable Apex | The user under whom Salesforce executes the queued transaction; investigate its AsyncApexJob separately from submission |
| Batch Apex | The user under whom Salesforce executes the Batch transaction |
| Scheduled Apex | The 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.
Private readiness evidence
Section titled “Private readiness evidence”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.
How stored SOQL is protected
Section titled “How stored SOQL is protected”Source Query, Comparison Query, and applicability count query text is inspected before it runs.
| Query condition | Package behavior |
|---|---|
Contains WITH SYSTEM_MODE | Rejects the query as INVALID_SOQL_TEMPLATE |
Contains a data-changing keyword such as INSERT, UPDATE, DELETE, UPSERT, or MERGE | Rejects the query as INVALID_SOQL_TEMPLATE |
Does not contain WITH USER_MODE | Adds WITH USER_MODE in the supported location |
Requests an outer LIMIT above 2,000 | Lowers 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.
Plugin write restrictions
Section titled “Plugin write restrictions”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_MODEfor 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.
Diagnostics authorization
Section titled “Diagnostics authorization”Detailed troubleshooting appears only when both conditions are true:
- Show Diagnostics is selected on the Check Set.
- 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.
| Information | Saved by Record Health Check? |
|---|---|
| Status, Reason Code, Found, and Expected in the returned response | No; returned to the current Apex, Flow, or Lightning caller |
| Checked record changes | No |
| Check Set and Check configuration | Yes; stored as Custom Metadata |
| Explicit Preview readiness receipt | Yes; stores identities, fingerprint, aggregate counts, capability state, actor/org, scope digest, and expiry, but no record IDs/values |
[RHC] lines | Present 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.
What do the Platform Events contain?
Section titled “What do the Platform Events contain?”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.
Which action links are allowed?
Section titled “Which action links are allowed?”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.
Security review checklist
Section titled “Security review checklist”- 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.