VIRGO

Audit-gated lifecycle tokens

원본
docs/design/AUDIT-GATED-LIFECYCLE-TOKENS.md
고정된 커밋
d62e85485903a5537ee2b73c14201597e29bdaa5
sha256
6df8edb68d2d49df554439ba766fd781057ee32a9d941b7f3283bab93ed8b59c

이 페이지는 요약이 아니라 명세 원문입니다. 위에 고정된 원본에서 그대로 렌더링되며, 본문은 한 글자도 바뀌지 않고 표현만 더해집니다.

명세 본문은 영어가 정본입니다. 번역본을 두면 진실의 출처가 둘이 되므로 의도적으로 번역하지 않습니다. 제목·목차·안내는 한국어로 제공합니다.

Audit-gated lifecycle tokens

Status: implementation contract

Lifecycle operations whose contract requires an audit CLEAR—persona down, persona up, and cutover—must not treat prose, chat, or an unbound test report as execution authority. Before any live mutation, the operator mechanism requires a verifiable, single-operation CLEAR token containing:

  • the exact candidate/release SHA and tree hash;
  • the exact action (down, up, or cutover), persona/logical identity, and target host;
  • verdict CLEAR, auditor identity, audit artifact/run id, and issued time;
  • expiry and a one-operation replay guard; and
  • for recovery, the durable recovery operation id distinguishing recovery from a new venture.

The mechanism refuses before mutation when SHA, tree, target, action, expiry, or operation id differs, or when the token was already consumed. Tokens grant no persona-side fence, lease, ingest, restore, or activation capability; this is operator tooling.

The signing key (V2-305 implementation note)

Verification is HMAC-SHA256 over the canonical signed subject, compared in constant time, against a single owner-only key. There is no default key and no compiled-in key: a hub that was not configured with one cannot verify a token and therefore cannot perform a gated operation, which is the correct failure rather than a fallback.

Ownership and provisioning point, stated so it is not decided twice:

  • The key lives at <state_root>/clear.key, mode 0600, owned by the root/hub seat's uid, read through the same single-descriptor private-file check as the device token (no symlink, no extra hard link, no group/other bits).
  • It is provisioned by the first CLEAR issuance flow, not by onboarding and not by state initialization. Generating one at install time would leave an unused signing secret on every machine — including every machine that never issues a token — and an unused secret is one nobody is watching.
  • It is read on demand, only by up/down, and only after the V2-508 supervision refusal. checkpoint is tokenless, so a hub with no key at all still composes and serves checkpoints; the absence of a key is never a reason to construct the lifecycle with a placeholder.
  • It never enters config, argv, a log line, or a receipt. Only the token's digest is durable, as the single-use marker virgo:lifecycle:clear-consumed:<token_sha256>, written in the same script as the transition it gates.

Regression fixtures include a controlled down performed on a resident host after a non-CLEAR audit state, and a watchdog incident where an unbound completion assertion was mistaken for host evidence. Execution context must be attested separately by hostname, uid, and exact tmux socket.