Configuration
Two files. Both hot-reload: save, and the running agent picks the change up within about two seconds. An invalid edit is rejected and the previous version stays live.
/etc/lumen/agent.yaml, where things live
agent:
listen: "127.0.0.1:7645" # or "unix:/run/lumen/agent.sock"
policy: /etc/lumen/policy.yaml
spool: /var/lib/lumen/spool.db # durable queue, survives restarts
findings: /var/lib/lumen/findings.jsonl
# intel: /var/lib/lumen/intel.bloom # threat-intel snapshot
reload_interval: 2s
policy: is load-bearingIt is the only thing that makes /etc/lumen/policy.yaml get read. Leave it
unset, either commented out or as an explicit policy: "", and the agent runs
the policy compiled into the binary instead, and stays on it. That policy
only logs, so nothing breaks loudly: an edit to policy.yaml changes nothing,
and a policy the console assigns is skipped too, because the agent writes it
through that file. The installers warn about it, and
lumen-agent policy effective always says which one is live
(policy source: embedded).
A proxy: section makes run serve the capturing proxy
alongside the inspection API. One engine, one policy store, one findings
file. The two listeners need separate addresses because they share a process.
agent:
proxy:
listen: "127.0.0.1:7646"
attribute_user: true # default: name whoever made each request
attribute_user decides whether a finding names a person. The agent runs as a
service account and serves every account on the machine, so it cannot tell who
sent a request from its own process — it resolves the account that owns the
process at the other end of the connection instead, per request. Turn it off and
findings carry the hostname and no user, which is what you want if you monitor
this machine's AI traffic without attributing it to individuals.
With attribution off, or when the owner cannot be resolved, the console falls back to the single user this endpoint was enrolled under, and shows "—" if there is not one. Tools that run as the person — the Claude Code hook, the MCP proxy, the browser extension — always name them regardless of this setting.
An inventory: section controls the AI-agent inventory — the scan that reports
which AI tools are present on the host, shown per machine and fleet-wide in the
console (Endpoints). It is on by default.
agent:
inventory:
enable: true # default: scan for AI tools on the host
attribute_user: false # default: report the machine, not the person
enable turns the scan on or off; off, the endpoint reports no inventory.
attribute_user is the same choice as the proxy's, and defaults the other way:
the inventory names the machine always and the person running a tool only
when you turn this on. It is a fleet-visibility feature you may want without
naming individuals, so naming them is the opt-in. The inventory is discovery
only — it records that a tool is present, never anything it sent.
/etc/lumen/policy.yaml, what to do about what
A packaged fresh install ships this file in monitor mode: every rule's
action is log. The policy the console assigns on enrollment, Local default,
logs every rule too, so a fresh endpoint redacts and blocks nothing whether it
is connected or not. On an enrolled machine the console owns this file and
promoting happens there; on a machine that
was never enrolled, promoting a rule here is a one-word change:
- id: pr_secrets
detector: sensitive_data
subclasses: [credentials, financial, pii]
applies_to: [prompt, response]
action: log # <- change to `redact` to start stripping secrets
The full grammar, covering access rules, thresholds, custom definitions and precedence, is in Policy file format.
Check before trusting
lumen-agent policy validate --policy /etc/lumen/policy.yaml
# policy pol_packaged_monitor v1 valid (bundle sha256 993496456bd5)
lumen-agent policy effective --config /etc/lumen/agent.yaml
# policy source: /etc/lumen/policy.yaml
# policy id: pol_packaged_monitor version 1 sha256 993496456bd5
# mode: MONITOR - every detector the policy references runs and nothing is redacted or blocked
On a connected endpoint policy effective also asks the running daemon for the
console's enforcement ceiling. A policy whose every rule logs, Local default
included, has nothing for the ceiling to hold back and reads MONITOR - every detector the policy references runs and nothing is redacted or blocked at
either setting. For a policy with promoted rules, under Monitoring the mode
line reads MONITOR (console ceiling); the policy would: pr_injection=block ...,
and when the daemon is not answering it says the ceiling is unknown rather
than claiming ENFORCING. Right after the agent starts, before its first heartbeat, the line
reads MONITOR (agent default until the console's first heartbeat): the agent
holds every rule at log until the console states the endpoint's mode. A rule on malicious_entity (pr_malicious_url) is listed as
INACTIVE when no agent.intel snapshot is configured: without one its detector
is not registered and the rule cannot fire.
Upgrades never overwrite your edited config files. That is exactly why a
hand-edited agent.yaml that dropped the policy: key keeps running the
embedded policy across upgrades, ignoring policy.yaml and the console's
assignment, until someone reads the warning.