Skip to main content

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-bearing

It 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.

Who a finding names

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.