Skip to content

CLI reference

The exhaustive command reference for the Etminan binaries. Every subcommand and sub-subcommand that etminan-verifier, etminan-verifierd, and etminan-agent dispatch is documented here with its one-line purpose, full synopsis (every flag, with type and default where the source reveals it), and at least one worked example.

This page is grounded in the same facts as the in-terminal --help (verifier/src/help.rs, verifier/src/daemon_client.rs) and the actual argument parsing in verifier/src/cli.rs / agent/src/main.rs. It is the authoritative operator reference; man etminan-verifier / man etminan-verifierd / man etminan-agent remain the deeper source for the complete ETMINAN_* environment variable, FILES, and EXIT STATUS lists.

The operator interface is the daemon — there are no operator key files

Every trust-changing action goes through etminan-verifier op <cmd>, which talks to the local etminan-verifierd daemon over a Unix socket. The daemon authenticates the caller by kernel peer-UID (SO_PEERCRED) — there is no operator key file to pass, and the daemon (not the operator) holds the only Ed25519 signing key and signs on the operator's behalf as operator:<label>. Roles are admin / operator / viewer, the model is default-deny / fail-closed, and every decision — allow and deny — is written to the audit log. This is Standard (free) behaviour, not Enterprise. See op below.

There is no --key back door and no root break-glass path: op is the sole way to enrol, approve, reject, exclude, assign a profile, or rotate a key. The read/attest commands (check, run, baseline review, baseline verify-signatures, plugins …, notify-…) stay open and take no key either.

Conventions used throughout this page

  • No operator key files exist. Authorization is the caller's kernel UID, mapped by the daemon to a role and scope. Whatever the invoking Unix user's UID is allowed to do is exactly what op can do; nothing more.
  • Several op verbs require a non-empty --reason <text> (enrol, exclude create/revoke, key rotation, dual-control policy). The reason is signed into the payload by the daemon and appended to the audit log. A --reason (or any other required flag) that is missing, empty, or whitespace-only is rejected (--<name> is required and cannot be empty) — a blank justification can never be signed.
  • The host is a positional argument on the op verbs that take one (op enroll <host>, op approve <host>, op check <host>, …) — it is rest[0], read strictly as the first token and never scanned past a flag.
  • Flag parsing is a minimal --flag value scanner. A flag whose next token is itself ---prefixed is treated as present-but-empty (the next token is reparsed as its own flag), so --addr --reason x sets addr="" and still registers --reason.
  • --help / -h is honoured anywhere in a subcommand's own argument list (e.g. baseline review --host web-01 --help works), and is checked before the command runs — no partial/invalid invocation ever executes first.
  • version / --version / -V prints the binary version (0.10.2) and exits 0, recognised before subcommand dispatch on both binaries.
  • Commands marked Enterprise are compiled only into the enterprise build; a Standard binary has no such capability and its help never mentions it. See Editions.
  • An unknown subcommand exits 2 (usage error), reserving 1 for a runtime failure inside a recognised command.

Table of contents

etminan-verifier

etminan-verifierd

etminan-agent


etminan-verifier

The verifier makes every trust decision. Its top-level dispatch is a match subcommand over a small set of families. The primary operator interface is the op command group, which forwards each trust-changing action to the etminan-verifierd daemon — the daemon authenticates the caller by kernel UID and signs the canonical payload with the one daemon-held key before appending it to the hash-chained audit log. The remaining top-level subcommands are read/attest and setup only: check, run, keygen-tls, keygen-catalog, baseline, plugins, notify-preview, notify-test. An unknown subcommand exits 2.

etminan-verifier op

The only interface for every trust-changing action. etminan-verifier op <cmd> is a thin client: it opens the local etminan-verifierd socket (ETMINAN_VERIFIERD_SOCKET, default /run/etminan-verifierd/etminan-verifierd.sock), sends one request, prints the response, and exits. The daemon reads the caller's kernel-supplied peer credentials (SO_PEERCRED), maps the UID to a registered identity, and applies that identity's role and scope. No key file is passed and none is held by the operator — the daemon owns the single Ed25519 signing key and signs on the operator's behalf as operator:<label>. The model is default-deny / fail-closed: an unmapped UID, an out-of-scope host, or an unreachable daemon is a refusal, and both the allow and the deny are written to the audit log.

