doc: SSH key management and secrets 📝

- Updated AGENTS.md to specify one key per purpose for SSH access, including naming conventions and configuration tips.
- Revised README.md to streamline the roadmap and link to SSH and secrets documentation.
- Created docs/ssh-and-secrets.md to outline the strategy for managing SSH keys and secrets in a public repo.
- Refined TODO.md to reflect the new approach for secrets and server configuration tasks.
This commit is contained in:
DannyDannyDanny 2026-03-01 11:55:44 +01:00
parent 1fdce52239
commit cd7658f452
5 changed files with 108 additions and 114 deletions

View file

@ -16,6 +16,14 @@ Do not automatically run rebuild commands - ask the user first.
No keys, tokens, or identifying secrets in the repo. Prefer `scp` or config outside the repo. No keys, tokens, or identifying secrets in the repo. Prefer `scp` or config outside the repo.
## SSH keys (one key per purpose)
We use **one key per purpose**, not one per machine: separate keys for server access, GitHub, Forgejo (and other forges if needed). Benefits: limit blast radius if a key is compromised; clear revocation; clear which key is for what.
- **Key names:** e.g. `id_ed25519_github`, `id_ed25519_forgejo`, `id_ed25519_servers` (Ed25519 preferred).
- **Config:** Use `~/.ssh/config` with `IdentityFile` and `IdentitiesOnly yes` per host so the right key is used. Keys and sensitive config stay outside the repo.
- **Server / NixOS:** Use actual key names on the machine (e.g. `id_ed25519_github`), not a generic `id_ed25519` (see Learnings below).
## Learnings (NixOS server) ## Learnings (NixOS server)
- Minimal ISO: use Ethernet or the graphical installer (WiFi on minimal is fiddly). - Minimal ISO: use Ethernet or the graphical installer (WiFi on minimal is fiddly).

View file

