feat: add agenix rekey
This commit is contained in:
parent
e0c8b30fe2
commit
2315fbdb71
11 changed files with 282 additions and 9 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -1 +1,2 @@
|
|||
**/result
|
||||
secrets/rekeyed
|
||||
|
|
|
|||
18
README.md
18
README.md
|
|
@ -7,6 +7,24 @@ The contents of this repository are organized as follows:
|
|||
- `systems`: These are complete nix modules for configuring specific systems. Unforutnately they're not "role based" systems, but explicit systems. I'd like to change that.
|
||||
- `images`: This directory contains a flake for building SD card images. Ideally, SD card images could also be complete systems e.g. for building a pi sd card. However, cross-compiling issues have prevented me from doing so. For now, sd card images are phase 1 in and two-phase install process.
|
||||
|
||||
## Adding secrets
|
||||
|
||||
1. Encrypt the secret using the master key's public key
|
||||
|
||||
> echo "my-super-secret-password" | age -r age13sgljsr9srgxjxncl49qsn9dkkstcqct3ck9s7n2yu4lzelgp4uqcajgtj -o ./path/to/my-secret.age
|
||||
|
||||
2. Add the secret to your Nix configuration
|
||||
```
|
||||
age.secrets.my-secret = {
|
||||
rekeyFile = ./secrets/my-secret.age; # Point to the file you just created
|
||||
# mode = "600"; # Optional, default is 400
|
||||
# owner = "root"; # Optional
|
||||
};
|
||||
```
|
||||
|
||||
3. Rekey the secrets. This will read the master key (via your gopass wrapper), decrypt my-secret.age, and re-encrypt it for specific hosts that use it
|
||||
> nix run .#rekey
|
||||
|
||||
## Systems
|
||||
|
||||
### z1
|
||||
|
|
|
|||
|
|
@ -14,6 +14,12 @@ in {
|
|||
with types; {
|
||||
enable = mkEnableOption "AI Agents";
|
||||
|
||||
githubPatPath = mkOption {
|
||||
type = nullOr path;
|
||||
default = null;
|
||||
description = "Path to the decrypted file containing the GitHub Personal Access Token.";
|
||||
};
|
||||
|
||||
mcpServers = mkOption {
|
||||
description = "MCP Configurations";
|
||||
type = attrs;
|
||||
|
|
@ -22,6 +28,20 @@ in {
|
|||
args = ["mcp-server-git" "--repository" "${config.home.homeDirectory}/proj/nixos-system"];
|
||||
command = "uvx";
|
||||
};
|
||||
github =
|
||||
if cfg.githubPatPath != null
|
||||
then {
|
||||
command = "${pkgs.bash}/bin/bash";
|
||||
args = [
|
||||
"-c"
|
||||
"export GITHUB_PERSONAL_ACCESS_TOKEN=$(cat ${cfg.githubPatPath}) && exec ${pkgs.nodejs}/bin/npx -y @modelcontextprotocol/server-github"
|
||||
];
|
||||
}
|
||||
else {
|
||||
# Opencode is not yet compatible with using github's remote MCP server with oauth
|
||||
type = "http";
|
||||
url = "https://api.githubcopilot.com/mcp/";
|
||||
};
|
||||
glean = {
|
||||
type = "http";
|
||||
url = "https://greenhouse-be.glean.com/mcp/default";
|
||||
|
|
@ -40,21 +60,18 @@ in {
|
|||
home = {
|
||||
packages = with pkgs; [
|
||||
uv # for uvx
|
||||
nodejs
|
||||
];
|
||||
};
|
||||
|
||||
programs = {
|
||||
# aider-chat.enable = true;
|
||||
# codex.enable = true;
|
||||
|
||||
opencode = {
|
||||
enable = true;
|
||||
enableMcpIntegration = true;
|
||||
rules = ''
|
||||
'';
|
||||
settings = {
|
||||
theme = "opencode";
|
||||
# model = "anthropic/claude-sonnet-4-20250514";
|
||||
theme = "nord";
|
||||
autoshare = false;
|
||||
autoupdate = true;
|
||||
};
|
||||
|
|
|
|||
11
common/rekey.nix
Normal file
11
common/rekey.nix
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
{...}: {
|
||||
age.rekey = {
|
||||
masterIdentities = [
|
||||
{
|
||||
identity = "master.key";
|
||||
pubkey = "age13sgljsr9srgxjxncl49qsn9dkkstcqct3ck9s7n2yu4lzelgp4uqcajgtj";
|
||||
}
|
||||
];
|
||||
storageMode = "local";
|
||||
};
|
||||
}
|
||||
5
common/secrets.nix
Normal file
5
common/secrets.nix
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{...}: {
|
||||
age.secrets.opencode-github-mcp-pat = {
|
||||
rekeyFile = ./secrets/opencode-github-mcp-pat.age;
|
||||
};
|
||||
}
|
||||
6
common/secrets/opencode-github-mcp-pat.age
Normal file
6
common/secrets/opencode-github-mcp-pat.age
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
age-encryption.org/v1
|
||||
-> X25519 qGmWsJ4WYLsV4N5P486vamO/L9v9VcB+9aUGrLTefiY
|
||||
Ic1r0SEf8MDT77iwcmuUFRHUfqYZ87EWiGjCEKhF0+E
|
||||
--- 0rHqnF7yMeiJgDP0oOzkJMEVdIiAhFiVJcCX/lewpMU
|
||||
P±M[Œx{…F'\Ħ:LêÎ#R€Òh‡sªKÓkfüá‚chDl£˜
|
||||
·zMÜúP<C3BA>>ŠØ×àQ{?—™²{Š#ˆ¢lA
|
||||
155
flake.lock
155
flake.lock
|
|
@ -23,13 +23,37 @@
|
|||
"type": "github"
|
||||
}
|
||||
},
|
||||
"btsw": {
|
||||
"agenix-rekey": {
|
||||
"inputs": {
|
||||
"devshell": "devshell",
|
||||
"flake-parts": "flake-parts",
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
],
|
||||
"pre-commit-hooks": "pre-commit-hooks",
|
||||
"treefmt-nix": "treefmt-nix"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1759699908,
|
||||
"narHash": "sha256-kYVGY8sAfqwpNch706Fy2+/b+xbtfidhXSnzvthAhIQ=",
|
||||
"owner": "oddlama",
|
||||
"repo": "agenix-rekey",
|
||||
"rev": "42362b12f59978aabf3ec3334834ce2f3662013d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "oddlama",
|
||||
"repo": "agenix-rekey",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"btsw": {
|
||||
"inputs": {
|
||||
"devshell": "devshell_2",
|
||||
"flake-parts": "flake-parts_2",
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
],
|
||||
"systems": "systems_2"
|
||||
},
|
||||
"locked": {
|
||||
|
|
@ -84,6 +108,27 @@
|
|||
}
|
||||
},
|
||||
"devshell": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"agenix-rekey",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1728330715,
|
||||
"narHash": "sha256-xRJ2nPOXb//u1jaBnDP56M7v5ldavjbtR6lfGqSvcKg=",
|
||||
"owner": "numtide",
|
||||
"repo": "devshell",
|
||||
"rev": "dd6b80932022cea34a019e2bb32f6fa9e494dfef",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "devshell",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"devshell_2": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs"
|
||||
},
|
||||
|
|
@ -143,7 +188,44 @@
|
|||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-compat": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1696426674,
|
||||
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
|
||||
"owner": "edolstra",
|
||||
"repo": "flake-compat",
|
||||
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "edolstra",
|
||||
"repo": "flake-compat",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-parts": {
|
||||
"inputs": {
|
||||
"nixpkgs-lib": [
|
||||
"agenix-rekey",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1733312601,
|
||||
"narHash": "sha256-4pDvzqnegAfRkPwO3wmwBhVi/Sye1mzps0zHWYnP88c=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "205b12d8b7cd4802fbcb8e8ef6a0f1408781a4f9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-parts_2": {
|
||||
"inputs": {
|
||||
"nixpkgs-lib": "nixpkgs-lib"
|
||||
},
|
||||
|
|
@ -161,7 +243,7 @@
|
|||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-parts_2": {
|
||||
"flake-parts_3": {
|
||||
"inputs": {
|
||||
"nixpkgs-lib": [
|
||||
"nur",
|
||||
|
|
@ -221,6 +303,28 @@
|
|||
"type": "github"
|
||||
}
|
||||
},
|
||||
"gitignore": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"agenix-rekey",
|
||||
"pre-commit-hooks",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1709087332,
|
||||
"narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "gitignore.nix",
|
||||
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hercules-ci",
|
||||
"repo": "gitignore.nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"greenhouse-nix-modules": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
|
|
@ -563,7 +667,7 @@
|
|||
},
|
||||
"nur": {
|
||||
"inputs": {
|
||||
"flake-parts": "flake-parts_2",
|
||||
"flake-parts": "flake-parts_3",
|
||||
"nixpkgs": "nixpkgs_6"
|
||||
},
|
||||
"locked": {
|
||||
|
|
@ -580,9 +684,33 @@
|
|||
"type": "github"
|
||||
}
|
||||
},
|
||||
"pre-commit-hooks": {
|
||||
"inputs": {
|
||||
"flake-compat": "flake-compat",
|
||||
"gitignore": "gitignore",
|
||||
"nixpkgs": [
|
||||
"agenix-rekey",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1735882644,
|
||||
"narHash": "sha256-3FZAG+pGt3OElQjesCAWeMkQ7C/nB1oTHLRQ8ceP110=",
|
||||
"owner": "cachix",
|
||||
"repo": "pre-commit-hooks.nix",
|
||||
"rev": "a5a961387e75ae44cc20f0a57ae463da5e959656",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "cachix",
|
||||
"repo": "pre-commit-hooks.nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"agenix": "agenix",
|
||||
"agenix-rekey": "agenix-rekey",
|
||||
"btsw": "btsw",
|
||||
"default-browser": "default-browser",
|
||||
"disko": "disko",
|
||||
|
|
@ -742,6 +870,27 @@
|
|||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"treefmt-nix": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"agenix-rekey",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1735135567,
|
||||
"narHash": "sha256-8T3K5amndEavxnludPyfj3Z1IkcFdRpR23q+T0BVeZE=",
|
||||
"owner": "numtide",
|
||||
"repo": "treefmt-nix",
|
||||
"rev": "9e09d30a644c57257715902efbb3adc56c79cf28",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "treefmt-nix",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
|
|
|
|||
45
flake.nix
45
flake.nix
|
|
@ -30,6 +30,10 @@
|
|||
url = "github:ryantm/agenix";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
inputs.agenix-rekey = {
|
||||
url = "github:oddlama/agenix-rekey";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
inputs.default-browser.url = "github:szympajka/nix-browser";
|
||||
|
||||
|
|
@ -71,6 +75,7 @@
|
|||
};
|
||||
|
||||
outputs = {
|
||||
self,
|
||||
default-browser,
|
||||
nixpkgs,
|
||||
nixos-hardware,
|
||||
|
|
@ -78,6 +83,7 @@
|
|||
home-manager,
|
||||
homeage,
|
||||
agenix,
|
||||
agenix-rekey,
|
||||
nur,
|
||||
kitty-grab,
|
||||
helix,
|
||||
|
|
@ -126,8 +132,34 @@
|
|||
qutebrowser-overlay
|
||||
];
|
||||
};
|
||||
|
||||
# Wrapper to handle the dynamic master key
|
||||
mkRekeyApp = system: pkgs: let
|
||||
rekeyPackage = inputs.agenix-rekey.packages.${system}.default;
|
||||
in {
|
||||
type = "app";
|
||||
program = "${pkgs.writeShellScript "rekey-wrapper" ''
|
||||
# Create the file expected by the config
|
||||
# We use the repo root context
|
||||
REPO_ROOT=$(git rev-parse --show-toplevel)
|
||||
MASTER_KEY_FILE="$REPO_ROOT/master.key"
|
||||
|
||||
# Cleanup on exit
|
||||
trap 'rm -f "$MASTER_KEY_FILE"' EXIT
|
||||
|
||||
# Get the master key from gopass
|
||||
echo "Retrieving master key from gopass..."
|
||||
${pkgs.gopass}/bin/gopass show -o systems/age.master > "$MASTER_KEY_FILE"
|
||||
chmod 600 "$MASTER_KEY_FILE"
|
||||
|
||||
# Run the actual rekey command
|
||||
${rekeyPackage}/bin/agenix rekey "$@"
|
||||
''}";
|
||||
};
|
||||
in {
|
||||
inherit lib;
|
||||
apps.${system}.rekey = mkRekeyApp system pkgs;
|
||||
apps.${darwinSystem}.rekey = mkRekeyApp darwinSystem darwin-pkgs;
|
||||
homeConfigurations = {
|
||||
"adriano@zw" = lib.homeManagerConfiguration {
|
||||
inherit pkgs;
|
||||
|
|
@ -221,6 +253,8 @@
|
|||
}
|
||||
nur.modules.nixos.default
|
||||
agenix.nixosModules.default
|
||||
agenix-rekey.nixosModules.default
|
||||
./common/rekey.nix
|
||||
./systems/zw/configuration.nix
|
||||
];
|
||||
};
|
||||
|
|
@ -232,6 +266,8 @@
|
|||
{environment.systemPackages = [agenix.packages.x86_64-linux.default];}
|
||||
nur.modules.nixos.default
|
||||
agenix.nixosModules.default
|
||||
agenix-rekey.nixosModules.default
|
||||
./common/rekey.nix
|
||||
inputs.disko.nixosModules.default
|
||||
./systems/jellybee/configuration.nix
|
||||
home-manager.nixosModules.home-manager
|
||||
|
|
@ -253,6 +289,8 @@
|
|||
{environment.systemPackages = [agenix.packages.x86_64-linux.default];}
|
||||
nur.modules.nixos.default
|
||||
agenix.nixosModules.default
|
||||
agenix-rekey.nixosModules.default
|
||||
./common/rekey.nix
|
||||
./systems/homebee/configuration.nix
|
||||
home-manager.nixosModules.home-manager
|
||||
{
|
||||
|
|
@ -273,6 +311,9 @@
|
|||
|
||||
modules = [
|
||||
default-browser.darwinModules.default-browser
|
||||
agenix.darwinModules.default
|
||||
agenix-rekey.nixosModules.default
|
||||
./common/rekey.nix
|
||||
./systems/greenhouse/configuration.nix
|
||||
inputs.greenhouse-nix-modules.nix-darwin.${system}
|
||||
inputs.home-manager.darwinModules.home-manager
|
||||
|
|
@ -286,5 +327,9 @@
|
|||
}
|
||||
];
|
||||
};
|
||||
agenix-rekey = inputs.agenix-rekey.configure {
|
||||
userFlake = self;
|
||||
nixosConfigurations = self.nixosConfigurations // self.darwinConfigurations;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,19 @@
|
|||
{pkgs, ...}: let
|
||||
{
|
||||
pkgs,
|
||||
inputs,
|
||||
...
|
||||
}: let
|
||||
primaryUser = "adriano.caloiaro";
|
||||
in {
|
||||
imports = [
|
||||
../../common/secrets.nix
|
||||
];
|
||||
config = {
|
||||
age.secrets.opencode-github-mcp-pat.owner = "adriano.caloiaro";
|
||||
age.rekey = {
|
||||
hostPubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINCARMVM8mwZBCFsnmr/hd0atFEj9oTOATzBajLGkS9V adriano.caloiaro@JJTH7GH17J";
|
||||
localStorageDir = ./. + "/secrets/rekeyed/";
|
||||
};
|
||||
environment = {
|
||||
etc = {
|
||||
"dict.conf".text = "server dict.org";
|
||||
|
|
@ -13,6 +23,8 @@ in {
|
|||
NH_FLAKE = "/Users/${primaryUser}/proj/nixos-system";
|
||||
};
|
||||
systemPackages = with pkgs; [
|
||||
age
|
||||
inputs.agenix.packages.${pkgs.system}.default
|
||||
gnupg
|
||||
gopass
|
||||
helix
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
ai-agents = {
|
||||
enable = true;
|
||||
crush.enable = true;
|
||||
githubPatPath = "/run/agenix/opencode-github-mcp-pat";
|
||||
};
|
||||
modules.aerospace.enable = true;
|
||||
programs = {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
age-encryption.org/v1
|
||||
-> ssh-ed25519 gSCyBg GF2cFn5yM9tpobmGGtbsyMx1ij7CqHaLv4G2BqdlH0c
|
||||
6/lzyxeGW2Qd8Po3Ip2JPRpw74oom8t2Ld+pt1xqQRw
|
||||
-> @=^/BY^-grease zz[nV *V_j svy3GEzY
|
||||
LguZReDWJQDqZ9hE3V9WjSm+GKKzTFPBZQ6z8Ij/8YEGjVvKF1R+sUWwT1AQfC7V
|
||||
HbKHsd744oyZ1y8rF6cS9QUHWUIMGJmXJk23lTCX
|
||||
--- 1XXOAhgivbMgtoq5r0YUEXv7vcVr/vdE9HQrBaJSC/w
|
||||
UŔmpOŤ+YÉÎąCŽv<C5BD>ŃV<C583>ďßR~7÷DĽÂ…‚ţąLŢp@ŽĂ)AGyďH$Ł`,Ť<>‹H* «/NYmăPŐšóň
|
||||
Loading…
Reference in a new issue