This document outlines the concrete plan for managing SSH access across the fleet using a modern, passkey-based hybrid approach.
The goal is a declarative, secure, and convenient SSH setup. We achieve this by combining:
- Platform Authenticators (TPM/Secure Enclave): For seamless, passwordless logins from primary machines.
- Roaming Authenticators (YubiKey): For secure, portable access from any machine.
- Emergency Passphrase Key: For "break-glass" disaster recovery scenarios.
All public keys are managed declaratively by Nix/Home-Manager. All private key material is stored encrypted in the repository using SOPS.
| Hostname | Key Name | Type | Purpose |
|---|---|---|---|
scholomance |
scholomance-se |
ed25519-sk |
Primary key for the M2 Ultra Mac, using the Secure Enclave. |
murderbot |
murderbot-tpm |
ed25519-sk |
Primary key for the Linux PC, using the TPM. |
culture |
culture-se |
ed25519-sk |
Primary key for the personal MacBook Pro, using the Secure Enclave. |
microserfs |
microserfs-se |
ed25519-sk |
Primary key for the work MacBook Pro, using the Secure Enclave. |
| (Physical Key) | yubikey-primary |
ed25519-sk |
Roaming key for portable access. |
| (Emergency) | emergency-recovery |
ed25519 |
Disaster recovery key, protected by a strong passphrase. |
Follow these steps to generate the keys and integrate them into the repository.
Run these commands once from the root of this repository:
mkdir -p ssh/authorized_keys
mkdir -p secrets/ssh# Generate the key, authenticating with Touch ID / Apple Watch
ssh-keygen -t ed25519-sk -C "mrw@scholomance" -f ~/.ssh/scholomance-se
# Add the public key to this repository
cp ~/.ssh/scholomance-se.pub ssh/authorized_keys/
# Add the private key handle to this repository and encrypt it
cp ~/.ssh/scholomance-se secrets/ssh/
sops --encrypt --in-place secrets/ssh/scholomance-seNote: You may need to install libfido2 first (e.g., sudo apt install libfido2-1).
# Generate the key, authenticating with your login password/biometrics
ssh-keygen -t ed25519-sk -C "mrw@murderbot" -f ~/.ssh/murderbot-tpm
# Add the public key to this repository
cp ~/.ssh/murderbot-tpm.pub ssh/authorized_keys/
# Add the private key handle to this repository and encrypt it
cp ~/.ssh/murderbot-tpm secrets/ssh/
sops --encrypt --in-place secrets/ssh/murderbot-tpm# Generate the key, authenticating with Touch ID / Apple Watch
ssh-keygen -t ed25519-sk -C "mrw@culture" -f ~/.ssh/culture-se
# Add the public key to this repository
cp ~/.ssh/culture-se.pub ssh/authorized_keys/
# Add the private key handle to this repository and encrypt it
cp ~/.ssh/culture-se secrets/ssh/
sops --encrypt --in-place secrets/ssh/culture-se# Generate the key, authenticating with Touch ID / Apple Watch
ssh-keygen -t ed25519-sk -C "mrw@microserfs" -f ~/.ssh/microserfs-se
# Add the public key to this repository
cp ~/.ssh/microserfs-se.pub ssh/authorized_keys/
# Add the private key handle to this repository and encrypt it
cp ~/.ssh/microserfs-se secrets/ssh/
sops --encrypt --in-place secrets/ssh/microserfs-sePlug in your YubiKey and run this on any machine.
# Generate the key, tapping the YubiKey to confirm
ssh-keygen -t ed25519-sk -C "mrw@yubikey-primary" -f ~/.ssh/yubikey-primary
# Add the public key to this repository
cp ~/.ssh/yubikey-primary.pub ssh/authorized_keys/
# Add the private key handle to this repository and encrypt it
cp ~/.ssh/yubikey-primary secrets/ssh/
sops --encrypt --in-place secrets/ssh/yubikey-primaryRun this on any machine.
# Generate a standard ed25519 key
ssh-keygen -t ed25519 -C "mrw@emergency-recovery" -f ~/.ssh/emergency-recovery
# When prompted, enter a new, very strong, and unique passphrase.
# Store this passphrase somewhere safe (e.g., a password manager).
# Add the public key to this repository
cp ~/.ssh/emergency-recovery.pub ssh/authorized_keys/
# Add the private key to this repository and encrypt it
cp ~/.ssh/emergency-recovery secrets/ssh/
sops --encrypt --in-place secrets/ssh/emergency-recoveryAdd the following code to your home.nix to declaratively manage the authorized_keys file on all machines in the fleet.
{ config, pkgs, ... }:
let
# Path to your public keys, relative to the flake root.
# This assumes your home.nix is in the same directory as the `ssh` folder.
authorizedKeysDir = ./ssh/authorized_keys;
# Read all .pub files in that directory and build a list of their contents.
authorizedKeys = builtins.map (keyFile: builtins.readFile (authorizedKeysDir + "/${keyFile}"))
(builtins.attrNames (builtins.readDir authorizedKeysDir));
in
{
# ... other home-manager configuration
programs.ssh = {
enable = true;
# This option takes a list of strings, where each string is a public key.
authorizedKeys.keys = authorizedKeys;
};
# ... other home-manager configuration
}After generating the keys and adding the Nix code:
- Commit all changes to the repository.
- Run
home-manager switchon each machine in the fleet.
This will distribute the public keys and ensure every machine authorizes the new set of keys.
To complement the SSH key system and address the "first unlock" problem after a reboot, a tiered passphrase strategy is essential. This avoids the security risk of reusing a single master password across all machines and services.
The core principle is to isolate risk. A compromise of a less-secure environment (like a work machine) should not compromise the keys to the entire digital kingdom (the password manager).
We will use three distinct, high-entropy passphrases based on the Diceware method (e.g., correct-horse-battery-staple).
- Purpose: To unlock your password manager (e.g., 1Password, Bitwarden).
- Characteristics: A unique, 6+ word Diceware passphrase.
- Usage: This key is used only for the password manager. It should not be used for any other login. Day-to-day access to the vault should be through biometrics (Face ID, Touch ID, etc.).
- Backup: Memorize it. This is the one passphrase you must commit to long-term memory.
- Purpose: The login password for your trusted, personal machines (
scholomance,murderbot,culture). - Characteristics: A different, 5+ word Diceware passphrase.
- Usage: It's acceptable to reuse this passphrase across your personal machines as you control their security environment.
- Backup: Store this passphrase securely inside your password manager. You do not need to have it perfectly memorized. After a reboot, you can look it up in your vault to perform the first unlock.
- Purpose: The login password for your work machine (
microserfs). - Characteristics: Another unique, 5+ word Diceware passphrase.
- Usage: This passphrase is used only for the work machine to ensure complete isolation between your personal and professional security domains.
- Backup: Store this passphrase securely inside your password manager.
| Item | Passphrase Tier | Example | Where It's Used | Primary Backup |
|---|---|---|---|---|
| Password Manager | Tier 1: Vault Key | gargantuan-silo-nomad-revolt... |
Master password for the vault. | Your Brain |
| Personal Machines | Tier 2: Fleet Key | eager-pelican-rodeo-treason... |
Login for scholomance, murderbot, culture. |
Password Manager |
| Work Machine | Tier 3: Work Key | staple-archive-ferry-tundra... |
Login for microserfs. |
Password Manager |