feat: Manage secrets w/ sops-nix

Closes #1
This commit is contained in:
Madeleine Sydney
2024-12-28 22:28:56 -07:00
parent fa3bd72816
commit 52dc849c67
10 changed files with 186 additions and 9 deletions

13
.sops.yaml Normal file
View File

@@ -0,0 +1,13 @@
keys:
- &crumb age1qayk0d0f765v57pedm7mtau6qkmv8rh6jtaqm40g5g9armaty4jqc0v0y2
creation_rules:
# System secrets
- path_regex: secrets\.(yaml|json|env|ini)$
key_groups:
- age:
- *crumb
# User secrets
- path_regex: users/[^/]+/secrets\.(yaml|json|env|ini)$
key_groups:
- age:
- *crumb

View File

@@ -145,7 +145,12 @@ I don't know anything about either.
** TODO password store 4 firefox ** TODO password store 4 firefox
** TODO secrets ** TODO password store w/ age
https://github.com/FiloSottile/passage
** DONE secrets
CLOSED: [2024-12-29 Sun 01:41]
** TODO niri ** TODO niri

37
flake.lock generated
View File

@@ -187,13 +187,48 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs_5": {
"locked": {
"lastModified": 1731763621,
"narHash": "sha256-ddcX4lQL0X05AYkrkV2LMFgGdRvgap7Ho8kgon3iWZk=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "c69a9bffbecde46b4b939465422ddc59493d3e4d",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": { "root": {
"inputs": { "inputs": {
"disko": "disko", "disko": "disko",
"home-manager": "home-manager", "home-manager": "home-manager",
"impermanence": "impermanence", "impermanence": "impermanence",
"niri": "niri", "niri": "niri",
"nixpkgs": "nixpkgs_4" "nixpkgs": "nixpkgs_4",
"sops-nix": "sops-nix"
}
},
"sops-nix": {
"inputs": {
"nixpkgs": "nixpkgs_5"
},
"locked": {
"lastModified": 1734546875,
"narHash": "sha256-6OvJbqQ6qPpNw3CA+W8Myo5aaLhIJY/nNFDk3zMXLfM=",
"owner": "Mic92",
"repo": "sops-nix",
"rev": "ed091321f4dd88afc28b5b4456e0a15bd8374b4d",
"type": "github"
},
"original": {
"owner": "Mic92",
"repo": "sops-nix",
"type": "github"
} }
}, },
"xwayland-satellite-stable": { "xwayland-satellite-stable": {

View File

@@ -11,6 +11,8 @@
home-manager.url = "github:nix-community/home-manager"; home-manager.url = "github:nix-community/home-manager";
niri.url = "github:sodiboo/niri-flake"; niri.url = "github:sodiboo/niri-flake";
sops-nix.url = "github:Mic92/sops-nix";
}; };
outputs = { nixpkgs, ... }@inputs: outputs = { nixpkgs, ... }@inputs:
@@ -47,6 +49,7 @@
inputs.self.nixosModules.default inputs.self.nixosModules.default
inputs.disko.nixosModules.disko inputs.disko.nixosModules.disko
inputs.sops-nix.nixosModules.sops
inputs.impermanence.nixosModules.impermanence inputs.impermanence.nixosModules.impermanence
# Directory name should always match host name. # Directory name should always match host name.
@@ -125,6 +128,7 @@
}; };
}) })
inputs.sops-nix.homeManagerModules.sops
inputs.impermanence.homeManagerModules.impermanence inputs.impermanence.homeManagerModules.impermanence
]; ];
}; };

View File