Standard (free) — not Enterprise

The daemon, the op interface, the admin/operator/viewer roles, and the optional per-role TOTP second factor are all part of the Standard, free edition and are the default access-control model. Only SIEM output (CEF/LEEF) and dual-control / four-eyes approval remain Enterprise. See Editions and RBAC.

Command Purpose
op whoami Show the identity and role the daemon maps your UID to.
op login Open an authenticated session (supply --code when TOTP is required for your role).
op logout End the current session immediately.
op enroll <host> Enrol a host through the daemon (daemon-signed; --reason required).
op enroll-totp Enrol your own TOTP second factor.
op review [<host>] List pending measurements (all hosts, or one).
op check <host> Run one attestation check of a host.
op verify-signatures Verify every signature, the audit chain, and the registry.
op approve <host> Approve a host's pending baseline (optionally one --matching/--hash).
op reject <host> Reject a specific pending measurement as a confirmed incident.
op exclude create / revoke / list exclusion rules.
op assign-profile <host> Push a watched-path profile selection to a host.
op rotate-tls <host> Re-pin a host's TLS certificate after its agent regenerates its keypair.
op rotate-ak <host> Re-bind a host's AK within the same TPM, without re-enrolling.
op identity list / add / revoke in the UID→identity registry.
op bootstrap One-time, root-only: seed the first admin identity.
op totp-policy Set whether a role must present a TOTP code (admin only).
op dual-control-policy show / set the signed four-eyes latch (Enterprise).
op ping Liveness check against the daemon socket.

op whoami

Print who the daemon believes you are — the identity your kernel UID maps to and its role (admin / operator / viewer). Pure read; the first command to run when a call is unexpectedly refused. An unmapped UID prints that it has no role and can do nothing until an admin maps it.

etminan-verifier op whoami

Takes no flags.

etminan-verifier op whoami
uid 1007 — role 'operator'

op login

Open (or refresh) an authenticated session for your UID. When totp-policy marks your role as requiring a second factor, pass the current RFC 6238 code with --code; the session then lasts ETMINAN_TOTP_SESSION_TTL_SECS (default 28800 = 8h). If --code is omitted, op login prompts for it on stderr. With TOTP off for your role, login simply confirms the mapping.

etminan-verifier op login [--code <n>]
Flag Type Default Notes
--code <n> integer prompted The current TOTP code. Required when your role's TOTP policy is required; if omitted, op login prompts for it.
etminan-verifier op login --code 481920

op logout

End the current authenticated session now, before its TTL expires — the next trust-changing op call will require a fresh login.

etminan-verifier op logout

Takes no flags.

etminan-verifier op logout

op enroll

Enrol a monitored host through the daemon: the daemon takes and self-validates a first quote (refusing a malformed/self-inconsistent quote rather than seed a bad baseline), pins the host's AK and TLS fingerprints (trust-on-first-use), and records every measurement from that quote as a pending baseline candidate. It authorizes the caller by UID and signs the enrollment record with its own key (operator:<label>). Confirm the printed AK fingerprint out of band before trusting it.

etminan-verifier op enroll <host> --addr <ip:port> --reason <why> [--force] [--ek-roots <dir>]
Argument / flag Type Default Notes
<host> string required (positional) Identifier this host is known by from now on.
--addr <ip:port> socket addr required Where the agent is listening.
--reason <why> string required Folded into the signed enrollment record and audited.
--force boolean flag off Re-enrol an already-enrolled host, discarding its pinned AK/TLS identity. Only after re-confirming the new AK fingerprint out of band.
--ek-roots <dir> path none Require manufacturer EK-certificate provenance: the host's EK cert must chain by signature to a self-signed root CA in <dir> (PEM or DER; RSA CAs only). Without it, enrollment relies on EK credential activation alone (a vTPM passes); with it, a host whose TPM ships no EK cert is refused.
etminan-verifier op enroll web-01 --addr 10.0.3.11:7620 \
  --reason "initial onboarding of web tier" \
  --ek-roots /etc/etminan-verifier/ek-roots/

