Keep provisioning credentials out of OEM installs and factory snapshots
Review findings from codex and Copilot: - A rig-supplied credentials file in OEM mode now contributes only its LUKS passphrase: preserved users/root_enc_password fields would have created a hidden provisioning account despite OEM promising no user until first boot. - The factory snapshot is taken writable, scrubbed of deployment credentials (staged authorized_keys, tailscale auth key and join unit, the dead OEM LUKS key and its initramfs drop-ins), then set read-only — a reset years later must not authorize the original deployment key or rejoin its tailnet. - The missing-Node-tarball case is a hard install error on every install, not just OEM: the stash is what lets a factory reset finalize offline. - The configurator's OEM gate checks the runtime package for the service unit as well as the setup binary. - The test harness handles the deliberately skipped mode picker on blank disks when the bundled runtime lacks OEM support. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
445db32792
commit
e49ea2bc96
5 files changed
+110
-15
No files matched your search
+50
-1
@@ -121,6 +121,22 @@ class ContextOemTest(unittest.TestCase):
|
||||
"rig-secret",
|
||||
)
|
||||
|
||||
def test_oem_discards_account_material_from_supplied_credentials(self):
|
||||
# A rig credentials file must not smuggle in users or a root password.
|
||||
self.write_config(self.base_config(oem=True))
|
||||
self.write_creds({
|
||||
"users": [{"username": "backdoor", "enc_password": "x", "sudo": True}],
|
||||
"root_enc_password": "x",
|
||||
"encryption_password": "rig-secret",
|
||||
})
|
||||
ctx = self.from_env()
|
||||
self.assertEqual(ctx.user_credentials["users"], [])
|
||||
self.assertNotIn("root_enc_password", ctx.user_credentials)
|
||||
self.assertEqual(ctx.user_credentials["encryption_password"], "rig-secret")
|
||||
synthesized = json.loads(ctx.creds_path.read_text())
|
||||
self.assertEqual(synthesized["users"], [])
|
||||
self.assertNotIn("root_enc_password", synthesized)
|
||||
|
||||
def test_oem_unencrypted_touches_nothing(self):
|
||||
self.write_config(self.base_config(oem=True))
|
||||
ctx = self.from_env()
|
||||
@@ -194,6 +210,14 @@ class StageOemStateTest(unittest.TestCase):
|
||||
with self.assertRaisesRegex(RuntimeError, "Node tarball"):
|
||||
phases_impl.stage_oem_state(ctx)
|
||||
|
||||
def test_missing_node_tarball_fails_normal_installs_too(self):
|
||||
# The stash is what makes a later factory reset work offline.
|
||||
for tarball in self.packages.glob("*.tar.gz"):
|
||||
tarball.unlink()
|
||||
ctx = make_ctx(self.target, oem=False)
|
||||
with self.assertRaisesRegex(RuntimeError, "Node tarball"):
|
||||
phases_impl.stage_oem_state(ctx)
|
||||
|
||||
def test_oem_arms_first_boot_setup(self):
|
||||
self.install_runtime_oem_support()
|
||||
ctx = make_ctx(self.target)
|
||||
@@ -357,11 +381,36 @@ class CreateFactorySnapshotTest(unittest.TestCase):
|
||||
top = str(self.state_dir / "factory-top")
|
||||
self.assertIn(["mount", "-o", "subvolid=5", "/dev/mapper/omarchy_root", top], self.calls)
|
||||
self.assertIn(
|
||||
["btrfs", "subvolume", "snapshot", "-r", f"{top}/@", f"{top}/@factory"],
|
||||
["btrfs", "subvolume", "snapshot", f"{top}/@", f"{top}/@factory"],
|
||||
self.calls,
|
||||
)
|
||||
self.assertIn(
|
||||
["btrfs", "property", "set", "-ts", f"{top}/@factory", "ro", "true"],
|
||||
self.calls,
|
||||
)
|
||||
self.assertIn(["umount", top], self.calls)
|
||||
|
||||
def test_factory_snapshot_scrubs_provisioning_credentials(self):
|
||||
# Simulate the snapshot carrying deployment credentials; the scrub
|
||||
# must drop them before the snapshot goes read-only.
|
||||
top = self.state_dir / "factory-top"
|
||||
factory = top / "@factory"
|
||||
secrets = [
|
||||
factory / "var/lib/omarchy/oem/authorized_keys",
|
||||
factory / "etc/tailscale/authkey",
|
||||
factory / "etc/omarchy/oem.key",
|
||||
]
|
||||
keep = factory / "var/lib/omarchy/oem/groups"
|
||||
for path in [*secrets, keep]:
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
path.write_text("secret")
|
||||
|
||||
phases_impl.create_factory_snapshot(self.ctx())
|
||||
|
||||
for path in secrets:
|
||||
self.assertFalse(path.exists(), path)
|
||||
self.assertTrue(keep.exists())
|
||||
|
||||
def test_non_btrfs_target_skips(self):
|
||||
self.findmnt["FSTYPE"] = "ext4"
|
||||
phases_impl.create_factory_snapshot(self.ctx())
|
||||
|
||||
Reference in new issue
Block a user