Split OpenBao initial config progress

This commit is contained in:
2026-05-25 15:14:59 +02:00
parent 9afe30f49f
commit b9bad47a21
2 changed files with 41 additions and 5 deletions

View File

@@ -381,6 +381,17 @@ def build_gates(data: dict[str, Any]) -> list[Gate]:
"human" if not yes(data, "openbao_initialized") else "done",
"Human-attended ceremony only. This console will not run init.",
),
Gate(
"OpenBao initial configuration",
(
"done"
if yes(data, "openbao_initial_config_applied")
else "human"
if yes(data, "openbao_initialized")
else "blocked"
),
"Apply first auth, mount, and policy configuration; audit may be a declarative follow-up.",
),
Gate(
"Root-token disposition",
"done" if data.get("root_token_disposition") in {"revoked", "offline-sealed"} else "blocked",
@@ -579,6 +590,7 @@ def merged_approval_metadata(
"openbao_init_output_produced",
"openbao_initialized",
"openbao_post_unseal_verified",
"openbao_initial_config_applied",
"openbao_trial_material_exposed",
"openbao_compromise_response_complete",
"openbao_unseal_keys_rotated",
@@ -795,6 +807,7 @@ def metadata_template() -> dict[str, Any]:
"openbao_init_output_produced": False,
"openbao_initialized": False,
"openbao_post_unseal_verified": False,
"openbao_initial_config_applied": False,
"openbao_trial_material_exposed": False,
"openbao_compromise_response_complete": False,
"openbao_unseal_keys_rotated": False,
@@ -1052,6 +1065,18 @@ def integration_payloads(data: dict[str, Any]) -> list[dict[str, str]]:
},
openbao_direct_taint,
),
add_taint(
{
"name": "OpenBao initial configuration",
"description": "First auth, mount, and policy configuration after unseal.",
"subsystem": "Railiance OpenBao",
"responsibility": "openbao-ceremony-operator",
"email": role_email(data, "role_openbao_operator_email"),
"location": "../railiance-platform openbao-configure-initial",
"state": state_value(yes(data, "openbao_initial_config_applied"), yes(data, "openbao_initialized")),
},
openbao_trial_taint(data, "downstream") if yes(data, "openbao_initialized") else {},
),
]
@@ -1185,6 +1210,7 @@ def command_payloads(data: dict[str, Any]) -> list[dict[str, str]]:
init_output = yes(data, "openbao_init_output_produced")
initialized = yes(data, "openbao_initialized")
post_unseal_verified = yes(data, "openbao_post_unseal_verified")
initial_config_applied = yes(data, "openbao_initial_config_applied")
trial_exposed = yes(data, "openbao_trial_material_exposed")
response_complete = yes(data, "openbao_compromise_response_complete")
keys_rotated = yes(data, "openbao_unseal_keys_rotated")
@@ -1225,12 +1251,15 @@ def command_payloads(data: dict[str, Any]) -> list[dict[str, str]]:
unseal_state = "blocked"
unseal_reason = "OpenBao init output must be produced first."
config_state = "done" if root_disposed else "todo"
config_reason = "Initial configuration and root-token disposition are recorded."
if not root_disposed:
config_reason = "Configure OpenBao, then revoke or offline-seal the root token."
config_state = "done" if initial_config_applied else "todo"
config_reason = "Initial configuration is recorded. Root-token disposition remains a separate gate."
if not initial_config_applied:
config_reason = "Configure OpenBao, then record this non-secret completion flag."
if trial_exposed and initialized and not response_complete:
config_reason = "Tainted by trial key-material exposure. Operator may proceed, but record the taint and complete rotation, reset, or another compromise response before production trust."
if initial_config_applied:
config_reason = "Initial configuration is recorded on a tainted workpath. Complete root-token disposition and compromise response before production trust."
else:
config_reason = "Tainted by trial key-material exposure. Operator may proceed, but record the taint and complete rotation, reset, or another compromise response before production trust."
if not initialized:
config_state = "blocked"
config_reason = "OpenBao must be initialized and unsealed first."
@@ -2293,6 +2322,7 @@ def ui_html() -> str:
<label class="choice"><input id="openbao_init_output_produced" type="checkbox"><span><strong>Init output produced</strong><span>OpenBao generated unseal shares and the initial root token outside this UI. Do not paste those values here.</span></span></label>
<label class="choice"><input id="openbao_initialized" type="checkbox"><span><strong>Initialized and unsealed</strong><span>The human ceremony completed outside this UI under the approved strategy.</span></span></label>
<label class="choice"><input id="openbao_post_unseal_verified" type="checkbox"><span><strong>Post-unseal verification passed</strong><span>Filesystem and post-unseal readiness checks completed without recording secret material.</span></span></label>
<label class="choice"><input id="openbao_initial_config_applied" type="checkbox"><span><strong>Initial configuration applied</strong><span>OpenBao auth, mounts, and policies were applied; audit may remain a declarative follow-up.</span></span></label>
<label class="choice"><input id="restore_drill_passed" type="checkbox"><span><strong>Restore drill passed</strong><span>Snapshot and isolated restore proof completed before live secrets are migrated.</span></span></label>
</div>
<label class="field" style="margin-top: 14px;">
@@ -2404,6 +2434,7 @@ def ui_html() -> str:
"openbao_init_output_produced",
"openbao_initialized",
"openbao_post_unseal_verified",
"openbao_initial_config_applied",
"openbao_trial_material_exposed",
"openbao_compromise_response_complete",
"openbao_unseal_keys_rotated",
@@ -2685,6 +2716,7 @@ def ui_html() -> str:
openbao_init_output_produced: document.getElementById("openbao_init_output_produced").checked,
openbao_initialized: document.getElementById("openbao_initialized").checked,
openbao_post_unseal_verified: document.getElementById("openbao_post_unseal_verified").checked,
openbao_initial_config_applied: document.getElementById("openbao_initial_config_applied").checked,
openbao_trial_material_exposed: document.getElementById("openbao_trial_material_exposed").checked,
openbao_compromise_response_complete: document.getElementById("openbao_compromise_response_complete").checked,
openbao_unseal_keys_rotated: document.getElementById("openbao_unseal_keys_rotated").checked,