op enroll-totp

Enrol your own TOTP second factor with the daemon (RFC 6238), so that once your role's totp-policy is required you can pass --code at op login. This is your personal 2FA self-enrolment, distinct from host enrollment (op enroll).

etminan-verifier op enroll-totp

Takes no flags.

etminan-verifier op enroll-totp

op review

List every pending (new or changed, not yet approved) measurement, optionally filtered to one host. Each entry prints a plain-language ownership verdict, a change-source-correlation line (if configured), a package trust line (if a package match exists), and the raw sha256/owner/size/mtime detail. Entries older than ETMINAN_PENDING_REVIEW_SLA_HOURS (default 24) are marked [SLA EXCEEDED]. Pure read. Also available directly as baseline review.

etminan-verifier op review [<host>]
Argument Type Default Notes
<host> string all hosts Optional positional; restrict to one host.
etminan-verifier op review web-01

op check

Run one attestation check of an enrolled host through the daemon: fresh quote, verify signature and AK fingerprint against the enrollment record, replay the IMA log against the signed PCR digest, and diff new measurements against the approved baseline. The same check logic is available without the daemon as top-level check.

etminan-verifier op check <host> --addr <ip:port>
Argument / flag Type Default Notes
<host> string required (positional) The enrolled host to check.
--addr <ip:port> socket addr required Where its agent is listening.
etminan-verifier op check web-01 --addr 10.0.3.11:7620

op verify-signatures

Re-verify every approval batch signature, every exclusion rule's create/revoke signature, every rejection's signature, the UID→identity registry, and the full audit-log hash chain, in one pass through the daemon. The same check is available directly as baseline verify-signatures.

etminan-verifier op verify-signatures

Takes no flags.

etminan-verifier op verify-signatures

op approve

Approve a host's pending baseline items. The bare form approves every pending item for one host in a single signed batch. The --matching/--hash form approves one specific hash for a path that has more than one pending candidate — the two flags must be given together (supplying one without the other is a usage error). Requires your identity to have operator (or admin) role and the host to fall within your scope; an out-of-scope host is refused and audited.

etminan-verifier op approve <host> [--matching <path> --hash <sha256>]
Argument / flag Type Default Notes
<host> string required (positional) The host whose pending items to approve. Must be in your scope.
--matching <path> string none Approve one specific pending path. Must be given with --hash.
--hash <sha256> hex none The exact hash to approve for that path. Must be given with --matching.
# Approve every pending item for web-01:
etminan-verifier op approve web-01

# Approve one specific hash for a path that has two pending candidates:
etminan-verifier op approve web-01 --matching /usr/bin/openssl --hash 3f9a…e1

op reject

Reject a specific pending measurement as a confirmed incident — fires the full alarm path immediately, the same as a run finding. Use the exact --path and --hash from op review, not from memory.

etminan-verifier op reject <host> --path <p> --hash <sha256>
Argument / flag Type Default Notes
<host> string required (positional) The host the measurement was seen on.
--path <p> path required Exact path from op review.
--hash <sha256> hex required Exact hash from op review.
etminan-verifier op reject web-01 --path /usr/sbin/sneaky --hash deadbeef…

op exclude

Manage exclusion rules: paths (or trailing-* glob prefixes) that should never generate a pending-review entry — for paths expected to churn with no security-relevant content. create and revoke are admin; list is a read.

