etminan
Quick start

From the package to a monitored host.

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 Downloadsapt install ./…deb or extract the signed tarball — then follow along. The full reference is the user guide.

Part 1 — On the verifier

Set up the verifier and your keys.

1

Give the verifier a TLS identity

Prints a fingerprint — you'll paste it into each agent later.

etminan-verifier keygen-tls
# → note the printed VERIFIER_FP
2

Generate operator keys

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
3

Turn on authorization (the operator-key registry)

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

4

Schedule automatic checks

Checks every enrolled host on a timer (hourly) and is the only place an alarm fires.

systemctl enable --now etminan-verifier.timer
Part 2 — On each monitored host

Set up the agent (the client).

5

Give the agent its own TLS identity

etminan-agent keygen-tls
6

Point it at the verifier and pick what to watch

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
7

Load the IMA policy and start the agent

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
Part 3 — Enroll the client

Bring the host under monitoring (run on the verifier).

8

Enroll the host

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/
9

Pin the verifier at the agent, then restart it

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
10

Approve the initial baseline

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.

Ongoing — key management

Rotate, revoke, and verify.

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.

Verify every signature and authorization

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

Rotate the day-to-day key

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"

Revoke a compromised key

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

List keys, or rotate a host's attestation key

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"