vulkro-sf org connected-apps
Audits live Connected Apps for OAuth posture
(SF-CONNECTED-APP-002 / -003 / -004).
Unlike the source-format Connected App detector, this command reads the org's current OAuth configuration and correlates it with recent token usage, so a dangerous scope on an app nobody uses is separated from a dangerous scope on an app that was used this week.
Synopsis
vulkro-sf org connected-apps --target-org <alias> [flags]
Flags
| Flag | Type | Default | Description |
|---|---|---|---|
--target-org, -o <alias> | string | (required) | Target org alias or username, as known to sf org login. |
--format <fmt> | enum | table | Output format. |
--check-compromised | flag | off | Cross-reference every Connected App's OAuth ConsumerKey against the bundled compromised-OAuth intel. Equivalent to setting VULKRO_SF_INTEL_COMPROMISED=1. |
--verbose, -v | flag | off | Bump stderr log verbosity. -v enables debug-level tracing for the vulkro + vulkro_sf targets; -vv enables trace. Honoured only when RUST_LOG is unset (an explicit RUST_LOG always wins). |
What gets read
ConnectedApplication(Tooling API) -Id,FullName, and theMetadatablob that carries<oauthConfig>with the granted<scopes>and the<callbackUrl>.OAuthToken(Tooling API) -ConnectedApp.Name,LastUsedDate,UseCount,UserId, most recent first. Tokens are correlated back to apps by name.
What gets reported
| Rule | Severity | Signal |
|---|---|---|
SF-CONNECTED-APP-002 | High | connected-app-live-full-scope-active |
SF-CONNECTED-APP-004 | Medium | connected-app-live-cleartext-callback |
SF-CONNECTED-APP-003 | Low | connected-app-stale-tokens |
SF-CONNECTED-APP-002 fires only when an app has both the Full
scope and an OAuth token used recently, so it reports apps that are
over-scoped and currently live. A Full-scope app with no recent token
usage is left to the source-format scanner rather than raised as an
urgent live-org finding.
Compromised-client-id intel (optional)
Passing --check-compromised (or setting
VULKRO_SF_INTEL_COMPROMISED=1) also cross-references every
ConsumerKey against a list of known-compromised OAuth client IDs from
public 2025 breaches (Salesloft Drift, Gainsight, and others) bundled
into the binary. A match emits one High-severity
SF-CONNECTED-APP-COMPROMISE-001 finding with the signal
connected-app-known-compromised-client-id.
The environment variable exists so non-interactive CI runs do not need
to add the flag to every job spec. Air-gapped operators can sideload a
vetted bundle with
VULKRO_SF_INTEL_COMPROMISED_BUNDLE_OVERRIDE=/path/to/bundle.json.gz.
The bundle is point-in-time and ships inside the binary. A match means the client ID appears in that snapshot and is worth investigating, not that the app is confirmed compromised in your org.
Examples
vulkro-sf org connected-apps --target-org my-prod
# Include the compromised-client-id cross-reference.
vulkro-sf org connected-apps -o my-prod --check-compromised
# Same, driven by environment for a CI job.
VULKRO_SF_INTEL_COMPROMISED=1 vulkro-sf org connected-apps -o my-prod --format json
Exit codes
0- no findings.1- findings reported.2- error.
Scope and honesty
The org is read locally through your own authenticated sf CLI login.
Nothing is sent anywhere, and the compromised-intel check runs against
a bundle inside the binary rather than a network lookup.
Findings are static posture signals about OAuth configuration and token recency, not runtime-validated exploits. No finding, and no clean run, certifies that an org's Connected App estate is safe.
Where to go next
- vulkro-sf org packages - installed package risk, including per-package Connected App posture.
- Connected Apps (detector) - the source-format side of the same rule family.
- vulkro-sf org named-credentials - outbound callout credentials.