etminan-verifier op exclude create --path <p> --reason <r> [--host <h>] [--confirm yes]
etminan-verifier op exclude revoke --id <n> --reason <r>
etminan-verifier op exclude list
Sub-action Flag Type Default Notes
create --path <p> string required Exact path, or trailing-* prefix (a plain string prefix — /etc* also matches /etcxyz; write /etc/*).
create --reason <r> string required Signed, audited.
create --host <h> string all hosts Scope the rule to one host; omit for a global (every-host) rule.
create --confirm yes literal required when --path ends in * Confirms after a preview of how many approved measurements the glob would affect.
revoke --id <n> integer required Rule id from exclude list.
revoke --reason <r> string required Revoking re-exposes what the rule hid — as consequential as creating it.
list (none) Show every rule with its scope.
etminan-verifier op exclude create --path '/var/log/*' --confirm yes \
  --host web-01 --reason "rotating logs, no security content"

etminan-verifier op exclude list

etminan-verifier op exclude revoke --id 7 --reason "log dir now security-relevant"

op assign-profile

Push a watched-path profile selection (never the profile's contents, which stay local to the agent) to an enrolled host over its existing mTLS channel. Only recorded locally if the agent acknowledges it took effect. The named profile must already exist in that host's profiles.conf.

etminan-verifier op assign-profile <host> --profile <name>
Argument / flag Type Default Notes
<host> string required (positional) The enrolled host to reassign.
--profile <name> string required Must already exist in that host's profiles.conf.
etminan-verifier op assign-profile web-01 --profile web-frontend

op rotate-tls

Re-pin a host's TLS certificate fingerprint after its agent-side keypair is regenerated (etminan-agent keygen-tls), without a full re-enrollment. Requires the host's AK fingerprint to still match and continues the PCR 10 replay from the stored cumulative value. AK trust and the approved baseline are untouched.

etminan-verifier op rotate-tls <host> --reason <why>
Argument / flag Type Default Notes
<host> string required (positional) The host whose agent TLS keypair changed.
--reason <why> string required Signed, audited action.
etminan-verifier op rotate-tls web-01 --reason "agent host re-provisioned, new TLS key"

Rotating the verifier's own certificate

That is a manual procedure, not this subcommand: run keygen-tls again, update ETMINAN_VERIFIER_CERT_FINGERPRINT in every agent's agent.env, then restart each agent — in that order.

op rotate-ak

Re-bind a host's attestation key (AK) to a new one within the same TPM, without a full re-enrollment (baseline, TLS pin, PCR replay state preserved). A fresh EK credential-activation ceremony proves the new AK resides in the same TPM as the EK on record; a different EK means a different TPM and is refused (that's a deliberate re-enroll). Use after a TPM owner-clear/firmware change or a precautionary rotation.

etminan-verifier op rotate-ak <host> --reason <why> [--ek-roots <dir>]
Argument / flag Type Default Notes
<host> string required (positional) The host whose AK changed.
--reason <why> string required Signed, audited action.
--ek-roots <dir> path none Also re-verify the manufacturer EK-cert chain, same as op enroll --ek-roots.
etminan-verifier op rotate-ak web-01 --reason "TPM owner-cleared after mainboard swap"

op identity

Manage the UID→identity registry the daemon enforces. list is readable by any mapped identity; add and revoke are admin-only. This registry lives in baseline.db and is the model that replaces per-operator key files.

etminan-verifier op identity list
etminan-verifier op identity add --uid <n> --role <admin|operator|viewer> --scope <host-globs> --label <name>
etminan-verifier op identity revoke --uid <n>
Sub-action Flag Type Default Notes
list (none) Every mapping: UID, role, scope, label.
add --uid <n> integer required The kernel UID to map.
add --role <r> string required admin, operator, or viewer.
add --scope <host-globs> string required Restrict the identity to a host group (comma-separated globs, e.g. region-a-*). Must be explicit — an omitted scope is refused, never silently fleet-wide. Use --scope '*' to deliberately grant every host.
add --label <name> string required Human label; appears in audit rows as operator:<label>.
revoke --uid <n> integer required The UID mapping to remove.
etminan-verifier op identity list

etminan-verifier op identity add --uid 1007 --role operator \
  --scope 'region-a-*' --label bob

etminan-verifier op identity revoke --uid 1007

--scope is mandatory

identity add refuses an omitted or empty --scope — the one field that bounds a scoped operator's blast radius must never fail open to the widest value. Pass a real host-group scope, or --scope '*' to knowingly grant every host.

op bootstrap

One-time genesis: seed the first admin identity so the registry has an owner. Must be run as root on the verifier host, and only when no admin identity exists yet; the action is recorded in the audit log. After this, further identities are added with op identity add.

etminan-verifier op bootstrap --uid <n> --label <name>
Flag Type Default Notes
--uid <n> integer required The UID to install as the first admin.
--label <name> string required Human label for that admin identity.
sudo etminan-verifier op bootstrap --uid 1000 --label alice

Development-only insecure bootstrap

ETMINAN_VERIFIERD_ALLOW_INSECURE_BOOTSTRAP relaxes the bootstrap preconditions for DEV/TEST only and must never be set in production. See Verifier configuration.

op totp-policy

Set, per role, whether an authenticated session requires a TOTP second factor. Optional (RFC 6238), off by default, and admin only. When a role is set --required true, its members must present --code at op login (after enrolling their factor with op enroll-totp).

etminan-verifier op totp-policy --role <admin|operator|viewer> --required <true|false>
Flag Type Default Notes
--role <r> string required The role whose policy to set.
--required <bool> boolean required true/yes/on/1 to require TOTP for that role, false/no/off/0 to relax it.
etminan-verifier op totp-policy --role admin --required true

op dual-control-policy

Enterprise edition

Optional four-eyes / separation-of-duties approval, off by default and present only in the Enterprise build. When enabled for the baseline-approve action, an op approve records a PENDING request over the exact payload, and a second, distinct authorized operator must co-sign the same payload before it applies. The policy itself is a signed, latched value stored in the daemon; changing it is itself four-eyes — a second admin must co-sign the change before it takes effect.

show prints the effective policy (which actions require four-eyes, and the threshold). set is admin-only and changes the latch.

etminan-verifier op dual-control-policy show
etminan-verifier op dual-control-policy set --actions baseline-approve [--threshold <n>] --reason <r>
Sub-action Flag Type Default Notes
show (none) Print the current latched policy, or that none is set.
set --actions <a> string required The action token(s) to require four-eyes on. baseline-approve is the only supported token in this release; off/none/empty disables.
set --threshold <n> integer 2 Distinct approvers required (M-of-N); clamped up to a floor of 2.
set --reason <r> string required Signed, audited.
etminan-verifier op dual-control-policy show

etminan-verifier op dual-control-policy set --actions baseline-approve --threshold 2 \
  --reason "enforce four-eyes on baseline approvals"

op ping

Liveness probe: confirm the daemon socket is present and answering. Prints pong and exits 0 on success; a non-zero exit means the daemon is down or the socket is unreachable (and, because the model is fail-closed, that every trust-changing op call would currently be refused).

etminan-verifier op ping

Takes no flags.

etminan-verifier op ping
pong

Setup keys

Run these once when standing up a verifier device. The two keys are deliberately separate — the mTLS transport identity (keygen-tls) and the off-host plugin-catalog signing key (keygen-catalog) — so rotating one never rotates the other. (The operator signing key is held by the daemon, not generated here; there is no operator-key CLI.)

Command Purpose
keygen-tls Create this verifier's own mTLS identity and print its SHA-256 fingerprint.
keygen-catalog Off-host, run-once: the dedicated plugin-catalog signing keypair.

keygen-tls

Generate this verifier's own self-signed mTLS keypair under $ETMINAN_TLS_DIR (default /var/lib/etminan-verifier/tls) and print its SHA-256 fingerprint. Copy that fingerprint into ETMINAN_VERIFIER_CERT_FINGERPRINT in every agent's agent.env. Run once per verifier device, before its first op enroll or run.

etminan-verifier keygen-tls

Takes no flags.

etminan-verifier keygen-tls
Generated verifier TLS keypair at /var/lib/etminan-verifier/tls
Fingerprint (sha256): 4d1e…c0ffee
Copy this fingerprint into ETMINAN_VERIFIER_CERT_FINGERPRINT in every agent.env …

keygen-catalog

Generate the dedicated single-purpose Ed25519 keypair a real plugin-catalog release would be signed with — deliberately not the same key that signs operator actions and not the GPG release key. Run once, offline, wherever catalog releases are built — never on a verifier host.

etminan-verifier keygen-catalog --out <path>
Flag Type Default Notes
--out <path> path required Private key (mode 0600). Replace CATALOG_VERIFYING_KEY_HEX in verifier/src/plugin_catalog.rs with the printed public key, then rebuild.
etminan-verifier keygen-catalog --out ./catalog-signing.key

Hosts

The read/attest side of host monitoring. Enrolling, rotating keys, and assigning profiles are trust-changing and live under op (op enroll, op rotate-tls, op rotate-ak, op assign-profile). The two commands here take no key and make no trust change.

Command Purpose
check Check one enrolled host now, interactively.
run Check every host + plugins + audit chain and fire alarms (the scheduled job).

check

Check one enrolled host interactively: fresh quote, verify signature and AK fingerprint against the enrollment record, replay the IMA log against the signed PCR digest, and diff new measurements against the approved baseline. Prints FINDING (<kind>): … and exits 1 if anything failed — an unreachable host is itself a finding, not a soft skip. (Also available as op check.)

etminan-verifier check --host <id> --addr <ip:port>
Flag Type Default Notes
--host <id> string required The enrolled host to check.
--addr <ip:port> socket addr required Where its agent is listening.
etminan-verifier check --host web-01 --addr 10.0.3.11:7620

run

The scheduled entry point (what etminan-verifier.timer calls hourly). Runs check against every enrolled host in one pass, fires the full alarm path (local structured log, audit log, email, notify-plugin channels) for anything that failed, and exits non-zero if any host produced a finding or a plugin failed verification. Also verifies every configured change-source/notify plugin (same as plugins verify) and the audit-log hash chain (same as baseline verify-signatures) every cycle.

etminan-verifier run

Takes no flags.

etminan-verifier run   # normally invoked by etminan-verifier.timer

Baseline & drift review

The read side of baseline handling. Drift is always proposed, never auto-accepted. Approving, rejecting, and excluding are trust-changing and live under op (op approve, op reject, op exclude); the two commands here are read-only and take no key.

Action Purpose
baseline review List pending (new/changed, unapproved) measurements.
baseline verify-signatures Re-verify every signed row + the audit chain in one pass.

baseline review

List every pending measurement, optionally filtered to one host. Each entry prints a plain-language ownership verdict, a change-source-correlation line (if configured), a package trust line (if a package match exists), and the raw sha256/owner/size/mtime detail. Entries older than ETMINAN_PENDING_REVIEW_SLA_HOURS (default 24) are marked [SLA EXCEEDED]. (Also available as op review.)

etminan-verifier baseline review [--host <id>]
Flag Type Default Notes
--host <id> string all hosts Restrict to one host.
etminan-verifier baseline review --host web-01

baseline verify-signatures

Re-check every approval batch's signature, every exclusion rule's create/revoke signature, every rejection's signature, and the full audit-log hash chain, in one pass. A row written before signing existed for its action is reported as "unsigned, predates this feature", not a failure. Exits non-zero if anything fails. (Also available as op verify-signatures, which additionally checks the identity registry.)

etminan-verifier baseline verify-signatures

Takes no flags.

etminan-verifier baseline verify-signatures

Plugins

The certified change-source / notify plugin catalog. Installed plugins are held to the same verify-then-exec bar (root-owned, not group/world-writable, content hash matches) whether hand-installed or catalog-installed.

Run etminan-verifier plugins <action> --help for one action's detail.

Action Purpose
plugins verify Check every configured change-source/notify plugin (allowlisted + verifies), without executing it.
plugins list Fetch + verify the certified catalog; show each entry's install status.
plugins install <name> Download, re-verify, and allowlist a catalog plugin.
plugins update <name> Re-pin an installed plugin to the catalog's current version.

plugins verify

Check every plugin referenced by ETMINAN_CHANGE_SOURCES or ETMINAN_NOTIFY_CHANNELS is allowlisted and passes verification, without running it. Exits non-zero and prints exactly what's wrong on any failure. (This same check runs automatically, silently on success, at the start of every run.)

etminan-verifier plugins verify

Takes no flags.

etminan-verifier plugins verify
  change-source 'apt-history' — OK
  notify 'slack-webhook' — OK
Everything verified.

plugins list

Fetch and verify the certified catalog (signature checked against the compiled-in trust anchor first), then print every entry with its install status: not installed / installed and up to date / installed with an update available. Never modifies anything.

etminan-verifier plugins list

Takes no flags.

etminan-verifier plugins list

plugins install

Download a certified catalog entry, re-verify its content hash against the catalog's pinned value, write it under /etc/etminan-verifier/<type>-plugins/, and append the matching allowlist entry. Must run as root. Does not add the plugin to ETMINAN_NOTIFY_CHANNELS/ETMINAN_CHANGE_SOURCES — it prints the exact line to add and a reminder to restart the service.

etminan-verifier plugins install <name>
Argument Type Default Notes
<name> string required Must appear in plugins list. Refuses if already installed (use plugins update).
sudo etminan-verifier plugins install slack-webhook

plugins update

Re-fetch and re-verify the catalog; if the pinned hash for <name> changed, download the new content, re-hash it, and re-pin the allowlist entry. Never automatic — runs only when you run it.

etminan-verifier plugins update <name>
Argument Type Default Notes
<name> string required Must already be installed (use plugins install first).
sudo etminan-verifier plugins update slack-webhook

Notifications

Preview and test the notification path without waiting for a real finding.

Command Purpose
notify-preview Render current templates against sample findings (sends nothing).
notify-test Send one synthetic finding through a channel's real plugin.

notify-preview

Render four representative fake findings through whatever _TEMPLATE/_FORMAT/_SEVERITIES is configured, and print the result: the full email (subject + body) and, per channel, the raw JSON payload the channel's plugin would receive on stdin. Never executes a plugin, never calls sendmail — safe any time, even against a channel not yet allowlisted.

etminan-verifier notify-preview [--channel <name>]
Flag Type Default Notes
--channel <name> string every channel in ETMINAN_NOTIFY_CHANNELS Preview just one channel.
etminan-verifier notify-preview --channel slack-webhook

notify-test

Send one synthetic test finding through <name>'s real plugin invocation — the same verify-then-exec path a live run uses — and report the plugin's actual exit status and any stderr. Deliberately ignores that channel's configured _SEVERITIES filter.

etminan-verifier notify-test --channel <name>
Flag Type Default Notes
--channel <name> string required Must already be allowlisted.
etminan-verifier notify-test --channel slack-webhook

Diagnostics

Command Purpose
version Print the version and exit (also --version, -V).

version

etminan-verifier version
etminan-verifier --version
etminan-verifier -V

Takes no flags. Prints etminan-verifier <version> and exits 0.

etminan-verifier --version
etminan-verifier 0.10.2

etminan-verifierd

The trust daemon. It is the sole owner of the verifier's trust-changing actions and of the one Ed25519 signing key; the op commands are thin clients that connect to its Unix socket. It runs on the verifier host as a long-lived service (etminan-verifierd.service) and is configured entirely through ETMINAN_* environment variables — it takes no subcommands.

etminan-verifierd

Takes no flags. Started by systemd; sources the same /etc/etminan-verifier/verifier.env (or a daemon drop-in) as the rest of the tool.

On start it opens the baseline DB, loads (or, on first run, expects) its signing key, and binds the peer-credentialed socket. It then authenticates each op client by SO_PEERCRED UID, maps the UID to a registered identity, enforces default-deny/fail-closed authorization, signs authorized actions as operator:<label>, and records every decision — allow and deny — on the hash-chained audit log.

Variable Default Purpose
ETMINAN_VERIFIERD_SOCKET /run/etminan-verifierd/etminan-verifierd.sock The Unix socket op clients connect to; peer-UID is read from it.
ETMINAN_VERIFIERD_DB /var/lib/etminan-verifier/baseline.db The baseline DB, which also holds the UID→identity registry and audit log.
ETMINAN_VERIFIERD_KEY /var/lib/etminan-verifier/daemon-signing.key The only Ed25519 signing key; the daemon signs operator actions with it (mode 0600).
ETMINAN_TOTP_SESSION_TTL_SECS 28800 (8h) How long an op login TOTP session stays valid.
ETMINAN_VERIFIERD_ALLOW_INSECURE_BOOTSTRAP (unset) DEV/TEST ONLY — relaxes op bootstrap preconditions. Never set in production.
etminan-verifierd.service (shipped unit — abridged)
[Service]
Type=notify
User=etminan-verifier
Group=etminan-verifier
WorkingDirectory=/var/lib/etminan-verifier
EnvironmentFile=-/etc/etminan-verifier/verifier.env
ExecStart=/usr/bin/etminan-verifierd
RuntimeDirectory=etminan-verifierd
NoNewPrivileges=true

See Verifier configuration for standing the daemon up and bootstrapping the first admin.


etminan-agent

The agent is a relay: with no subcommand it starts the long-running attestation daemon. It never decides what is trustworthy — it only produces signed, verifiable evidence; every judgment is made by etminan-verifier on a separate device. The handful of subcommands are one-shot setup. The agent requires a real TPM and is Linux-only.

Invocation Purpose
etminan-agent Start the long-running daemon.
etminan-agent write-ima-policy Write this host's IMA measurement policy, then exit.
etminan-agent keygen-tls Create the agent's mTLS identity and print its fingerprint.
etminan-agent version Print the version and exit (also --version, -V).

etminan-agent (daemon — no subcommand)

Start the long-running daemon: listen for mutual-TLS connections from etminan-verifier and, on request, take a TPM quote over PCR 10, read the IMA measurement-log delta from the last consumed offset, and return both together so the verifier can prove they describe the same boot state.

etminan-agent

Takes no flags — configured entirely through ETMINAN_* environment variables (see Configuration / man etminan-agent). Key variables: ETMINAN_AGENT_LISTEN (default 0.0.0.0:7620), ETMINAN_VERIFIER_CERT_FINGERPRINT (the pinned verifier fingerprint — required unless ETMINAN_ALLOW_PERMISSIVE_TLS=1 is set for the one-time enrollment bootstrap), ETMINAN_TLS_DIR, ETMINAN_IMA_LOG_PATH, ETMINAN_WATCHED_PATHS / ETMINAN_PROFILE.

Fail-closed transport

The daemon refuses to start if ETMINAN_VERIFIER_CERT_FINGERPRINT is unset and ETMINAN_ALLOW_PERMISSIVE_TLS is not enabled. Permissive mode (accept any client cert) is an explicit opt-in for enrollment only; in it the agent serves only the enrollment quote (without advancing the IMA-log cursor) and refuses SetProfile/PackageLookup.

# Normal operation (systemd sources agent.env):
etminan-agent

# One-time enrollment bootstrap:
ETMINAN_ALLOW_PERMISSIVE_TLS=1 etminan-agent

etminan-agent write-ima-policy

Write this host's IMA measurement policy to /sys/kernel/security/ima/policy (or ETMINAN_IMA_POLICY_PATH if set) and exit. Meant to run once, early at boot, before the daemon starts — see etminan-agent-ima-policy.service. Idempotent: a policy already active this boot is treated as success — either the write node's open fails outright (it can disappear from securityfs once loaded) or the write itself is rejected — as long as measurements are already flowing.

etminan-agent write-ima-policy

Takes no flags.

etminan-agent write-ima-policy

etminan-agent keygen-tls

Generate the agent's own self-signed mTLS keypair under $ETMINAN_TLS_DIR (default /var/lib/etminan-agent/tls) and print its SHA-256 fingerprint. Give that fingerprint to the verifier operator to confirm during op enroll, where it's pinned alongside the AK fingerprint. Run once per host, before its first connection from a verifier.

etminan-agent keygen-tls

Takes no flags.

etminan-agent keygen-tls
Generated agent TLS keypair at /var/lib/etminan-agent/tls
Fingerprint (sha256): a1b2…f9
Give this fingerprint to the verifier operator to confirm during `etminan-verifier enroll` …

etminan-agent version

etminan-agent version
etminan-agent --version
etminan-agent -V

Takes no flags. Prints etminan-agent <version> and exits 0.

etminan-agent --version
etminan-agent 0.10.2

See also

  • Configuration reference — every ETMINAN_* environment variable.
  • Verifier configuration — standing up etminan-verifierd and bootstrapping the first admin.
  • RBAC — the daemon's admin/operator/viewer roles, scope, and TOTP.
  • Editions — the daemon/RBAC are Standard; what Enterprise adds.
  • Audit log — where every signed action (and every deny) lands.
  • Troubleshooting — diagnosing a refused op call or a failed run.
  • man etminan-verifier, man etminan-verifierd, man etminan-agent — the deepest per-variable references.