Configuration
Obexum reads a single YAML config file. Every option below maps to a real key in the scanner; defaults are the values the binary applies when a key is absent. Each top-level section can also be overridden from the environment.
File location & format
The config is YAML. obexum init writes a starter file to
~/.obexum/config.yaml. When you do not pass an explicit
path, Obexum searches the following locations in order and loads the
first obexum.yaml it finds:
./obexum.yaml(current directory)./configs/obexum.yaml/etc/obexum/obexum.yaml~/.config/obexum/obexum.yaml~/.obexum/obexum.yaml
You can point at any file directly with the global
-c / --config flag:
obexum --config /etc/obexum/obexum.yaml scan --target ssh://Administrator@10.0.0.5
obexum init
writes ~/.obexum/config.yaml as your editable starting
point, but the auto-discovery walk looks for files named
obexum.yaml. To have a config picked up automatically,
either pass it with --config, or place an
obexum.yaml in one of the search paths above. Missing
config is not an error — Obexum runs entirely on the documented
defaults.
Environment overrides
Every key can be overridden by an environment variable. The variable
name is the key path, uppercased, with the prefix OBEXUM_
and dots replaced by underscores. For example:
# general.depth -> OBEXUM_GENERAL_DEPTH
# logging.level -> OBEXUM_LOGGING_LEVEL
# target.host -> OBEXUM_TARGET_HOST
export OBEXUM_LOGGING_LEVEL=debug
export OBEXUM_GENERAL_DEPTH=deep
The --log-level flag, when given, takes precedence over
both the config file and OBEXUM_LOGGING_LEVEL for that run.
Validated values
Obexum rejects the config at load time if any of these are out of range:
general.depth— one ofquick,standard,deeptarget.type— one oflocal,ssh,docker,httpstorage.driver— one ofsqlite,postgresoutput.formats— each entry one ofmarkdown,json,html,sarif
general
| Key | Type | Default | Meaning |
|---|---|---|---|
depth | string | standard | Scan depth. One of quick, standard, deep. |
target
Describes the single host to scan. The SSH fields apply when type: ssh.
| Key | Type | Default | Meaning |
|---|---|---|---|
type | string | local | Transport. One of local, ssh, docker, http. |
name | string | localhost | Display name for the target in reports. |
host | string | — | Hostname or IP (used by ssh / http). |
user | string | — | SSH login user. |
port | int | — | SSH port. |
key_path | string | — | Path to the SSH private key. |
key_passphrase | string | — | Passphrase for the SSH key, if encrypted. |
known_hosts_path | string | — | Path to a known_hosts file for host-key checking. |
strict_host_key | bool | false | Enforce strict SSH host-key verification. |
timeout_sec | int | — | Per-connection SSH timeout, in seconds. |
context
Per-target environmental factors fed to the contextual scorer.
| Key | Type | Default | Meaning |
|---|---|---|---|
exposure | string | restricted | Network exposure. One of localhost, internal, restricted, public. |
data_sensitivity | string | regular | Data sensitivity. One of public, regular, high, critical. |
scanners
Controls the external open-source engines. Lynis has its own sub-block.
| Key | Type | Default | Meaning |
|---|---|---|---|
enabled | list<string> | [lynis] | Which external scanners to run. |
lynis.binary_path | string | lynis | Path to the Lynis executable. |
lynis.tests | list<string> | — | Specific Lynis tests to run (empty = all). |
lynis.skip | list<string> | — | Lynis tests to skip. |
lynis.timeout_sec | int | 1800 | Lynis run timeout, in seconds. |
rules
The deterministic rule engine (default detection path).
| Key | Type | Default | Meaning |
|---|---|---|---|
enabled | bool | true | Enable the deterministic rule engine. |
extra_dir | string | — | Optional path to a directory of custom rules. |
audit
Controls the native Obexum audit framework (the built-in check catalogue).
| Key | Type | Default | Meaning |
|---|---|---|---|
enabled | bool | true | Enable the native audit checks. |
concurrency | int | 8 | Number of checks run in parallel. |
check_timeout | int | 60 | Per-check timeout, in seconds. |
only_ids | list<string> | — | Run only these check IDs (exact match). |
skip_ids | list<string> | — | Skip these check IDs. |
only_categories | list<string> | — | Run only checks in these categories. |
include_opt_in | bool | false | Enable opt-in checks (e.g. the cloud-credential-at-rest batch: AWS/GCP/Azure/Docker/kube/netrc/git). |
include_experimental | bool | false | Enable experimental checks. Their findings carry an experimental tag. |
audit.threat_intel
External threat-feed consumers. All providers default to disabled, which
is air-gapped-safe. With enable_external_apis: false (the
default) every API-based check is forced to skip regardless of whether a
key is set, preventing accidental egress. Enabling these reveals peer IPs
to the external service.
| Key | Type | Default | Meaning |
|---|---|---|---|
enable_external_apis | bool | false | Master switch for all external reputation APIs. |
abuseipdb_api_key | string | — | AbuseIPDB API key. |
greynoise_enabled | bool | false | Use the GreyNoise community API (no key, but still egress). |
virustotal_api_key | string | — | VirusTotal API key. |
enrichment
Threat-intel enrichment of findings (EPSS, KEV, distro security trackers).
| Key | Type | Default | Meaning |
|---|---|---|---|
enabled | bool | true | Enable the enrichment layer. |
cache_dir | string | ./cache/enrichment | Directory for cached enrichment data. |
ttl_hours | int | 24 | Cache time-to-live, in hours. |
epss | bool | true | Annotate CVEs with EPSS exploit-probability scores. |
kev | bool | true | Flag CVEs present in the CISA KEV catalogue. |
tracker.enabled | bool | true | Enable distro security-tracker cross-check. |
tracker.debian | bool | true | Cross-check against the Debian Security Tracker. |
tracker.ubuntu | bool | true | Cross-check against Ubuntu USN. |
reasoning
The optional LLM reasoning layer. It is opt-in —
enabled defaults to false, and the
deterministic rule engine is the default detection path. Prefer
supplying the API key via an environment variable named by
api_key_env rather than putting it in the file.
| Key | Type | Default | Meaning |
|---|---|---|---|
enabled | bool | false | Enable the LLM reasoning layer. |
api_key_env | string | ANTHROPIC_API_KEY | Name of the environment variable holding the API key. |
api_key | string | — | API key set directly (less secure; prefer api_key_env). |
cache_dir | string | ./cache/reasoning | Directory for cached LLM responses. |
cache_ttl_days | int | 7 | Cache time-to-live, in days. 0 = no expiry. |
os_hint | string | debian | OS hint passed to the reasoning prompts. |
config_analyzer | bool | true | Enable the config-analyzer component. |
chain_finder | bool | true | Enable the attack-chain finder component. |
context_filter | bool | true | Enable the context-filter component. |
remediation | bool | true | Enable LLM-authored remediation guidance. |
scoring
| Key | Type | Default | Meaning |
|---|---|---|---|
model | string | contextual | Scoring model. One of cvss, contextual, kev-weighted. |
output
| Key | Type | Default | Meaning |
|---|---|---|---|
formats | list<string> | [markdown, json] | Report formats to emit. Each one of markdown, json, html, sarif. |
path | string | ./reports | Directory for the flat report output. |
engagement_dir | string | — | When set, also writes a per-scan engagement directory at <engagement_dir>/<scan_id>/ with manifest.json, each selected format as findings.<ext>, scan.log, and an artifacts/ subdir. Empty keeps the flat path layout. |
storage
| Key | Type | Default | Meaning |
|---|---|---|---|
driver | string | sqlite | History/diff store backend. One of sqlite, postgres. |
dsn | string | ./obexum.db | Data-source name for the store (SQLite file path or Postgres DSN). |
logging
| Key | Type | Default | Meaning |
|---|---|---|---|
level | string | info | Log level. One of trace, debug, info, warn, error. |
format | string | console | Log format. One of console, json. |
Example config file
A complete ~/.obexum/config.yaml for an SSH scan of a
Windows target, using only real keys:
general:
depth: standard # quick | standard | deep
target:
type: ssh # local | ssh | docker | http
name: prod-dc-01
host: 10.0.0.5
user: Administrator
port: 22
key_path: ~/.obexum/keys/obexum_ed25519
strict_host_key: false
context:
exposure: internal # localhost | internal | restricted | public
data_sensitivity: high # public | regular | high | critical
audit:
enabled: true
concurrency: 8
check_timeout: 60
only_categories: [identity, crypto, network, persistence, threat, logging, forensic, integrity]
include_opt_in: false
include_experimental: false
threat_intel:
enable_external_apis: false # air-gapped-safe default
scanners:
enabled: [lynis]
lynis:
binary_path: lynis
timeout_sec: 1800
rules:
enabled: true
enrichment:
enabled: true
epss: true
kev: true
tracker:
enabled: true
debian: true
ubuntu: true
reasoning:
enabled: false # opt-in LLM layer
api_key_env: ANTHROPIC_API_KEY
scoring:
model: contextual # cvss | contextual | kev-weighted
output:
formats: [json, html] # markdown | json | html | sarif
path: ~/.obexum/reports
engagement_dir: ~/.obexum/scans
storage:
driver: sqlite # sqlite | postgres
dsn: ~/.obexum/obexum.db
logging:
level: info # trace | debug | info | warn | error
format: console # console | json
obexum init — it writes a ready-to-edit
~/.obexum/config.yaml with these defaults, creates
~/.obexum/scans/, and points storage.dsn at a
local SQLite database.