Add Separated-Key Architecture#146
Open
dvicory wants to merge 5 commits into
Open
Conversation
Introduce two-key security model protecting against physical access: Boot key (/boot/host_key): - SSH host key for initrd environment - Stored unencrypted (necessary for remote unlock) - Physical access = SSH MITM, but data safe at rest Runtime key (/persist/etc/ssh/ssh_host_ed25519_key): - SSH host key for normal system operation - Used for SOPS secrets decryption - Stored encrypted on ZFS pool - Physical access = cannot decrypt secrets Security improvement: Physical /boot access no longer compromises SOPS-encrypted secrets (ZFS passphrase, passwords, API keys). Core changes: - Add runtimeHostKeyPath and runtimeHostKeyPub options - Auto-detect separated-key mode from sops.age.sshKeyPaths - Install runtime key during disko (postMountHook) - Configure OpenSSH to use runtime key for post-boot - Mark /persist as neededForBoot for early SOPS access - Improves known_hosts generation - Pass runtime key via --disk-encryption-keys during install Templates default to separated-key mode. Single-key mode remains functional (backward compatible).
Provide scripts to assist with migration (some manual steps still required, to be documented). 1. enable-key-separation: Prepare migration - Generate runtime SSH host key - Derive age key from runtime key for SOPS - Update .sops.yaml with runtime key, renames boot key 2. install-runtime-key: Deploy to target - Copy runtime key to /persist/etc/ssh/ - Required before deploying separated-key configuration 3. rotate-boot-key: Rotate to prevent future compromise - Back up /boot to tmpfs - Securely wipe boot partition (dd + TRIM) - Recreate filesystem and reinstall bootloader - Handle mirrored boot partitions automatically
New hosts now use separated-key architecture by default for better security. Add --single-key flag for legacy mode (discouraged).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
Closes #132.
This PR introduces a separated-key architecture that protects SOPS-encrypted secrets (including ZFS passphrase, passwords, API keys) from physical access attacks. By separating the boot SSH key from the runtime SSH key used for SOPS decryption, an attacker with physical access to the unencrypted
/bootpartition can no longer decrypt your secrets.New hosts created with
gen-new-hostnow use separated-key mode by default. Migration tools are provided for upgrading existing single-key hosts.Security Model
The Problem: Single-Key Vulnerability
In traditional single-key mode, one SSH key (
/boot/host_key) serves two purposes:Since
/bootmust be unencrypted, this creates a vulnerability:/boot/host_keyThe Solution: Separated-Key Architecture
Boot key (
/boot/host_key):/bootpartition (required for remote decrypt)Runtime key (
/persist/etc/ssh/ssh_host_ed25519_key):/persistConfiguration Modes
Single-key (legacy, discouraged):
Separated-key (default, recommended):
Core Implementation
Automatic Detection
Skarabox automatically detects separated-key mode when the runtime key path (
/persist/etc/ssh/ssh_host_ed25519_key) is configured insops.age.sshKeyPaths.New Configuration Options
skarabox.runtimeHostKeyPath- Path to runtime private key (default:"${hostDir}/runtime_host_key")skarabox.runtimeHostKeyPub- Runtime public key contentKey Installation
During system installation (
install-on-beacon), the runtime key is:--disk-encryption-keysto disko/persist/etc/ssh/ssh_host_ed25519_keyin disko'spostMountHookservices.openssh.hostKeysBoot Dependency
/persistis marked asneededForBootto ensure SOPS can access the runtime key early in boot process.Breaking Changes
Default to Separated-Key Mode
gen-new-hostnow creates separated-key hosts by default. Use--single-keyflag for legacy single-key mode.Backward compatibility: Existing single-key hosts remain fully functional.
Migration Tools for Existing Hosts
Three new tools help migrate existing single-key hosts to separated-key architecture:
enable-key-separation- Generates runtime keys and updates.sops.yamlconfigurationinstall-runtime-key- Deploys runtime key to/persist/etc/ssh/on target hostrotate-boot-key- Securely replaces boot key via partition wipeComplete migration workflow is documented in
docs/normal-operations.md.Testing
gen-new-hostrotate-boot-key