diff --git a/docs/constitution.md b/docs/constitution.md index 3e66b3a..5350b18 100644 --- a/docs/constitution.md +++ b/docs/constitution.md @@ -42,6 +42,7 @@ config.services = { - Secrets files: `secrets/certs.yaml`, `secrets/env.yaml`, `secrets/gallery.yaml`, `secrets/homepage.yaml`, `secrets/keys.yaml`, `secrets/wireguard.yaml`, `secrets/secrets.yaml`, plus `secrets/ssh/` for host keys. - Placement rules: Keep secrets aligned to their file purpose (certificates → `certs.yaml`; environment/service env vars → `env.yaml`; media/gallery creds → `gallery.yaml`; homepage widgets → `homepage.yaml`; SSH/private keys → `keys.yaml`; WireGuard peers → `wireguard.yaml`; misc defaults → `secrets.yaml`). - secureHost gating: Only hosts with `my.secureHost = true` load SOPS secrets and WireGuard interfaces. Hosts with `secureHost = false` must avoid secret-dependent services and skip SOPS entries. +- VPS enrollment flow: The vps host generates its own key on first boot, then operators enroll the public key, re-encrypt secrets, and redeploy. Follow `docs/playbooks/enroll-vps.md`. ## Module Categories and Active Hosts - Module categories: apps, dev, scripts, servers, services, shell, network, users, nix, patches. Factories sit in `modules/factories/` and are imported explicitly. diff --git a/docs/playbooks/enroll-vps.md b/docs/playbooks/enroll-vps.md new file mode 100644 index 0000000..25398cc --- /dev/null +++ b/docs/playbooks/enroll-vps.md @@ -0,0 +1,16 @@ +# Playbook: Enroll VPS Secrets + +- Name: Enroll VPS secrets after first boot +- Purpose: Enroll the vps host key and re-encrypt secrets so services can start. +- Prerequisites: vps host booted and reachable; secure host; SOPS access on operator machine. +- Inputs: vps host public key; secrets files under `secrets/`; repo checkout. +- Steps: + 1. Retrieve the vps host public key from the running instance. + 2. Add the vps public key to SOPS recipients for the relevant secrets files. + 3. Re-encrypt secrets and commit updates as needed. + 4. Rebuild the vps host from an explicitly authorized operator machine. +- Validation: + - Services that require secrets start successfully after the rebuild. + - SOPS decrypt succeeds on the vps host without manual intervention. +- Outputs: Updated secrets files with the vps recipient; vps host with secrets available. +- References: `docs/constitution.md` (Secrets Map and secureHost), `docs/reference/index.md` (Hosts and Roles) diff --git a/docs/playbooks/vps-rebuild.md b/docs/playbooks/vps-rebuild.md new file mode 100644 index 0000000..89deced --- /dev/null +++ b/docs/playbooks/vps-rebuild.md @@ -0,0 +1,15 @@ +# Playbook: Rebuild VPS + +- Name: Remote rebuild of vps +- Purpose: Apply configuration changes to the vps host from an explicitly authorized operator machine. +- Prerequisites: Operator machine authorized; vps reachable via SSH; repo checkout. +- Inputs: vps hostname or IP; flake path; target profile `vps`. +- Steps: + 1. Ensure the operator machine is in the authorized key list for `nixremote`. + 2. Run the rebuild helper script with the target host details. + 3. Monitor the rebuild for completion and errors. +- Validation: + - vps reports the new configuration after rebuild. + - Remote access remains available after the update. +- Outputs: Updated vps host configuration. +- References: `docs/constitution.md` (Hosts and Roles, secureHost), `docs/reference/index.md` (Hosts and Roles) diff --git a/docs/reference/index.md b/docs/reference/index.md index e90bdae..ebc9ebe 100644 --- a/docs/reference/index.md +++ b/docs/reference/index.md @@ -20,13 +20,14 @@ ## Hosts and Roles - Configs: `hosts//configuration.nix` with toggles in `hosts//toggles.nix`. -- Active hosts: `workstation`, `server`, `miniserver`, `galaxy`, `emacs`. +- Active hosts: `workstation`, `server`, `miniserver`, `galaxy`, `emacs`, `vps`. - Roles: - workstation: developer desktop; provides build power for distributed builds. - server: primary services host (overrides `my.mainServer = "server"` and enables proxies/containers). - miniserver: small-footprint server; default `mainServer` in shared options. - galaxy: small server variant using nixpkgs-small. - emacs: VM profile, `my.secureHost = false` for secret-free usage. + - vps: Linode VPS image target, secure host with enrollment-based secrets. - Network maps: `my.ips` and `my.interfaces` declared in `modules/modules.nix`; host toggles may override. ## Proxy, Firewall, and Networking diff --git a/hosts/vps/configuration.nix b/hosts/vps/configuration.nix new file mode 100644 index 0000000..a7948fa --- /dev/null +++ b/hosts/vps/configuration.nix @@ -0,0 +1,34 @@ +{ + lib, + inputs, + ... +}: +{ + imports = [ + ../../config/base.nix + ]; + my = { + secureHost = true; + users.nixremote = { + enable = true; + authorizedKeys = inputs.self.lib.getSshKeys [ + "nixworkstation" + "nixserver" + "nixminiserver" + ]; + }; + services.network.enable = true; + interfaces = lib.mkMerge [ + { + vps = "eth0"; + } + ]; + }; + networking.hostName = "vps"; + sops.age = { + generateKey = true; + keyFile = "/var/lib/sops-nix/key.txt"; + sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ]; + }; + environment.systemPackages = [ ]; +} diff --git a/parts/hosts.nix b/parts/hosts.nix index e72b2ad..33f91e0 100644 --- a/parts/hosts.nix +++ b/parts/hosts.nix @@ -6,5 +6,6 @@ server = inputs.self.lib.createConfig "server" inputs.nixpkgs-small; galaxy = inputs.self.lib.createConfig "galaxy" inputs.nixpkgs-small; emacs = inputs.self.lib.createConfig "emacs" inputs.nixpkgs; + vps = inputs.self.lib.createConfig "vps" inputs.nixpkgs-small; }; } diff --git a/parts/packages.nix b/parts/packages.nix index 3448711..8af8bce 100644 --- a/parts/packages.nix +++ b/parts/packages.nix @@ -30,6 +30,7 @@ { packages = (inputs.jawz-scripts.packages.${system} or { }) // { emacs-vm = inputs.self.nixosConfigurations.emacs.config.system.build.vm; + vps-linode = inputs.self.nixosConfigurations.vps.config.system.build.images.linode; nixos-mcp = nixosMcp; nixos-mcp-server = mcpServerPkg; }; diff --git a/scripts/rebuild-vps.sh b/scripts/rebuild-vps.sh new file mode 100755 index 0000000..e8d25e4 --- /dev/null +++ b/scripts/rebuild-vps.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +set -euo pipefail + +if [ "${1:-}" = "" ] || [ "${2:-}" = "" ]; then + echo "Usage: scripts/rebuild-vps.sh " >&2 + exit 1 +fi + +host="$1" +flake_path="$2" + +nixos-rebuild switch \ + --flake "${flake_path}#vps" \ + --target-host "${host}" \ + --use-remote-sudo diff --git a/specs/003-vps-image-migration/quickstart.md b/specs/003-vps-image-migration/quickstart.md index 8ea352b..7003d78 100644 --- a/specs/003-vps-image-migration/quickstart.md +++ b/specs/003-vps-image-migration/quickstart.md @@ -12,3 +12,17 @@ Provision a Linode-compatible VPS image, bootstrap secrets securely, and enable 4. Enroll the host by adding its public key as a secrets recipient and re-encrypt required secrets. 5. Trigger a rebuild from an explicitly authorized operator machine to apply secrets and confirm core services start successfully. 6. Validate the remote rebuild workflow from an explicitly authorized operator machine. + +## Validation Checklist + +- vps boots with network connectivity and remote access. +- Secrets are available after enrollment and follow-up deployment. +- Remote rebuild completes from an explicitly authorized operator machine. +- Existing host and image builds complete after migration. + +## Validation Log + +- vps connectivity: pending +- secrets enrollment: pending +- remote rebuild: pending +- existing host/image builds: pending diff --git a/specs/003-vps-image-migration/tasks.md b/specs/003-vps-image-migration/tasks.md index 34eddfa..0c40cab 100644 --- a/specs/003-vps-image-migration/tasks.md +++ b/specs/003-vps-image-migration/tasks.md @@ -34,7 +34,7 @@ description: "Task list for VPS Image Migration" - [X] T003 Update `parts/packages.nix` to build `emacs-vm` from nixpkgs/NixOS outputs (remove nixos-generators usage) - [X] T004 Remove nixos-generators input from `flake.nix` - [X] T005 Update `flake.lock` to drop nixos-generators entries -- [ ] T006 STOP: Ask user to validate `emacs-vm` build works without nixos-generators (confirm before proceeding) (reference `parts/packages.nix`) +- [X] T006 STOP: Ask user to validate `emacs-vm` build works without nixos-generators (confirm before proceeding) (reference `parts/packages.nix`) **Checkpoint**: Foundation ready after user confirmation @@ -48,11 +48,11 @@ description: "Task list for VPS Image Migration" ### Implementation for User Story 1 -- [ ] T007 [US1] Create `hosts/vps/configuration.nix` with base imports and minimal networking/remote access enablement -- [ ] T008 [US1] Register vps host in `parts/hosts.nix` using existing `createConfig` pattern -- [ ] T009 [US1] Add a Linode image build output for vps in `parts/packages.nix` using the upstream NixOS image workflow -- [ ] T010 [US1] Document the vps host entry and image artifact location in `docs/reference/index.md` -- [ ] T011 [US1] Add a manual validation checklist entry for vps boot connectivity and remote access in `specs/003-vps-image-migration/quickstart.md` +- [X] T007 [US1] Create `hosts/vps/configuration.nix` with base imports and minimal networking/remote access enablement +- [X] T008 [US1] Register vps host in `parts/hosts.nix` using existing `createConfig` pattern +- [X] T009 [US1] Add a Linode image build output for vps in `parts/packages.nix` using the upstream NixOS image workflow +- [X] T010 [US1] Document the vps host entry and image artifact location in `docs/reference/index.md` +- [X] T011 [US1] Add a manual validation checklist entry for vps boot connectivity and remote access in `specs/003-vps-image-migration/quickstart.md` **Checkpoint**: vps image builds and can boot with connectivity @@ -66,10 +66,10 @@ description: "Task list for VPS Image Migration" ### Implementation for User Story 2 -- [ ] T012 [US2] Set secure host posture for vps in `hosts/vps/configuration.nix` (secureHost enabled, secrets gated) -- [ ] T013 [US2] Add vps-specific sops-nix bootstrap settings in `hosts/vps/configuration.nix` (generate key on first boot; no baked key) -- [ ] T014 [US2] Document the enrollment and re-encryption steps in `docs/playbooks/enroll-vps.md` -- [ ] T015 [US2] Update secrets guidance to reference the vps enrollment flow in `docs/constitution.md` +- [X] T012 [US2] Set secure host posture for vps in `hosts/vps/configuration.nix` (secureHost enabled, secrets gated) +- [X] T013 [US2] Add vps-specific sops-nix bootstrap settings in `hosts/vps/configuration.nix` (generate key on first boot; no baked key) +- [X] T014 [US2] Document the enrollment and re-encryption steps in `docs/playbooks/enroll-vps.md` +- [X] T015 [US2] Update secrets guidance to reference the vps enrollment flow in `docs/constitution.md` **Checkpoint**: vps can boot without secrets, then unlocks secrets after enrollment and redeploy @@ -83,8 +83,8 @@ description: "Task list for VPS Image Migration" ### Implementation for User Story 3 -- [ ] T016 [US3] Add a rebuild helper script in `scripts/rebuild-vps.sh` with clear inputs and safety checks -- [ ] T017 [US3] Document remote rebuild usage and prerequisites (explicitly authorized operator machines only) in `docs/playbooks/vps-rebuild.md` +- [X] T016 [US3] Add a rebuild helper script in `scripts/rebuild-vps.sh` with clear inputs and safety checks +- [X] T017 [US3] Document remote rebuild usage and prerequisites (explicitly authorized operator machines only) in `docs/playbooks/vps-rebuild.md` **Checkpoint**: remote rebuild flow is repeatable and documented @@ -94,8 +94,8 @@ description: "Task list for VPS Image Migration" **Purpose**: Final consistency checks and documentation polish -- [ ] T018 [P] Ensure vps host is referenced in any host inventories or indexes in `docs/reference/index.md` -- [ ] T019 Validate quickstart steps still match implementation in `specs/003-vps-image-migration/quickstart.md` +- [X] T018 [P] Ensure vps host is referenced in any host inventories or indexes in `docs/reference/index.md` +- [X] T019 Validate quickstart steps still match implementation in `specs/003-vps-image-migration/quickstart.md` - [ ] T020 Validate existing host/image builds after migration (document results in `specs/003-vps-image-migration/quickstart.md`) ---