vulkro-sf org integration-users
Audits active integration-user accounts for excess privilege, human
reuse of the integration login, and staleness
(SF-INTEG-USER-001 / -002 / -003), then runs the service-account
lifecycle audit (SF-SVC-USER-001 / -002 / -003).
Integration accounts are the accounts nobody owns: created for one vendor connection, granted broad access to make the integration work, and never reviewed again. They were the lateral-movement pivot in the published 2025 incidents.
Synopsis
vulkro-sf org integration-users --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> | table | json | table | Output format. |
--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
User rows filtered to known integration-user profile names with
IsActive = true for the first pack, then all active users for the
service-account lifecycle pack.
What gets reported
Integration users
| Rule | Severity | What fires |
|---|---|---|
SF-INTEG-USER-001 | High | An integration user holding API permission alongside extra permissions (an admin profile). Signal org-integration-user-has-api-enabled. |
SF-INTEG-USER-002 | Medium | A recent interactive login on an integration account: a human is using the robot's credentials. Signal org-integration-user-recent-interactive-login. |
SF-INTEG-USER-003 | Low | An integration account with no login for over 180 days. Signal org-integration-user-inactive-stale. |
Service-account lifecycle
Runs over all active users. An account is classified heuristically as a bot or service account from username / alias markers or an integration or API-only profile, then checked:
| Rule | Severity | What fires |
|---|---|---|
SF-SVC-USER-001 | High | MFA-exempt with no login-IP lock. Signal org-service-account-mfa-exempt-no-ip-lock. |
SF-SVC-USER-002 | Medium | Not time-bound: no expiry and a session window above 60 minutes. Signal org-service-account-not-time-bound. |
SF-SVC-USER-003 | High | Holds a broad system permission (Modify All Data, View All Data, or Author Apex). Signal org-service-account-broad-permissions. |
Examples
vulkro-sf org integration-users --target-org my-prod
vulkro-sf org integration-users -o my-prod --format json > integration-users.json
Exit codes
0- no findings.1- posture findings reported.2- error.
Scope and honesty
The org is read locally through your own authenticated sf CLI login;
nothing is sent anywhere. The audit reads user, profile, and permission
metadata. No business records are read.
Two limits worth being explicit about. The integration-user pack keys off known integration-user profile names, so an integration account running on a custom profile with an ordinary name may not be picked up by that pack. The service-account pack uses a heuristic classification from username, alias, and profile shape: it can classify a human account as a bot, or miss a bot that looks like a person. Review the classification before acting on a finding.
Findings are static posture signals, not runtime-validated exploits, and a clean run does not certify the org's integration accounts safe.
Where to go next
- vulkro-sf org effective-perms - what those accounts can actually reach.
- vulkro-sf org mfa - MFA exemption on integration profiles.
- vulkro-sf org connected-apps - the OAuth side of vendor integrations.