Install the verifier¶
etminan-verifier runs on a separate, independently-administered device and
makes every trust decision. It needs no TPM — quote verification is pure
offline signature math. This chapter installs it, generates its identity, starts
the etminan-verifierd trust daemon that owns every trust-changing action,
bootstraps the first admin operator, and enables the hourly attestation timer.
One machine, one role
Do not install the verifier on a machine that also runs etminan-agent. The
verifier is your trust root; its value comes from being unreachable by a host
compromise. Give it its own box.
Install the package¶
The verifier binary is portable, and rides the same signed package as the agent. Import the Etminan Team signing key first, then:
The verifier has no libtss2 requirement, so it builds anywhere Rust does —
including macOS and static musl:
cargo build --release -p etminan-verifier # native (incl. macOS)
cargo zigbuild --release \
--target x86_64-unknown-linux-musl -p etminan-verifier # static musl
Add --features enterprise to build the Enterprise edition (SIEM, dual
control, RBAC). See Editions.
The package creates the etminan-verifier service user, the state directory
/var/lib/etminan-verifier/, and /etc/etminan-verifier/ with a
verifier.env.example to copy.
Configure the verifier¶
Copy the example environment file and review it:
sudo cp /etc/etminan-verifier/verifier.env.example /etc/etminan-verifier/verifier.env
sudo $EDITOR /etc/etminan-verifier/verifier.env
The defaults are sensible for a first deployment (state in
/var/lib/etminan-verifier, a 24-hour pending-review SLA). Notification
channels, change-source correlation, and SIEM output are all off until you
configure them. The complete list is in
Verifier configuration.
Initialize the verifier¶
A fresh verifier needs three things before it can enrol and judge a host: its
own TLS identity, the running etminan-verifierd trust daemon that owns the
single signing key, and a bootstrapped first admin operator.
1. Generate the verifier's TLS identity¶
This writes the verifier's mTLS keypair under /var/lib/etminan-verifier/tls
and prints its SHA-256 certificate fingerprint. Every agent this verifier
talks to pins that fingerprint in ETMINAN_VERIFIER_CERT_FINGERPRINT — copy it
somewhere handy for the first-attestation walkthrough.
2. Start the trust daemon¶
etminan-verifierd performs every trust-changing action — enrol approvals,
baseline decisions, identity changes. Operators never hold a signing key of
their own. The daemon holds the only signing key and signs on an operator's
behalf, attributing each action to operator:<label>. Operators reach it through
etminan-verifier op <command>, and the daemon authenticates every caller by the
kernel-supplied peer credentials of the connection (SO_PEERCRED) — there are no
operator key files to generate, distribute, or protect.
The unit listens on the local socket
/run/etminan-verifierd/etminan-verifierd.sock. Confirm it is up:
Authorization is default-deny / fail-closed: until an identity is enrolled the daemon refuses every trust-changing action, and it records both every allow and every deny to the tamper-evident, hash-chained audit log.
3. Bootstrap the first admin operator¶
The identity registry starts empty, so the very first identity is added by root, once, directly on the verifier host:
--uid is the Unix UID the daemon recognises (over SO_PEERCRED) as this admin;
--label is how it attributes their signed actions. From then on that admin adds
further operators — scoped to a host-group where you want least privilege —
without root:
# an operator confined to the region-A host group
etminan-verifier op identity add --uid 1002 --role operator \
--scope "region-a-*" --label "carol"
etminan-verifier op identity list
Roles are admin, operator, and viewer; an operator is confined to its
host scope. The full model — roles, scopes, revocation, and the optional TOTP 2FA
(off by default) — is in RBAC.
There is no operator key file
Every trust-changing action goes through the daemon over
etminan-verifier op …, authorized by peer-UID and signed with the daemon's
single key. There are no operator key files to generate, distribute, or
protect, and no --key signing path. See RBAC.
Enterprise edition
Dual control (four-eyes approval) builds on this daemon and requires the Enterprise build. It is optional and off by default. RBAC itself is Standard — the daemon above is the default access-control model, not an Enterprise add-on.
Enable the hourly timer¶
The verifier is not a daemon — it runs one complete pass over every enrolled host per invocation, scheduled by a timer:
The timer runs etminan-verifier run hourly (OnBootSec=10min,
OnUnitActiveSec=1h), firing the alarm path on anything wrong. You can always
run a single pass by hand — etminan-verifier run — or check one host
interactively with etminan-verifier check (used in the next chapter).
flowchart LR
timer["etminan-verifier.timer<br/>(hourly)"] --> run["etminan-verifier run"]
run --> loop{"for each<br/>enrolled host"}
loop --> check["request quote · verify ·<br/>replay · diff baseline"]
check --> loop
loop -->|findings| alarm["alarm path<br/>(email / SIEM / plugins)"]
style timer fill:#0f1c18,stroke:#7fd99a,color:#e9efec
style alarm fill:#1e332b,stroke:#7fd99a,color:#e9efec
Next steps¶
- Walk through your first attestation — enrol a host and reach a verified verdict.
- Reference: Verifier configuration · RBAC · The attestation loop.