Source scan vs live-org scan
vulkro-sf runs in two shapes:
- Source-only: scan retrieved metadata or an SFDX checkout from disk. No org access. Covers the Code pillar in full and the declarative-side findings that exist on disk.
- Live-org: connect to a running org through the official
sfCLI. Adds the Posture, Identity, Third-party, and AI / Agentforce- runtime pillars by reading live metadata.
This page explains the trade-off so an admin or developer can choose the right shape for the right job (and the right pattern when both are needed).
The five pillars, source-only vs live-org
Vulkro's Salesforce coverage is structured around five pillars. Some pillars live entirely in source on disk; others require a live org to evaluate.
| Pillar | What it covers | Source-only? | Live-org? |
|---|---|---|---|
| Code | Apex, LWC, Aura, Visualforce, Flow detectors. Includes the AppExchange Top-20 SOQL injection / XSS / CSRF / sharing / crypto / open-redirect surface. | Full coverage on disk. | Same coverage, no change. |
| Posture | SecuritySettings (session timeout, clickjack, CSRF, HTTPS, password policy, login IP ranges), sharing rules, org-wide defaults. | Partial: only what is in the retrieved securitySettings/, sharingRules/, and object OrganizationWideDefault metadata. Settings the ISV did not retrieve are silent. | Authoritative: reads live from the org. |
| Identity | Profile over-privilege, Permission Set over-privilege, Permission Set Group aggregation, guest-user object exposure, dormant System Administrators. | Static analysis on retrieved Profile.xml / PermissionSet.xml. The dormant-admin check cannot fire without User.LastLoginDate from the live org. | Authoritative: every check fires, including dormant admins. |
| Third-party | Connected Apps, Named Credentials, External Credentials, RemoteSiteSetting, CorsWhitelistOrigin, CspTrustedSite, installed managed and unmanaged packages. | Connected App / Named Credential metadata in source is covered. Installed packages are silent: source does not list them. | Authoritative: live-org org packages enumerates every installed managed and unmanaged package with version, license, and namespace. |
| AI / Agentforce | GenAiFunction surface, ForcedLeak class-bypass detection (Apex action class declared without sharing). | The metadata GenAiFunction declarations and target Apex classes on disk are covered. | Same coverage, plus the live confirmation that the GenAiFunction is active and assigned to a Bot. |
The short version: source-only catches code findings; live-org catches every code finding plus configuration in the running org.
Source-only: when it is the right shape
Run vulkro-sf scan ./force-app (no org subcommand) when:
- Pre-submission code review for an AppExchange managed package. The submission is the source code; the reviewer scans the retrieved source; the readiness report is generated from the same source. No live org needed.
- CI/CD pull-request gating. The PR scan should not authenticate to a real org from a runner; it should scan the diff. See CI/CD integration.
- A pre-purchase due-diligence audit on third-party Apex. When you only have the source artifact (a ZIP, a partner-provided checkout) and no org access, source-only is the only available path.
- An engineering team's day-to-day workflow. Developers iterate against scratch orgs that change frequently; the source on the laptop is the stable artifact to scan.
Source-only is also the lowest-trust path: it reads files from disk, makes no network calls, and writes findings to disk. Air-gapped runs work without further configuration.
Live-org: when it is the right shape
Run vulkro-sf org status, vulkro-sf org perms, and vulkro-sf org packages when:
- You need the live posture. SecuritySettings drift between source-controlled metadata and a live org is common (an admin changed it in Setup and never wrote the change back). Only the live read tells you what is currently active.
- You need the dormant-admin check. A System Administrator who
has not logged in for 90+ days is a credible compromise target.
The check needs
LastLoginDatefrom the live org. - You need the installed-package inventory. Connected Apps and
managed packages installed into a customer org are not in the
source artifact; they are in the org. The
org packagesdetector enumerates them. - You are running an ongoing org audit. The consultancy and internal-IT-security workflow runs the live-org pass on a schedule, not only at engagement start.
The live-org path requires the sf CLI on PATH and a one-time
authentication per org (see Live-org setup).
Privacy: the live-org contract in full
The live-org path is metadata-only. The contract below is the verbatim wording from the install page; it is repeated here because the trade-off in this document is about the choice between two scan shapes, and the privacy properties of each are part of that choice.
What vulkro-sf org reads
- Profiles and Permission Sets, including assignments.
- Permission Set Groups.
- SecuritySettings, sharing rules, org-wide defaults.
- Connected Apps and their OAuth scopes.
- Named Credentials and External Credentials.
- Flow definitions and process automation metadata.
- GenAiFunction declarations and the target Apex class metadata.
- Installed managed and unmanaged packages with version, license, and namespace.
- Static Resources (for hardcoded-API-key scanning).
- SAML SSO and Auth Provider configuration.
- Login Flows and Login IP Ranges.
- RemoteSiteSetting, CorsWhitelistOrigin, CspTrustedSite.
Every item above comes from the Salesforce Metadata API or the Tooling API. No SOQL or Bulk queries are issued against business records.
What vulkro-sf org does NOT read
- No customer records.
- No Accounts, Opportunities, Leads, Cases, Contacts, custom-object rows.
- No file attachments, ContentVersions, ContentDocuments.
- No SOQL
SELECTagainst any sObject that contains business data. - No Bulk API queries.
- No reports, dashboards, list views, or email content.
- No
Userrecords beyond what is needed to identify the System Administrator population for the dormant-admin check (username, LastLoginDate, IsActive, Profile).
Where the OAuth token lives
In the official sf CLI credential store on your laptop. Vulkro
never sees the access token, never stores it, never transmits it.
Revoke org access through Salesforce Setup the same way you would
for the sf CLI itself.
The source-only path is even narrower: it does not authenticate anywhere and makes no outbound network calls during the scan.
Combining both: merge the SARIFs
The recommended pattern when you need full coverage is to run both passes and merge the findings. The combined deliverable is one SARIF file containing every finding from both paths.
# 1. Source-only scan (the Code pillar findings).
vulkro-sf scan ./force-app --format sarif -o code.sarif
# 2. Live-org passes (Posture, Identity, Third-party).
vulkro-sf org status --target-org my-prod
vulkro-sf org perms --target-org my-prod --format sarif -o perms.sarif
vulkro-sf org packages --target-org my-prod --format sarif -o packages.sarif
# 3. Merge the SARIFs.
# sarif-multitool from Microsoft is the canonical merger:
sarif merge code.sarif perms.sarif packages.sarif --output-file combined.sarif
Upload combined.sarif to GitHub Code Scanning, GitLab's
Vulnerability Report, or any SARIF-aware tool. Every Vulkro finding,
across both pillars, lands in the same downstream view.
The same pattern works for the AppExchange readiness report: run the source-only scan first, the live-org passes second, and generate the readiness HTML from the combined finding set so the report reflects both source and live configuration.
A simple decision matrix
| Question | Use this |
|---|---|
| "Am I prepping a managed-package submission?" | Source-only scan plus appexchange-report. Live-org is not in the submission boundary. |
| "Is this a PR-time gate?" | Source-only scan --since main. No org auth from a runner. |
| "Am I auditing a live production org?" | Live-org org status, org perms, org packages. Combine with a source scan if the source is available. |
| "Am I tracking org-config drift over time?" | Live-org, scheduled. Source-only would miss admin-side Setup changes. |
| "Air-gapped network, no internet?" | Source-only. Live-org needs HTTPS to the Salesforce instance. |
Where to go next
- First scan: the source-only quickstart.
- Live-org setup: install
sf, authenticate, run the firstorg status. - Methodology: the master coverage matrix, which per-detector annotation says which pillar (and therefore which scan shape) it belongs to.