Flow
These checks cover every *.flow-meta.xml (SFDX) and *.flow (MDAPI) file in the project.
vulkro-sf scan ./force-app
Checks
| Rule ID | What it finds |
|---|---|
flow-runinmode-elevated | A flow whose runInMode is SystemModeWithoutSharing, SystemModeWithSharing (or the keep-permissions variant), or the legacy DefaultMode. Flows with no runInMode are also flagged, because the implicit context depends on the trigger type. |
flow-runinmode-system-mode-recordcreates / -recordupdates / -recorddeletes | Each Create, Update or Delete Records element in a system-mode flow. The DML bypasses sharing. |
flow-system-mode-sensitive-field-write | A system-mode flow that writes a sensitive-named field (SSN, salary, an admin flag). |
| SF-FLOW-TAINT-001 | Caller input (a screen field, input variable or the triggering record) reaching a query filter or action in a system-context flow. |
flow-dynamic-filter-from-input | A Get Records filter whose value comes from a flow input variable. |
flow-dml-inside-loop | A Create, Update or Delete Records element run once per loop iteration. Collect records in the loop and write once after it. |
flow-query-inside-loop | A Get Records element run once per loop iteration. |
flow-dml-reachable-in-loop | A query or DML reached from inside a loop through the connector chain. |
salesforce-id-literal-in-flow | A 15- or 18-character record ID with a known key prefix in a stringValue. It breaks on deploy to another org. |
flow-hardcoded-id-outside-stringvalue | A record ID in a formula, element reference or filter value. |
flow-missing-fault-connector | A DML, query, action or Apex plugin element with no fault path. |
To fix a system-mode finding, run the flow in user context and grant access through permission sets, or keep system mode and enforce FLS in an Apex action the flow calls.
Example
Non-compliant: system-mode DML on Lead, run once per loop iteration.
<Flow xmlns="http://soap.sforce.com/2006/04/metadata">
<runInMode>SystemModeWithoutSharing</runInMode>
<start>
<triggerType>RecordAfterSave</triggerType>
<object>Lead</object>
</start>
<loops>
<name>updateLoop</name>
<collectionReference>Leads</collectionReference>
<nextValueConnector>
<targetReference>UpdateLead</targetReference>
</nextValueConnector>
</loops>
<recordUpdates>
<name>UpdateLead</name>
<inputReference>updateLoop</inputReference>
</recordUpdates>
</Flow>
See also: Flow logic and process mining, Anti-patterns CLI