Writing a collector
A collector is anything that observes some state — a server, a database, a cloud account, a config file — and produces a Ledvar snapshot. The protocol guarantees the hashing; how you turn the real world into nodes is your modeling decision, and a handful of choices decide whether your drift is clean or noisy.
This is the hands-on companion to the normative modeling guide.
The shape of a fact
Each node is identity + content + labels + refs:
path— the node’s identity. Must be stable (doesn’t change when irrelevant things change) and unique. A bad identity produces churn: don’t key a process by PID, or a firewall rule by line number.content— the observed values, as sets of strings. This is what, when it changes, is drift.labels— human notes. Never hashed, never drift.refs— annotation edges to other nodes. Never hashed.
The four rules that matter most
- Choose a stable identity. “If this thing is unchanged but the world around it shifts, does its path stay the same?” If not, pick a different path.
- Everything is a string — normalize it.
"0.5"≠"0.50";"ACCEPT"≠"accept". Pick one canonical form per attribute and emit it the same way every time. - Sets are unordered and de-duplicated. If order matters, encode the position into the value —
a firewall chain evaluated top-to-bottom becomes
["0:allow tcp:22", "1:allow tcp:80", "2:deny all"]; a bare set would hash the same in any order, hiding a reorder. - Be complete for your scope. A missing node reads as removed. Emit the whole state of your scope, or narrow the scope so “complete” is something you can guarantee.
A minimal example
Observing two files and emitting a snapshot:
{
"protocol_version": "0.1.0",
"origin_id": "web-01",
"provider_name": "files",
"timestamp": 1718800000,
"tree": [
{ "path": ["files", "/etc/ssh/sshd_config"],
"content": { "mode": ["0600"], "owner": ["root"] } },
{ "path": ["files", "/etc/hosts"],
"content": { "mode": ["0644"], "owner": ["root"] } }
]
}
This page is a starting point — a fuller, worked walkthrough (a real iptables / cloud collector) is coming. For the complete set of modeling rules, read the modeling guide.