Skip to main content

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

FlagTypeDefaultDescription
--target-org, -o <alias>string(required)Target org alias or username, as known to sf org login.
--format <fmt>enumtableOutput format.
--check-compromisedflagoffCross-reference every Connected App's OAuth ConsumerKey against the bundled compromised-OAuth intel. Equivalent to setting VULKRO_SF_INTEL_COMPROMISED=1.
--verbose, -vflagoffBump 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 the Metadata blob 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

RuleSeveritySignal
SF-CONNECTED-APP-002Highconnected-app-live-full-scope-active
SF-CONNECTED-APP-004Mediumconnected-app-live-cleartext-callback
SF-CONNECTED-APP-003Lowconnected-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