etminan
Quick start

From the package to a monitored host.

Copy-paste steps, in order. You need two machines to start: 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 dnf install ./…rpm — then follow along. The full reference is the user guide.

A third machine comes later, and is worth planning for now: the small etminan-witness package checks the verifier's own signed evidence somewhere the verifier is not. Nothing here needs it, and everything here works without it — but evidence checked only on the machine that produced it has not been checked.

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

Bootstrap the first admin

Operators are identified by their Unix user, not a key file — the RBAC daemon (etminan-verifierd) authenticates every caller by their kernel UID (SO_PEERCRED, unforgeable for non-root). Bootstrap the genesis admin once, as root, binding an admin UID. Start the daemon first — every op command talks to it over its local socket:

# Start the RBAC daemon (the package installs but does not auto-enable it).
sudo systemctl enable --now etminan-verifierd.service

# One-time, run as root. Binds this UID as the first admin.
sudo etminan-verifier op bootstrap --uid 1000 --label "admin1"
3

Map operator identities

The admin maps each operator's Unix UID to a role (and, for operators, a host-group scope). The matrix is default-deny: an unmapped or revoked UID is refused every trust-changing action. Roles are admin (manages the registry, unscoped), operator (day-to-day, confined to a scope), and viewer (read-only).

# A second admin (for recovery) and a day-to-day operator, by UID.
etminan-verifier op identity add --uid 1001 --role admin --label "admin2 (recovery)"
etminan-verifier op identity add --uid 1002 --role operator --scope "web-*" --label "day-to-day"

Operators now act as their own OS user — no key file to distribute or protect; the daemon holds the one signing key and signs on their behalf. Where policy requires it, an operator runs op login (TOTP) first.

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 op enroll web-01 --addr <host-ip>:7620 --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 op review web-01
etminan-verifier op approve 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 — identities & rotation

Rotate, revoke, and verify.

All of these are signed, dated, and appended to the tamper-evident audit log; admin actions require an admin-role UID, day-to-day actions an operator-role UID — the daemon enforces which by Unix identity and holds the one signing 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 op verify-signatures

Add or list operators

Operators are UIDs, not keys, so there's nothing to rotate — you just manage the registry. Any admin adds or lists identities; a new operator can act immediately, with no key handover.

etminan-verifier op identity add --uid 1003 --role operator --scope "db-*" --label "db team"
etminan-verifier op identity list

Revoke an operator

When someone leaves or a machine is lost, revoke their UID. Their past actions stay valid; from then on that UID is refused every trust-changing action (default-deny).

etminan-verifier op identity revoke --uid 1002

etminan-verifier op verify-signatures   # re-check the signed history + audit chain

Rotate a host's attestation key

op 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 op rotate-ak web-01 --reason "TPM cleared"