@@ -8,7 +8,7 @@
sydnix = { sydnix = {
filesystemType = "btrfs"; filesystemType = "btrfs";
gpg.enable = true; # gpg.enable = true;
users.users = [ users.users = [
"crumb" "crumb"
@@ -101,6 +101,9 @@
services.openssh.enable = true; services.openssh.enable = true;
services.openssh.settings.PermitRootLogin = "yes"; services.openssh.settings.PermitRootLogin = "yes";
# TODO: Move to defaults.
users.mutableUsers = false;
# services.xserver.windowManager.qtile = { # services.xserver.windowManager.qtile = {
# enable = true; # enable = true;
# extraPackages = python3Packages: with python3Packages; [ # extraPackages = python3Packages: with python3Packages; [

28
modules/home/sops.nix Normal file
View File

@@ -0,0 +1,28 @@
{ config, lib, pkgs, ... }:
with lib;
let cfg = config.sydnix.sops;
in {
options = {
sydnix.sops = {
enable = mkEnableOption "Sops";
keyFile = mkOption {
description = "Path to an Age key file.";
type = types.path;
default = config.home.homeDirectory + "/key.txt";
};
secrets = mkOption {
description = "Secrets passed directly to sops-nix.";
};
};
};
config = mkIf cfg.enable {
sops = {
age.keyFile = cfg.keyFile;
defaultSopsFile = ../../users/${config.home.username}/secrets.yaml;
secrets = cfg.secrets;
};
};
}

37
modules/nixos/sops.nix Normal file
View File

@@ -0,0 +1,37 @@
{ config, lib, pkgs, ... }:
with lib;
let cfg = config.sydnix.sops;
in {
options = {
sydnix.sops = {
enable = mkEnableOption "Sops secrets";
keyFile = mkOption {
description = "Path to an Age key file.";
type = types.path;
default = "/persist/key.txt";
};
secrets = mkOption {
description = "Secrets passed directly to sops-nix.";
};
package = mkOption {
description = "Sops CLI package. If null, nothing will be installed.";
type = with types; nullOr package;
default = pkgs.sops;
};
};
};
config = mkIf cfg.enable {
sops.defaultSopsFile = ../../secrets.yaml;
sops.defaultSopsFormat = "yaml";
environment.systemPackages =
mkIf (cfg.package != null)
[ cfg.package ];
sops.age.keyFile = cfg.keyFile;
sops.secrets = cfg.secrets;
};
}

21
secrets.yaml Normal file
View File

@@ -0,0 +1,21 @@
example-key: ENC[AES256_GCM,data:ddKerh17p/+kDzSlSQ==,iv:62BgArZBCfcxL/qeVRluaSbY5y1GHtuiAbqXRB3NuG4=,tag:chcteZECw/SHFQctM+swVA==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1qayk0d0f765v57pedm7mtau6qkmv8rh6jtaqm40g5g9armaty4jqc0v0y2
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBzSU40YUdJbEh6b01FdHYv
SjhKNFhwTmtiRVVKTC80T3ZjZnI4LzZIY2tBCms3S1lJcHo4M242ZmZBNTQrbmxa
YUxJb085Q2JWc2JNVkNrSU5SQktwbjQKLS0tIEd6aEo2NlNnVjJYZ3FISGVYZGNm
VFh1RFYvMUNnY1QveXF6TkVSMGpOTlUK9HrBWz8BzbA+HJ8XLFc5ji9QDKw1TuGx
pcDUwNy8DdSBhEtYQ7DxQ2U379IRQY1CN5qL3SdZnicg3zMhV5TWSA==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2024-12-29T07:21:13Z"
mac: ENC[AES256_GCM,data:4SO/ho4QYlwwFthsbBhHTsOIwKwq0xPHUaabt+OZbTzETSg9UDTiLi8LZci+CUh9mKDwwh1CKJxIsl4MiOei+pLU0PB9uaudb9n68pPjeIxzJYKjjXwXzpfXipiAYcpSJJybmbJoivHncJoOuerBMmOlZ1HmHK9pcE2aJmGaBDY=,iv:HJF6A4bOJnXpMctHCTV1Cw7T8DAq4AXuBdqJzGo4vVI=,tag:2zD++PfLS6/4sp2SeBZLiw==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.9.1

View File

@@ -4,18 +4,28 @@
# TODO: Don't hard-code `persist`. Use # TODO: Don't hard-code `persist`. Use
# config.sydnix.impermanence.persistGroupName. # config.sydnix.impermanence.persistGroupName.
extraGroups = [ "wheel" "persist" ]; extraGroups = [ "wheel" "persist" ];
# Change this immediately after installation! initialHashedPassword =
initialPassword = "password123"; "$y$j9T$aEFDDwdTZbAc6VQRXrkBJ0$K8wxTGTWDihyX1wxJ.ZMH//wmQFfrGGUkLkxIU0Lyq8";
}; };
homeConfiguration = { config, lib, pkgs, ... }: { homeConfiguration = { config, lib, pkgs, ... }: {
imports = [ ./programs.nix ]; imports = [ ./programs.nix ];
sydnix = {
sops = {
enable = true;
secrets = {
example-user-key = {};
};
};
};
home = { home = {
stateVersion = "18.09";
packages = [ packages = [
pkgs.hello
# pkgs.wezterm
]; ];
# Don't touch!
stateVersion = "18.09";
}; };
}; };
} }

21
users/crumb/secrets.yaml Normal file
View File

@@ -0,0 +1,21 @@
example-user-key: ENC[AES256_GCM,data:zefLZFp/MuxwrhbNhiCRWOCG,iv:IFwI3e2+uq1yv+hWQnHcX25XGiHa3AFqeIr5LW+2KFo=,tag:yS6KzPK7robKJsupZW8a2w==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1qayk0d0f765v57pedm7mtau6qkmv8rh6jtaqm40g5g9armaty4jqc0v0y2
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA2NE5mTER1OXpadmNzaXV6
b3RSbS9yWTN0NWR4Z2xBRnRSanQxYXdRT2drClVrSk1raXE4ZUVIVmxoMzJWU1Rj
VmxzdnVSUVEvQk1JcFo4Qjh6YWhiME0KLS0tIHh1OCtzSUZpWWhrbXB4SlA4RVBs
VVBqSEM2bVFBU0M5YzZBQWIwUmVXUXMKvWb57Rc+rO5M8Pf7lvbSjuZB4FrHgT3A
uBQHH3wpv0BVVzL8tucPnwNxDnwpWvFxxwNVy/rtfs6y6HPu6fuOsA==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2024-12-29T08:21:03Z"
mac: ENC[AES256_GCM,data:08lmfeXvrhipenfCO9AjdahGSvfaUO74EVlbtjhNw+Pjlu3SQNlqTBdzPFwpebCphNnryun/WGgT6fopgyITdkd1V7DGQLV184LRe0lD5qA3DEBm+uEPBqFpXT0AYucylWEam8paZYZ8HjdPL91I1H1MTDqGcO2dYhAh59JWXfE=,iv:fY+FxlfexYkkQsYp/On/QEhiKrZyzJ6mzTaXIxY44u0=,tag:U29ULu1vNi2z/MXMz9PkTg==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.9.1