@ -1,86 +1,48 @@
# dotfiles # dotfiles
[`nixos`](https://nixos.org/) + [`tmux`](https://github.com/tmux/tmux/?tab=readme-ov-file#welcome-to-tmux) + [`fish`](https://fishshell.com/) + [`neovim`](https://neovim.io/) [nixos](https://nixos.org/) + [tmux](https://github.com/tmux/tmux) + [fish](https://fishshell.com/) + [neovim](https://neovim.io/)
This repo is an extension of [dannydannydanny/methodology](https://github.com/DannyDannyDanny/methodology/) Extension of [dannydannydanny/methodology](https://github.com/DannyDannyDanny/methodology).
## Roadmap: ## Roadmap
* configure [firefox-scrolling](firefox-scrolling.md) via terminal
* server cluster roadmap: [server](server.md); NixOS server flake and bootstrap: [nixos/readme.md](nixos/readme.md) (nixos-server).
* :art: check for `nvim checkhealth` status
* make tmux nice: https://www.youtube.com/watch?v=DzNmUNvnB04
* [fonts](https://www.programmingfonts.org/) - how does this relate to nerdfonts?
* [HN: What's on your home server](https://news.ycombinator.com/item?id=34271167)
* Jetson Nano Developer Kit SD Card Image [link](https://developer.nvidia.com/embedded/learn/get-started-jetson-nano-devkit)
* Raspberry Pi OS Lite (32-bit) [link](https://www.raspberrypi.com/software/operating-systems/#raspberry-pi-os-32-bit)
- [firefox-scrolling](firefox-scrolling.md) via terminal
- Server: [server](server.md); NixOS flake and bootstrap [nixos/readme.md](nixos/readme.md). SSH and secrets: [docs/ssh-and-secrets.md](docs/ssh-and-secrets.md).
- nvim checkhealth; tmux setup; [fonts](https://www.programmingfonts.org/) / nerdfonts; [HN: home server](https://news.ycombinator.com/item?id=34271167)
## Windows ## Windows
* disable system sounds: `start menu search: "change system sounds" -> set profile to None` - System sounds: None. Language/keyboard: en_US.
* change language / keyboard layout to `en_US` - [Powertoys](https://docs.microsoft.com/en-us/windows/powertoys/install) — remap CAPS to L-CTRL.
* [install powertoys](https://docs.microsoft.com/en-us/windows/powertoys/install#install-with-windows-executable-file-via-github) - [Alacritty](https://alacritty.org/) — config: `%AppData%/alacritty/alacritty.yml`.
* remap CAPS LOCK to L-CTRL
* install [alacritty](https://alacritty.org/) (use the installer, not portable)
* add alacritty config: `/mnt/c/Users/<winuser>/AppData/Roaming/alacritty/alacritty.yml`
### WSL ### WSL
Install via [nix-community/NixOS-WSL Quickstart](https://github.com/nix-community/NixOS-WSL?tab=readme-ov-file#quick-start) :white_check_mark: [Quickstart](https://github.com/nix-community/NixOS-WSL?tab=readme-ov-file#quick-start):
Setup dotfiles / config via github:
```bash ```bash
# git and github CLI tool in a temp shell
nix-shell -p gh git nix-shell -p gh git
# authenticate
gh auth login gh auth login
# clone dotfiles gh repo clone dannydannydanny/dotfiles && cd dotfiles
gh repo clone dannydannydanny/dotfiles # git checkout <branch> # if needed
# checkout the appropriate branch
git checkout feat/wsl-neovim-update
# rebuild WSL nixos using
sudo nixos-rebuild switch --flake ~/dotfiles/nixos#wsl sudo nixos-rebuild switch --flake ~/dotfiles/nixos#wsl
# rebuild macbook nixos using
# sudo nixos-rebuild switch --flake ~/dotfiles/nixos#macbook
``` ```
### Clone repo SSH method ### Clone via SSH
Skip this if you don't plan on getting SSH access to github repos and clone with HTTP instead
#### generate ssh
```
ssh-keygen -q -t ed25519 -N '' -f ~/.ssh/id_ed25519_github <<<y >/dev/null 2>&1
# echo 'older machines might not support ed25519, then use RSA with 4096 bit key' One key per purpose; see [AGENTS.md](AGENTS.md) and [docs/ssh-and-secrets.md](docs/ssh-and-secrets.md). Otherwise clone with HTTPS.
# echo 'ssh-keygen -q -t rsa -b 4096 -N '' -f ~/.ssh/id_rsa_github <<<y >/dev/null 2>&1'
# add the output to https://github.com/settings/ssh/new ```bash
cat ~/.ssh/id_*_github.pub ssh-keygen -q -t ed25519 -N '' -f ~/.ssh/id_ed25519_github <<<y
# add to https://github.com/settings/ssh/new cat ~/.ssh/id_ed25519_github.pub # add at https://github.com/settings/ssh/new
``` eval $(ssh-agent -s) # fish: eval (ssh-agent -c)
ssh-add ~/.ssh/id_ed25519_github
#### activate ssh git clone git@github.com:DannyDannyDanny/dotfiles.git && cd dotfiles
```
echo 'adding key to ssh-agent'
eval `ssh-agent -s` # if using fish shell run: eval "$(ssh-agent -c)"
ssh-add ~/.ssh/id_*_github
# download dotfiles repo
git clone git@github.com:DannyDannyDanny/dotfiles.git
# config git
cd dotfiles
git config user.name "DannyDannyDanny" git config user.name "DannyDannyDanny"
git config user.email "dth@taiga.ai" git config user.email "dth@taiga.ai"
git config pull.rebase false
git config push.autoSetupRemote true
# more git config: https://blog.gitbutler.com/how-git-core-devs-configure-git/
# install dotfiles
bash install.sh bash install.sh
# hop back out
cd ..
``` ```
## Good Reads / Philosophy ## Good reads
* sometimes [`TODO`s arent for doing](https://sophiebits.com/2025/07/21/todos-arent-for-doing)
- [TODOs aren't for doing](https://sophiebits.com/2025/07/21/todos-arent-for-doing)

36
TODO.md
View file

@ -1,26 +1,24 @@
# TODO # TODO
1. **Secrets** (started) 1. **Secrets** — Approach A (see [docs/ssh-and-secrets.md](docs/ssh-and-secrets.md)): public repo only, one key per purpose (AGENTS.md), server keys via scp. Optional later: private repo + sops-nix.
- SSH public keys removed from `nixos/hosts/nixos-server.nix` and `nixos/server-install-configuration.nix`. Keys are not managed by NixOS there; use scp (see comments in those files and server-quickstart.md). - **GitHub:** Use `id_ed25519_github`; in `~/.ssh/config`: `Host github.com` with `IdentityFile ~/.ssh/id_ed25519_github` and `IdentitiesOnly yes`. Remove `id_rsa_github` from GitHub and locally once confirmed unused.
- Optional: audit repo for other IDs (emails, UUIDs) if desired. - **nixos-server:** Switch to key auth if still on password: on server `mkdir -p ~/.ssh; chmod 700 ~/.ssh`; from Mac `scp ~/.ssh/id_ed25519_github.pub danny@SERVER:/tmp/`; on server `cat /tmp/id_ed25519_github.pub >> ~/.ssh/authorized_keys; chmod 600 ~/.ssh/authorized_keys`. Optional: create `id_ed25519_servers` and use only for servers (add Host in config).
- Check out friend's setup: public repo w config + setup; private repo w IDs, keys and secrets.
- **SSH keys (one key per purpose).** Strategy: AGENTS.md. Actions:
- **GitHub:** In use: `id_ed25519_github`. Add `~/.ssh/config`: `Host github.com` with `IdentityFile ~/.ssh/id_ed25519_github` and `IdentitiesOnly yes`. Remove `id_rsa_github` from GitHub and locally once confirmed unused.
- **nixos-server:** No `~/.ssh/authorized_keys` on server → currently password auth. To switch to key auth: on server `mkdir -p ~/.ssh; chmod 700 ~/.ssh`; from Mac `scp ~/.ssh/id_ed25519_github.pub danny@SERVER:/tmp/`; on server `cat /tmp/id_ed25519_github.pub >> ~/.ssh/authorized_keys; chmod 600 ~/.ssh/authorized_keys`. Optional: create `id_ed25519_servers` and use that only for server (then add Host in config).
- **Forgejo:** When needed: create `id_ed25519_forgejo`, add to forge, add Host in `~/.ssh/config`. - **Forgejo:** When needed: create `id_ed25519_forgejo`, add to forge, add Host in `~/.ssh/config`.
2. ~~**Server hardware before testing**~~ Done. Fetched via `ssh danny@server 'sudo cat /etc/nixos/hardware-configuration.nix'`, replaced stub; added boot.loader and system.stateVersion; flake check passes. 2. **Server**
- Only I use the machine. Access: SSH keys only (no password auth).
- Continue configuring (add services in `hosts/nixos-server.nix` as needed).
- SSH: key-only auth; disable password auth. Optionally restrict SSH to LAN.
- Passwordless sudo for wheel.
3. **Server** 3. Rename nixos-server to <something-cooler>
- Continue configuring the server (add more services to `hosts/nixos-server.nix` as needed). - Shortlist hostnames; then do flake + hostname + docs in one pass.
- Make sure SSH is only possible via LAN, using ssh keys and no password - **Monte Cristothemed candidates (two-word, non-human):**
- Make sudo not require a password - Ships / sea: sunken-ship, phantom-ship, rusty-anchor, salty-wind, stormy-wave, calm-harbor, distant-shore, foreign-port, wooden-hull, anchor-chain
- Prison / stone: prison-rock, cold-stone, iron-chain, damp-cell, guard-tower, midnight-bell, stony-corridor, broken-chain
- Secrets / treasure: buried-treasure, secret-cave, forgotten-tunnel, hidden-key, rusty-sword, faded-parchment, ancient-map, broken-seal, buried-chest
- Atmosphere: strange-companion, masked-ball, poison-vial
4. **Verify** 4. Give <something-cooler> wifi access instead of ethernet.
- After 24: confirm server hardware in repo, flake builds, auto-rebuild works. On server, `systemctl is-active dotfiles-rebuild.timer` should be `active` once the flake config is live (see nixos/readme.md).
5. Rename nixos-server to <something-cooler> 5. Host telegram bot once again (for what purpose?)
6. Give <something-cooler> wifi access in stead of using ethernet.
7. Host telegram bot once again (for what purpose?)

47
docs/ssh-and-secrets.md Normal file
View file

@ -0,0 +1,47 @@
# SSH and secrets
Strategy for SSH key management and secrets with a public NixOS/dotfiles repo and a handful of servers.
## Chosen approach: A (current)
- **Repo:** Public only. No keys or tokens in the repo ([AGENTS.md](../AGENTS.md)).
- **SSH keys:** One key per purpose (e.g. `id_ed25519_github`, `id_ed25519_servers`, `id_ed25519_forgejo`). Configure `~/.ssh/config` with `IdentityFile` and `IdentitiesOnly yes` per host. Keys live outside the repo.
- **Server authorized_keys:** Not managed by Nix. Push public keys via `scp` and append to `~/.ssh/authorized_keys` on each server. See [server-quickstart.md](../server-quickstart.md) and comments in [nixos/hosts/nixos-server.nix](../nixos/hosts/nixos-server.nix).
Benefits: no private repo, simple, works with public dotfiles. Trade-off: one-time (or scripted) scp step per server; authorized_keys are not declarative in Nix.
## Optional future: private secrets repo + sops-nix
If you later want declarative secrets (passwords, tokens) or authorized_keys in Nix, a common pattern is:
- **Public repo:** Config only (like this one).
- **Private repo:** Encrypted secret files (e.g. `secrets.yaml`), added as a flake input via `git+ssh://...`.
- **sops-nix:** Decrypts at activation using age (e.g. host SSH key). Secrets end up in `/run/secrets/`; you can reference them in config (e.g. `hashedPasswordFile`, or `openssh.authorizedKeys.keyFiles` for authorized_keys).
```mermaid
flowchart LR
subgraph public [Public repo]
config[NixOS config]
end
subgraph private [Private repo]
secrets[Encrypted secrets]
end
subgraph build [Build]
flake[Flake input git+ssh]
sops[sops-nix]
end
config --> flake
private --> flake
flake --> sops
sops --> secrets
```
References: [sops-nix](https://github.com/Mic92/sops-nix), NixOS options `users.users.<name>.openssh.authorizedKeys.keyFiles` and `sops.secrets`.
## Long-term plan
1. **Now:** Use approach A. Document and follow one key per purpose and scp-based server keys; see AGENTS.md and server-quickstart.md.
2. **Optional later:** If you add a private secrets repo, add it as a flake input, enable sops-nix with a small module (defaultSopsFile from that input, age with host SSH key). Use for hashedPassword and service secrets first.
3. **Optional later:** To make authorized_keys declarative, add an encrypted file (one key per line) in the private repo and set `users.users.<name>.openssh.authorizedKeys.keyFiles = [ config.sops.secrets.authorized_keys.path ];` in the server host module.
AGENTS.md remains the source of truth for key naming and one-key-per-purpose.

View file

@ -1,48 +1,27 @@
Rebuild nixos and points to dotfiles dir: # NixOS flake
``` Rebuild from dotfiles dir:
```bash
sudo nixos-rebuild switch --flake ~/dotfiles/nixos#macbookair sudo nixos-rebuild switch --flake ~/dotfiles/nixos#macbookair
# or # or #wsl
sudo nixos-rebuild switch --flake ~/dotfiles/nixos#wsl # macOS: cd ~/dotfiles/nixos && darwin-rebuild switch --flake .
# or (macOS)
sudo -H nix run github:lnl7/nix-darwin -- switch --flake ~/dotfiles/nixos#Daniel-Macbook-Air
``` ```
## Server (nixos-server) ## Server (nixos-server)
One-time on the server (git is not installed until after the first rebuild, so use nix run to get git): One-time bootstrap (no git until first rebuild):
```bash ```bash
nix run --extra-experimental-features "nix-command flakes" nixpkgs#git -- clone https://github.com/DannyDannyDanny/dotfiles.git /tmp/dotfiles nix run --extra-experimental-features "nix-command flakes" nixpkgs#git -- clone https://github.com/DannyDannyDanny/dotfiles.git /tmp/dotfiles
sudo mv /tmp/dotfiles /etc/dotfiles sudo mv /tmp/dotfiles /etc/dotfiles
# Enable flakes for this run (needed if the current system config does not)
sudo nixos-rebuild switch --flake /etc/dotfiles/nixos#nixos-server --option accept-flake-config true sudo nixos-rebuild switch --flake /etc/dotfiles/nixos#nixos-server --option accept-flake-config true
``` ```
If that fails with "does not provide attribute ... nixos-rebuild", enable flakes for the Nix daemon via the current config (on NixOS, `/etc/nix/nix.conf` is often read-only), then build and switch manually.
**From your Mac:** push a config that enables flakes, then on the server copy it and rebuild: If the daemon doesnt have flakes: copy [server-configuration-with-flakes.nix](server-configuration-with-flakes.nix) to `/etc/nixos/configuration.nix`, run `sudo nixos-rebuild switch`, then build and switch to the flake (see [server-quickstart.md](../server-quickstart.md) for SSH keys).
```bash
scp nixos/server-configuration-with-flakes.nix danny@<server>:/tmp/configuration.nix
```
**On the server:**
```bash
sudo cp /tmp/configuration.nix /etc/nixos/configuration.nix
sudo nixos-rebuild switch
```
Then build and switch to the flake:
```bash
sudo nix build /etc/dotfiles/nixos#nixosConfigurations.nixos-server.config.system.build.toplevel -o /tmp/nixos-result
sudo /tmp/nixos-result/bin/switch-to-configuration switch
```
Use `git@github.com:DannyDannyDanny/dotfiles.git` if the repo is private (clone as danny then `sudo mv` and `sudo chown -R root:root /etc/dotfiles`). SSH keys (not in repo): `scp ~/.ssh/*.pub danny@server:/tmp/`, then on server `mkdir -p ~/.ssh; cat /tmp/*.pub >> ~/.ssh/authorized_keys`. See [docs/ssh-and-secrets.md](../docs/ssh-and-secrets.md).
SSH keys for danny (not in repo): from your machine `scp ~/.ssh/*.pub danny@server:/tmp/`, then on server `mkdir -p ~/.ssh; cat /tmp/*.pub >> ~/.ssh/authorized_keys`. Timer: every 15 min the server pulls and rebuilds when `main` changes. Config: `hosts/nixos-server.nix`, `hosts/nixos-server-hardware.nix`.
After that, a timer pulls and rebuilds every 15 min when `main` changes. Config lives in `hosts/nixos-server.nix` and `hosts/nixos-server-hardware.nix`. No git in PATH: `sudo nix run nixpkgs#git -- -C /etc/dotfiles pull origin main`.
**Pull when git is not in PATH** (e.g. before first rebuild or when `sudo git` says "command not found"):
```bash
sudo nix run nixpkgs#git -- -C /etc/dotfiles pull origin main
```
Then run `sudo nixos-rebuild switch --flake /etc/dotfiles/nixos#nixos-server` as usual. After that, git is in the system profile; for manual pulls you can use `sudo /run/current-system/sw/bin/git -C /etc/dotfiles pull origin main` if `sudo git` still isnt in PATH.