Preserve app gate TLS access through provisioning and certificate rotation

This commit is contained in:
archipelago
2026-10-06 15:19:38 -04:00
parent 719e723816
commit 9f0df2ac44
9 changed files with 200 additions and 2 deletions
@@ -780,6 +780,19 @@ impl TlsMaterial {
);
}
// nginx and the app gate share the leaf. Validate the daemon's read
// permission on the staged key before replacing either live file.
if self.privileged {
let mut repair = self.cmd("/usr/bin/python3");
repair.args([
"-c",
include_str!("../../../../../../scripts/repair-app-gate-tls-permissions.py"),
"--key-name",
TLS_KEY_STAGING_NAME,
]);
run_checked(repair, "repair staged app TLS key permissions").await?;
}
// rename(2) within one directory: a reader sees either the whole old
// file or the whole new one, never a partial write. Two files cannot
// be swapped in a single atomic step, so there is a sub-millisecond
+14
View File
@@ -162,6 +162,20 @@ pub async fn ensure_runtime_assets_ready() {
Ok(_) => debug!("No OTA runtime payload to synchronize"),
Err(e) => warn!("Runtime asset bootstrap failed (non-fatal): {:#}", e),
}
// Older provisioning/rotation wrote a root-only leaf key. nginx could
// read it while the unprivileged app gate silently lost HTTPS. Repair
// permissions without replacing node identity, including binary-only OTA.
match host_sudo(&[
"python3",
"-c",
include_str!("../../../scripts/repair-app-gate-tls-permissions.py"),
])
.await
{
Ok(status) if status.success() => debug!("App gate TLS key permissions verified"),
Ok(status) => warn!("App gate TLS key permissions need attention: {status}"),
Err(error) => warn!("App gate TLS permission repair failed: {error}"),
}
// A frontend payload can predate the binary during qualification or rollback.
// Replace its doctor before starting reconciliation; direct writes cannot
// escape the management service's ProtectSystem filesystem namespace.