Copy-paste steps, in order. You need two machines: a verifier (makes every
trust decision, needs no TPM) and each monitored host (runs the agent, needs
a TPM 2.0). Install the signed package on both from
Downloads — apt install ./…deb
or extract the signed tarball — then follow along. The full reference is the
user guide.
Prints a fingerprint — you'll paste it into each agent later.
etminan-verifier keygen-tls
# → note the printed VERIFIER_FP
Two admin keys (kept offline, in separate custody, so one can revoke the
other) and one operational key for day-to-day use. Each also writes a
.pub file with its public-key hex.
etminan-verifier keygen --out admin1.key etminan-verifier keygen --out admin2.key etminan-verifier keygen --out operator.key
Bootstrap the first admin, add the second admin, then authorize the day-to-day key. After this, only registered, active keys can perform trust-changing actions.
etminan-verifier operator-key init --key admin1.key \ --label "admin1 (offline)" --reason "bootstrap registry" etminan-verifier operator-key authorize --pubkey "$(cat admin2.key.pub)" \ --role admin --label "admin2 (offline)" \ --key admin1.key --reason "second admin for recovery" etminan-verifier operator-key authorize --pubkey "$(cat operator.key.pub)" \ --role operational --label "day-to-day" \ --key admin1.key --reason "operational key"
Now move admin1.key and
admin2.key offline and back them up. Use
operator.key for everything below. (Skip this whole step to
run in legacy accountability-only mode — any key is then accepted and only recorded.)
Checks every enrolled host on a timer (hourly) and is the only place an alarm fires.
systemctl enable --now etminan-verifier.timer
etminan-agent keygen-tls
Edit /etc/etminan-agent/agent.env. For the very first
enrollment, opt into the bootstrap mode (accept the verifier before its fingerprint is
pinned); you'll pin the fingerprint right after enrolling.
# /etc/etminan-agent/agent.env ETMINAN_AGENT_LISTEN=0.0.0.0:7620 ETMINAN_WATCHED_PATHS=/usr/bin,/usr/sbin,/etc/systemd/system ETMINAN_ALLOW_PERMISSIVE_TLS=1 # first enrollment only
The policy unit runs once at boot before the agent; the agent then serves quotes.
systemctl enable --now etminan-agent-ima-policy.service etminan-agent.service
Takes a first quote and proves the key lives in a real TPM. It prints an AK fingerprint — confirm it out-of-band (e.g. read it off the host's console) before trusting it.
etminan-verifier enroll --host web-01 --addr <host-ip>:7620 \ --key operator.key --reason "onboard web-01" # Discrete TPM with a manufacturer EK cert? Require genuine hardware: # ... --ek-roots /etc/etminan-verifier/ek-roots/
Back on the host, replace the bootstrap flag with the real fingerprint from step 1.
# /etc/etminan-agent/agent.env ETMINAN_VERIFIER_CERT_FINGERPRINT=<VERIFIER_FP from step 1> # remove the ETMINAN_ALLOW_PERMISSIVE_TLS line, then: # systemctl restart etminan-agent.service
Every measurement from the first quote lands as pending — review once, then bulk-approve the known-good image. The host is now monitored.
etminan-verifier baseline review --host web-01 etminan-verifier baseline approve --host web-01 \ --key operator.key --reason "initial baseline for web-01"
From here the timer (step 4) checks the host automatically and only alarms on drift you haven't approved. Repeat Part 2 + Part 3 for each additional host.
All of these are signed, dated, and appended to the tamper-evident audit log; admin actions need an admin key, day-to-day actions the operational key.
Re-checks all signatures, the audit-log chain, and that every past action was signed by a key authorized for its role at that time. Run any time (or schedule it).
etminan-verifier baseline verify-signatures
Authorize the replacement and retire the old one in a single signed action. History under the old key stays valid; forward actions use the new key.
etminan-verifier keygen --out operator-new.key etminan-verifier operator-key rotate \ --old "$(cat operator.key.pub)" --new "$(cat operator-new.key.pub)" \ --key admin1.key --reason "scheduled rotation"
Time-bounded: actions before the revocation stay valid; at/after are rejected. Pass
--compromised-since if it may have leaked earlier — actions in
that window get flagged for re-review.
etminan-verifier operator-key revoke --pubkey "$(cat operator.key.pub)" \ --key admin1.key --reason "laptop stolen" \ --compromised-since 2026-07-20T00:00:00Z etminan-verifier baseline verify-signatures # re-review any flagged actions
rotate-ak re-binds a host's AK within the same TPM (after a
TPM clear or firmware change) without discarding its baseline.
etminan-verifier operator-key list etminan-verifier rotate-ak --host web-01 \ --key operator.key --reason "TPM cleared"