Skip to content

Dual control (four eyes)

Some actions do not merely observe the fleet — they change what the verifier will accept as trustworthy. Approving a baseline, hiding a path from drift review, or changing who may act at all are decisions that should not rest on one person. Dual control makes them require a second, distinct authorized operator.

Enterprise

Dual control is an Enterprise-edition capability. The Standard build behaves exactly as before, byte for byte.

What can be put under four eyes

Four actions are wired end to end:

Action token What it gates Why it is on the list
baseline-approve Accepting pending measurements as the new approved baseline The single decision that redefines "genuine" for a host
exclude-create Adding a baseline exclusion rule An exclusion permanently hides a path from drift review — the most trust-suppressing action available
operator-key Adding, changing or revoking an identity in the operator registry This is the action a rogue admin needs before any other: add themselves a second identity, or revoke the colleague who would otherwise have to co-sign. Both directions are covered, and the co-signer must independently hold AdminRegistry — re-validated when the action applies, not only when it is requested
approve-boot Accepting a host's current boot state as its golden PCR values Like exclude-create, this is an action that makes an alarm stop. Whoever can approve a boot state single-handed can boot a host into something else and then bless it, after which every later attestation reports Genuine and quiet. Group scope makes that one call for a whole fleet

default expands to all four, not to baseline-approve alone.

This changed in 0.11 — read before you upgrade

Through 0.10, default meant baseline-approve only. An existing install that configured default therefore gains four-eyes on exclude-create, operator-key and approve-boot on upgrade, without anybody editing a config file. Actions one admin could take alone will start needing a second.

It was widened because the old meaning was a trap: an operator who asked for "the recommended four-eyes posture" got coverage on approvals but not on who may approve, and had a gap exactly where they believed there was a wall.

Widening default can only ever ADD co-signing, never remove it, and the token is still opt-in — nothing applies until default is configured. If you want the old, narrower set, name the actions explicitly: ETMINAN_DUAL_CONTROL_ACTIONS=baseline-approve.

Any other token is rejected rather than quietly accepted single-signed — a four-eyes control that fails open is worse than none.

How an approval actually happens

There is no separate "request" object to hunt for. The first authorized operator's attempt records their signature over the canonical payload without applying it. A different authorized operator performing the same action co-signs that same payload. When the number of distinct approvals reaches the threshold, the action applies — and every step is written to the audit log.

The honest limit, stated plainly: this enforces two distinct identities, not two distinct humans. Custody of those identities is your control, not the software's.

Configuration — and why a signed latch exists

Dual control is configured two ways, and they compose deliberately.

ETMINAN_DUAL_CONTROL_ACTIONS=baseline-approve,exclude-create
ETMINAN_DUAL_CONTROL_THRESHOLD=2

Off unless set. Simple, and exactly the legacy behaviour when no signed policy exists.

etminan-verifier op dual-control-policy show
etminan-verifier op dual-control-policy set \
    --actions baseline-approve,exclude-create \
    --threshold 2 \
    --reason "four-eyes per security policy §4.2"

Admin only — and itself four-eyes: a second admin must co-sign the policy change. There is no single-person path to weaken it.

The composition rule is what makes this a control rather than a suggestion:

  • Effective action set = environment ∪ signed policy. The environment variable can only ever add coverage. A signed policy latches actions on, so unsetting the environment variable can never remove them.
  • Effective threshold = max(environment, signed policy, 2). Two is the floor; a lower value would defeat the control and is clamped up.

An environment variable alone is not an enforcement boundary

Anything that can edit the unit file can unset an environment variable. That is precisely why the signed, audited policy exists and why it wins. If four eyes is a requirement rather than a preference, set the signed policy — do not rely on the environment alone.

Each open request captures the threshold in force at creation time, so a later configuration change never retroactively alters a request already in flight.

Verifying it after the fact

op verify-signatures checks the audit chain, the registry, and each dual-controlled action's distinct-approver count. An action that applied without its required approvals does not verify — which is the point.

Next steps