mirror of
https://github.com/smg1024/nix-darwin.git
synced 2026-05-22 20:32:59 +09:00
feat: add secret-backed kmeat ssh config
This commit is contained in:
parent
7be0d2eafc
commit
725e9f6d87
7 changed files with 180 additions and 36 deletions
7
Justfile
7
Justfile
|
|
@ -10,6 +10,12 @@ default:
|
||||||
#
|
#
|
||||||
############################################################################
|
############################################################################
|
||||||
|
|
||||||
|
[group('desktop')]
|
||||||
|
dry-run hostname:
|
||||||
|
nix build .#darwinConfigurations.{{ hostname }}.system \
|
||||||
|
--dry-run \
|
||||||
|
--extra-experimental-features 'nix-command flakes'
|
||||||
|
|
||||||
[group('desktop')]
|
[group('desktop')]
|
||||||
darwin hostname:
|
darwin hostname:
|
||||||
nix build .#darwinConfigurations.{{ hostname }}.system \
|
nix build .#darwinConfigurations.{{ hostname }}.system \
|
||||||
|
|
@ -75,4 +81,3 @@ fmt range:
|
||||||
[group('nix')]
|
[group('nix')]
|
||||||
gcroot:
|
gcroot:
|
||||||
ls -al /nix/var/nix/gcroots/auto/
|
ls -al /nix/var/nix/gcroots/auto/
|
||||||
|
|
||||||
|
|
|
||||||
18
flake.lock
generated
18
flake.lock
generated
|
|
@ -99,11 +99,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1778444552,
|
"lastModified": 1778628724,
|
||||||
"narHash": "sha256-f18pIiR9q/p1vHY93gmAum7aHhQOG49oGvAB9+lptRo=",
|
"narHash": "sha256-VNG6hJ146VEenXcDrB3t6MVnrMx+gtyCWTCDkzOp9Qs=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "home-manager",
|
"repo": "home-manager",
|
||||||
"rev": "dcebe66f958673729896eec2de4abfd86ef22d21",
|
"rev": "6a0bbd6b4720da1c9ce7ebf35ff5c41a82db367a",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -184,11 +184,11 @@
|
||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1778458615,
|
"lastModified": 1778580735,
|
||||||
"narHash": "sha256-cY07EsdhBJ8tFXPzDYevgqxRev9ZLxFonuq9wmq5kwg=",
|
"narHash": "sha256-t+8AVV8ExvOmslz2sLIgw/hJBKlyl65rJvxjvvjHgpE=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "c6e5ca3c836a5f4dd9af9f2c1fc1c38f0fac988a",
|
"rev": "48d91f2c0ce7b9e589f967d4f685153dd765dcdd",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -225,11 +225,11 @@
|
||||||
"systems": "systems"
|
"systems": "systems"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1778408907,
|
"lastModified": 1778618635,
|
||||||
"narHash": "sha256-QXjdRz5fssxAWDrtfBYxvjMtTqJzQAbnAmX3u22xCck=",
|
"narHash": "sha256-eiZkwksjBS4yr5uPt9rzoEQrnuwTgmFVFb6glGrNGF4=",
|
||||||
"owner": "notashelf",
|
"owner": "notashelf",
|
||||||
"repo": "nvf",
|
"repo": "nvf",
|
||||||
"rev": "e86a92e4b29b499e5f1285b737b7612115103da9",
|
"rev": "0f7a1ff6ecff4a1f4fa2bbdd0f42151706a26831",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
secrets = {
|
secrets = {
|
||||||
"github_ssh_key" = {};
|
"github_ssh_key" = {};
|
||||||
"github_cli_token" = {};
|
"github_cli_token" = {};
|
||||||
|
"kmeat_mac_mini_ssh_key" = {};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,13 @@
|
||||||
identitiesOnly = true;
|
identitiesOnly = true;
|
||||||
identityFile = [config.sops.secrets."github_ssh_key".path];
|
identityFile = [config.sops.secrets."github_ssh_key".path];
|
||||||
};
|
};
|
||||||
|
"kmeat-mac-mini" = {
|
||||||
|
hostname = "ai.kmeat.com";
|
||||||
|
user = "kmeat";
|
||||||
|
port = 10222;
|
||||||
|
identitiesOnly = true;
|
||||||
|
identityFile = [config.sops.secrets."kmeat_mac_mini_ssh_key".path];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,11 @@ config = {
|
||||||
mods = "SUPER",
|
mods = "SUPER",
|
||||||
action = wezterm.action.ActivateCommandPalette,
|
action = wezterm.action.ActivateCommandPalette,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key = "Enter",
|
||||||
|
mods = "ALT",
|
||||||
|
action = wezterm.action.DisableDefaultAssignment,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
125
secrets/README.md
Normal file
125
secrets/README.md
Normal file
|
|
@ -0,0 +1,125 @@
|
||||||
|
# Secrets
|
||||||
|
|
||||||
|
This directory stores SOPS-encrypted secrets used by the `secrets` Home Manager
|
||||||
|
aspect. Do not commit plaintext secrets.
|
||||||
|
|
||||||
|
## Current Setup
|
||||||
|
|
||||||
|
- Secret file: `secrets/poby.yaml`
|
||||||
|
- SOPS rules: `.sops.yaml`
|
||||||
|
- Age key file: `~/.config/sops/age/keys.txt`
|
||||||
|
- Secret declarations: `modules/aspects/_secrets/sops.nix`
|
||||||
|
- SSH host wiring: `modules/aspects/_ssh/ssh.nix`
|
||||||
|
|
||||||
|
## Add An SSH Private Key
|
||||||
|
|
||||||
|
From the repository root, open a shell with `sops` and `age`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nix-shell -p sops age
|
||||||
|
```
|
||||||
|
|
||||||
|
Open the encrypted secret file with the age key:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
SOPS_AGE_KEY_FILE="$HOME/.config/sops/age/keys.txt" sops secrets/poby.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
Add a top-level key name and paste the private key as a YAML block scalar:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
workstation_ssh_key: |
|
||||||
|
-----BEGIN OPENSSH PRIVATE KEY-----
|
||||||
|
...
|
||||||
|
-----END OPENSSH PRIVATE KEY-----
|
||||||
|
```
|
||||||
|
|
||||||
|
Save and quit the editor. SOPS will re-encrypt the file automatically.
|
||||||
|
|
||||||
|
Do not edit the `sops:` metadata block manually.
|
||||||
|
|
||||||
|
## Generate A New SSH Key First
|
||||||
|
|
||||||
|
If the key does not exist yet, generate it before opening SOPS:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ssh-keygen -t ed25519 -f ~/.ssh/workstation_ssh_key -C "workstation"
|
||||||
|
```
|
||||||
|
|
||||||
|
Register the public key wherever the remote service expects it:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cat ~/.ssh/workstation_ssh_key.pub
|
||||||
|
```
|
||||||
|
|
||||||
|
Then copy the private key contents into `secrets/poby.yaml` with SOPS.
|
||||||
|
|
||||||
|
After the private key is stored in SOPS and deployed through `sops-nix`, remove
|
||||||
|
any temporary plaintext private key if it is no longer needed outside this repo.
|
||||||
|
|
||||||
|
## Declare The Secret In Nix
|
||||||
|
|
||||||
|
Add the secret name to `modules/aspects/_secrets/sops.nix`:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
secrets = {
|
||||||
|
"github_ssh_key" = {};
|
||||||
|
"github_cli_token" = {};
|
||||||
|
"workstation_ssh_key" = {};
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## Use The Secret For SSH
|
||||||
|
|
||||||
|
Reference the SOPS-managed secret path from the matching SSH host block in
|
||||||
|
`modules/aspects/_ssh/ssh.nix`:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
"workstation-host" = {
|
||||||
|
hostname = "example.com";
|
||||||
|
user = "example";
|
||||||
|
identitiesOnly = true;
|
||||||
|
identityFile = [config.sops.secrets."workstation_ssh_key".path];
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## Verify
|
||||||
|
|
||||||
|
Confirm the encrypted file contains the expected top-level secret names without
|
||||||
|
printing secret values:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
SOPS_AGE_KEY_FILE="$HOME/.config/sops/age/keys.txt" \
|
||||||
|
sops -d secrets/poby.yaml \
|
||||||
|
| awk -F: '/^[A-Za-z0-9_]+:/ { print $1 }'
|
||||||
|
```
|
||||||
|
|
||||||
|
Confirm no plaintext private key was written into the encrypted file:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
rg -n "BEGIN OPENSSH PRIVATE KEY|END OPENSSH PRIVATE KEY" secrets/poby.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected result: no output.
|
||||||
|
|
||||||
|
Evaluate the Darwin configuration:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nix build .#darwinConfigurations.fenrir.system \
|
||||||
|
--dry-run \
|
||||||
|
--extra-experimental-features 'nix-command flakes'
|
||||||
|
```
|
||||||
|
|
||||||
|
Build and switch:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
just darwin fenrir
|
||||||
|
```
|
||||||
|
|
||||||
|
Test the SSH alias:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ssh -o BatchMode=yes workstation-host true
|
||||||
|
```
|
||||||
|
|
||||||
|
No output means the SSH command succeeded.
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
github_ssh_key: ENC[AES256_GCM,data:3EPsAfo11u5p48B2myGkHmKcbj0jpFXbc1LxSzpRSFa4yBuRwBIne2hCcgpbqF3pMJml9FuhWtamVPsuhJoRHHonTdgPb5Y48uqegl4HAJefUBWPJEZ0q3F990wqpcF3P8PK5NjjwkZdzJlzXSucjISxEI65q43+/KAlxylu0DMwClZY1lF3DEwg2V9cycmgDWN4XWYQLp89aAXY2A6mC1nHQNI3UbI3VogEVooALSiWgNGZVAWbLNgpPN8qc2zqfPqVdC0Qna+ucRA5MEkvyhyWnjvzoKgFv8n0IHLd+Y676R9SaP56zxFdZUgyQ7nUNSWW8fWaHuL9EvvK4uTaJAGv2Je5AyehRKZ6Sw9/3O2hugCG8d1DhMcc7A1p2wiEScy/m3MDtMUv9ndk0rmk6/+7bH1Ha71tOsAjR08zOPBs5hrDOEXuA0yURqEV9HdNWSt1zQ0NrWsxOJTHeKw6jWG0shWpvLftqoLbhTYGIeNkxhSft7Vm9Cp23hCvG2J38BtRV108UITKvDg9U8utVVR/oCFIBuZkJ2j7,iv:t82G7RM7QybvOW008lZh6XNcmvP0XkBUbgjKMlq3Ov0=,tag:7Y1H0QPsA3k6NOiy3ock+Q==,type:str]
|
github_ssh_key: ENC[AES256_GCM,data:3EPsAfo11u5p48B2myGkHmKcbj0jpFXbc1LxSzpRSFa4yBuRwBIne2hCcgpbqF3pMJml9FuhWtamVPsuhJoRHHonTdgPb5Y48uqegl4HAJefUBWPJEZ0q3F990wqpcF3P8PK5NjjwkZdzJlzXSucjISxEI65q43+/KAlxylu0DMwClZY1lF3DEwg2V9cycmgDWN4XWYQLp89aAXY2A6mC1nHQNI3UbI3VogEVooALSiWgNGZVAWbLNgpPN8qc2zqfPqVdC0Qna+ucRA5MEkvyhyWnjvzoKgFv8n0IHLd+Y676R9SaP56zxFdZUgyQ7nUNSWW8fWaHuL9EvvK4uTaJAGv2Je5AyehRKZ6Sw9/3O2hugCG8d1DhMcc7A1p2wiEScy/m3MDtMUv9ndk0rmk6/+7bH1Ha71tOsAjR08zOPBs5hrDOEXuA0yURqEV9HdNWSt1zQ0NrWsxOJTHeKw6jWG0shWpvLftqoLbhTYGIeNkxhSft7Vm9Cp23hCvG2J38BtRV108UITKvDg9U8utVVR/oCFIBuZkJ2j7,iv:t82G7RM7QybvOW008lZh6XNcmvP0XkBUbgjKMlq3Ov0=,tag:7Y1H0QPsA3k6NOiy3ock+Q==,type:str]
|
||||||
github_cli_token: ENC[AES256_GCM,data:8+IqQnxA/Qm7dsFVNYAVWfYVTNTbmW1bevGnF8e635wU2fBjPpnsZg==,iv:v0sV8Te6eIqKcu6lArU4OfHAP5ucfmPHLnqtFW8dZxk=,tag:VjVdJqIbYrNlcGyKSa3Fmg==,type:str]
|
github_cli_token: ENC[AES256_GCM,data:8+IqQnxA/Qm7dsFVNYAVWfYVTNTbmW1bevGnF8e635wU2fBjPpnsZg==,iv:v0sV8Te6eIqKcu6lArU4OfHAP5ucfmPHLnqtFW8dZxk=,tag:VjVdJqIbYrNlcGyKSa3Fmg==,type:str]
|
||||||
|
kmeat_mac_mini_ssh_key: ENC[AES256_GCM,data:rDopWoLKy0lXIDxKKKGoY8NFINIfJBIu/6fgcki0lr6zL/GAl1OmMY5T/GJkNOAhZjGSww4U9zOAzH5KPAe6QznstAqZz3T9qor1VOte7hd7r2iKrurc4ezZ0CLeP5y1rrKuruQ1xh47t5z0y6s2tP+QtDTShTYlCyCC1BS+k/1US+gpk7+qe/3U0qM5HLcu6m11Hp7sExEESffjTU+YeqaGAGBStY4uAhHeLZHvTZNHKcb9HrLREp91SwmvRLa9n5NAKyXZJQysyHyNHRTYOYEOpNt9hmKoRNSNg4qcLvZjmEtlLA2I11RPvgmiNhKQKpewj6CVKNWGUsaxIG7eWNvwPziaZBViNNP65WrULeo7d1csf/VdGegRK09b1iBAr+/JlsNryiBSYmVTDJWBFrte7LEanXyZJ8LLPebqHXJmmyznfUriz3maTBTkJNfyqqfuSLT2l6j1NHM0GBqnNOV+5gkjU9CuOn/75fiMMW2b8OtJjyJ1gj4GCf7DLZIg2Jod,iv:RnRaShSyw8OS/R0tkESezqgCyQk/fQNrS19gnfzhudY=,tag:ak46MeblmraeHI3V2fZy2Q==,type:str]
|
||||||
sops:
|
sops:
|
||||||
age:
|
age:
|
||||||
- recipient: age1qeyrh6e40nek3da4mnj298cy2l3aswe7432us30d2p93akcvp9zqext63j
|
- enc: |
|
||||||
enc: |
|
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBQaUt1Y1hFS1N0djNEU3NQ
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBQaUt1Y1hFS1N0djNEU3NQ
|
||||||
QjFIMk9GZkxoeks2WUx0WlBNblR6dEpSZ2tBCkl3Wk1xaDlXWEFnYkIzZ2J3bUxw
|
QjFIMk9GZkxoeks2WUx0WlBNblR6dEpSZ2tBCkl3Wk1xaDlXWEFnYkIzZ2J3bUxw
|
||||||
|
|
@ -11,7 +11,8 @@ sops:
|
||||||
QXQ3YUkxWnk2U0hacjBMZDQ5WlNFQTAKzzzcoCZg7iNg5QoajxSpP1ka5qIIfaNE
|
QXQ3YUkxWnk2U0hacjBMZDQ5WlNFQTAKzzzcoCZg7iNg5QoajxSpP1ka5qIIfaNE
|
||||||
5VMXcX4qL0OszsO3j3ShYIT02m3XqkSeaOMSz+uty2BWtPCDZoLHrg==
|
5VMXcX4qL0OszsO3j3ShYIT02m3XqkSeaOMSz+uty2BWtPCDZoLHrg==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
lastmodified: "2026-04-16T13:40:02Z"
|
recipient: age1qeyrh6e40nek3da4mnj298cy2l3aswe7432us30d2p93akcvp9zqext63j
|
||||||
mac: ENC[AES256_GCM,data:u6uqpTdLRE8gB4WphelVhMRKouTZDlNqpa1R6ACXu1ek/9sVaZLxyAhY/xrKhYhGu7MHN0RDG0sHousRtdqCTGE/mDiCEj4hVufctpefpwS9amDRH2XW1kOcheEHvNjPTimKPsJJXutcofxm1LtBZkbkhflrsRQLyOvkc/674eI=,iv:bHtn8yrudQnwH2rPzfUEU25Mar4uwPZK3beU0uLgxY4=,tag:6Fwl6ZeM83w6eTfxBNiqtw==,type:str]
|
lastmodified: "2026-05-13T12:58:01Z"
|
||||||
|
mac: ENC[AES256_GCM,data:RJM9WeCDqWPYMs8xROuZ8TrBfIU3T6t2jy/VW6qZJ6YAwRjkGQ8Bkr+YlZaqpWxr4dRnuUNA1NonZZJxW5xfGti+umsRHiGEa1fGTz+0sq5TIK9XpYIOZPy0AksKSGMvvfG8VZbdBYE+DT97yWSANqWeuY6vnaGThkJXyLDfnAs=,iv:qpQq7H2kIgETS43FCLW2WorU91yC6drSqVQhvhniCRs=,tag:hPW7FvOiMjcHH7WZ09+psw==,type:str]
|
||||||
unencrypted_suffix: _unencrypted
|
unencrypted_suffix: _unencrypted
|
||||||
version: 3.12.1
|
version: 3.13.0
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue