CLI Commands
All config.yaml values can be overridden or replaced entirely at the command line.
Usage
python sfhound.py [OPTIONS]Run from the sf-opengraph/ directory.
Options reference
General
| Flag | Description | Default |
|---|---|---|
--help | Print help and exit | — |
--config PATH | Path to the YAML configuration file | config.yaml |
Salesforce credentials
| Flag | Description | Default |
|---|---|---|
--client-id TEXT | Connected App Consumer Key | From config |
--client-secret TEXT | Connected App Consumer Secret (if not using JWT) | From config |
--username TEXT | Salesforce username of the integration user | From config |
--private-key PATH | Path to the PEM private key for JWT authentication | From config |
--login-url URL | Salesforce login endpoint | https://login.salesforce.com |
--api-version TEXT | Salesforce API version string | v56.0 |
Output
| Flag | Description | Default |
|---|---|---|
--output-path PATH | Directory where the output JSON is written | ./opengraph_output |
BloodHound CE auto-ingest
| Flag | Description | Default |
|---|---|---|
--auto-ingest | Upload graph to BloodHound CE after export | Off |
--bh-url URL | BloodHound CE base URL | http://127.0.0.1:8080 |
--bh-username TEXT | BloodHound CE admin username | From config |
--bh-password TEXT | BloodHound CE admin password | From config |
Examples
Minimal — use config.yaml for everything
python sfhound.pyOverride Salesforce credentials only
python sfhound.py \ --client-id YOUR_CLIENT_ID \ --username user@example.com \ --private-key /path/to/salesforce_jwt.keySandbox org
python sfhound.py --login-url https://test.salesforce.comAuto-ingest with all credentials on the command line (no config.yaml required)
python sfhound.py \ --client-id YOUR_CLIENT_ID \ --username user@example.com \ --private-key ./salesforce_jwt.key \ --login-url https://login.salesforce.com \ --auto-ingest \ --bh-url http://127.0.0.1:8080 \ --bh-username admin \ --bh-password YOUR_BLOODHOUND_PASSWORDCustom output directory
python sfhound.py --output-path /tmp/sfhound_$(date +%Y%m%d)Override API version
python sfhound.py --api-version v60.0Example Output - Auto Ingest with Config file
The output below produced a file of 100mb in size, it is based off my personal Salesforce development organisation. This should give you a rough idea of the output from your organisation.
$ python3 sfhound.py --auto-ingest[+] Hydrated 7 aggregate/system PermissionSet placeholder nodes[+] Found 1 organizations[+] Found 25 users[+] Found 51 profiles[+] Found 206 permission sets[+] Found 21 permission set groups[+] Found 23 roles[+] Found 84 groups[+] Found 5 connected apps[+] Found 1260 objects[+] Found 831 fields[+] Graph exported to ./opengraph_output/org-kaibersec.json, happy graphing!Login response status: 200Login response text: {"data":{"user_id":"x","auth_expired":false,"session_token":"x"}}BloodHound API login successful.OpenGraph JSON validation passed (2507 nodes, 45287 edges).[*] Upload job created: 124[*] Uploading orgfarm-ebd8b33ed1-dev-ed_20260304_074333.json ...[+] File uploaded successfully[+] Ingestion started[*] Polling job 124 every 15s (timeout 600s)... [Ingesting] total=0 failed=0 partial=0 [Ingesting] total=0 failed=0 partial=0 [Ingesting] total=0 failed=0 partial=0 [Ingesting] total=0 failed=0 partial=0 [Ingesting] total=0 failed=0 partial=0 [Complete] total=1 failed=0 partial=0 — Complete[+] Ingestion complete: Complete[+] Completed tasks:[ { "ingest_job_id": 124, "file_name": "org-kaibersec.json", "parent_file_name": "", "errors": [], "warnings": [], "id": 94, "created_at": "2026-03-04T07:45:21.587238Z", "updated_at": "2026-03-04T07:45:21.587238Z", "deleted_at": { "Time": "0001-01-01T00:00:00Z", "Valid": false } }]Exit codes
| Code | Meaning |
|---|---|
0 | Success |
1 | Configuration or authentication error |
2 | Extraction error (partial data may have been written) |
3 | Auto-ingest failure (data was extracted but not uploaded) |
Environment variable support
All --flag arguments can optionally be read from environment variables using the SFHOUND_ prefix:
| Flag | Environment variable |
|---|---|
--client-id | SFHOUND_CLIENT_ID |
--username | SFHOUND_USERNAME |
--private-key | SFHOUND_PRIVATE_KEY |
--login-url | SFHOUND_LOGIN_URL |
--bh-password | SFHOUND_BH_PASSWORD |
Subcommands
examples/post_custom_icons.py
Registers custom BloodHound node icons for all SFHound node types.
python examples/post_custom_icons.py \ --bh-url http://127.0.0.1:8080 \ --bh-username admin \ --bh-password YOUR_BLOODHOUND_PASSWORDMust be run once after BloodHound CE is started. Safe to re-run (idempotent).