Compare commits
No commits in common. "033755b4bb1b4188645f62f9114a965bc71fb4e2" and "28d78dce6194ef3d09398686ea534c071274ec83" have entirely different histories.
033755b4bb
...
28d78dce61
9 changed files with 3 additions and 211 deletions
|
@ -1,7 +0,0 @@
|
||||||
keys:
|
|
||||||
- &rafiq age12l33pas8eptwjc7ewux3d8snyzfzwz0tn9qg5kw8le79fswmjgjqdjgyy6
|
|
||||||
creation_rules:
|
|
||||||
- path_regex: \.(yaml)$
|
|
||||||
key_groups:
|
|
||||||
- age:
|
|
||||||
- *rafiq
|
|
21
flake.lock
generated
21
flake.lock
generated
|
@ -215,31 +215,10 @@
|
||||||
"import-tree": "import-tree",
|
"import-tree": "import-tree",
|
||||||
"make-shell": "make-shell",
|
"make-shell": "make-shell",
|
||||||
"nixpkgs": "nixpkgs",
|
"nixpkgs": "nixpkgs",
|
||||||
"sops-nix": "sops-nix",
|
|
||||||
"systems": "systems",
|
"systems": "systems",
|
||||||
"text": "text"
|
"text": "text"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sops-nix": {
|
|
||||||
"inputs": {
|
|
||||||
"nixpkgs": [
|
|
||||||
"nixpkgs"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1751606940,
|
|
||||||
"narHash": "sha256-KrDPXobG7DFKTOteqdSVeL1bMVitDcy7otpVZWDE6MA=",
|
|
||||||
"owner": "Mic92",
|
|
||||||
"repo": "sops-nix",
|
|
||||||
"rev": "3633fc4acf03f43b260244d94c71e9e14a2f6e0d",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "Mic92",
|
|
||||||
"repo": "sops-nix",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"systems": {
|
"systems": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1681028828,
|
"lastModified": 1681028828,
|
||||||
|
|
|
@ -21,11 +21,6 @@
|
||||||
};
|
};
|
||||||
# impermanence provides a nice abstraction over linking files from /persist
|
# impermanence provides a nice abstraction over linking files from /persist
|
||||||
impermanence.url = "github:nix-community/impermanence";
|
impermanence.url = "github:nix-community/impermanence";
|
||||||
# sops-nix lets us version control secrets like passwords and api keys
|
|
||||||
sops-nix = {
|
|
||||||
url = "github:Mic92/sops-nix";
|
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
|
||||||
};
|
|
||||||
# import-tree imports all nix files in a given directory.
|
# import-tree imports all nix files in a given directory.
|
||||||
import-tree.url = "github:vic/import-tree";
|
import-tree.url = "github:vic/import-tree";
|
||||||
# files lets us write text files and automatically add checks for them
|
# files lets us write text files and automatically add checks for them
|
||||||
|
|
|
@ -1,16 +1,8 @@
|
||||||
{
|
{ lib, inputs, ... }:
|
||||||
lib,
|
|
||||||
config,
|
|
||||||
inputs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
let
|
||||||
inherit (lib.options) mkOption;
|
inherit (lib.options) mkOption;
|
||||||
inherit (lib.types) path lazyAttrsOf raw;
|
inherit (lib.types) path lazyAttrsOf raw;
|
||||||
inherit (inputs.flake-parts.lib) mkSubmoduleOptions;
|
inherit (inputs.flake-parts.lib) mkSubmoduleOptions;
|
||||||
inherit (cfg.lib.attrsets) firstAttrNameMatching;
|
|
||||||
cfg = config.flake;
|
|
||||||
username = firstAttrNameMatching (_: v: v.primary or false) cfg.manifest.users;
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.flake = mkSubmoduleOptions {
|
options.flake = mkSubmoduleOptions {
|
||||||
|
@ -22,13 +14,5 @@ in
|
||||||
type = path;
|
type = path;
|
||||||
default = "";
|
default = "";
|
||||||
};
|
};
|
||||||
admin = mkOption {
|
|
||||||
type = lazyAttrsOf raw;
|
|
||||||
default = { };
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config.flake.admin = cfg.manifest.users.${username} // {
|
|
||||||
inherit username;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,54 +0,0 @@
|
||||||
{ lib, ... }:
|
|
||||||
let
|
|
||||||
inherit (builtins) attrNames head;
|
|
||||||
inherit (lib.trivial) pipe;
|
|
||||||
inherit (lib.attrsets) filterAttrs;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
flake.lib.attrsets = {
|
|
||||||
/**
|
|
||||||
`firstAttrNameMatching pred set` filters an attribute set `set` based on a predicate `pred`
|
|
||||||
and returns the *first* attribute name that satisfies the predicate.
|
|
||||||
|
|
||||||
# Example
|
|
||||||
|
|
||||||
```nix
|
|
||||||
let
|
|
||||||
mySet = {
|
|
||||||
a = { value = 1; };
|
|
||||||
b = { value = 2; };
|
|
||||||
c = { value = 3; };
|
|
||||||
};
|
|
||||||
|
|
||||||
isGreaterThanOne = name: value: value.value > 1;
|
|
||||||
|
|
||||||
result = firstAttrNameMatching isGreaterThanOne mySet;
|
|
||||||
|
|
||||||
in
|
|
||||||
result
|
|
||||||
# Output: "b"
|
|
||||||
```
|
|
||||||
|
|
||||||
# Type
|
|
||||||
|
|
||||||
```
|
|
||||||
firstAttrNameMatching :: (String -> Any -> Bool) -> AttrSet -> String
|
|
||||||
```
|
|
||||||
|
|
||||||
# Arguments
|
|
||||||
|
|
||||||
pred
|
|
||||||
: A function that takes an attribute name and its value and returns a boolean.
|
|
||||||
|
|
||||||
set
|
|
||||||
: The attribute set to filter.
|
|
||||||
*/
|
|
||||||
firstAttrNameMatching =
|
|
||||||
pred: set:
|
|
||||||
pipe set [
|
|
||||||
(filterAttrs pred)
|
|
||||||
attrNames
|
|
||||||
head
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,41 +1,10 @@
|
||||||
{ lib, config, ... }:
|
{ lib, config, ... }:
|
||||||
let
|
let
|
||||||
cfg = config.flake;
|
cfg = config.flake;
|
||||||
inherit (builtins) foldl' attrNames;
|
|
||||||
inherit (lib.attrsets) mapAttrs;
|
inherit (lib.attrsets) mapAttrs;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
flake.lib.modules = {
|
flake.lib.modules = {
|
||||||
/**
|
|
||||||
Fold over the users list and create an attribute set.
|
|
||||||
|
|
||||||
# Inputs
|
|
||||||
|
|
||||||
`f`
|
|
||||||
|
|
||||||
: A function that takes the name of a user and returns an attribute set.
|
|
||||||
|
|
||||||
# Type
|
|
||||||
|
|
||||||
```
|
|
||||||
userListToAttrs :: (String -> AttrSet) -> AttrSet
|
|
||||||
```
|
|
||||||
|
|
||||||
# Examples
|
|
||||||
:::{.example}
|
|
||||||
## `userListToAttrs` usage example
|
|
||||||
|
|
||||||
```nix
|
|
||||||
flake.manifest.users.rafiq = { ... };
|
|
||||||
flake.modules.homeManager.users = userListToAttrs (name: {
|
|
||||||
${name}.home.username = name;
|
|
||||||
});
|
|
||||||
=> flake.modules.homeManager.default.users.rafiq.home.username = "rafiq";
|
|
||||||
```
|
|
||||||
|
|
||||||
:::
|
|
||||||
*/
|
|
||||||
userListToAttrs = f: foldl' (acc: elem: acc // (f elem)) { } (attrNames cfg.manifest.users);
|
|
||||||
/**
|
/**
|
||||||
Return an attribute set for use with a option that needs to be used for all users.
|
Return an attribute set for use with a option that needs to be used for all users.
|
||||||
|
|
||||||
|
|
|
@ -1,52 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
inputs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
cfg = config.flake;
|
|
||||||
inherit (builtins) readFile;
|
|
||||||
inherit (lib.meta) getExe;
|
|
||||||
inherit (lib.strings) trim;
|
|
||||||
inherit (cfg.admin) username pubkey;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
flake.modules.nixos.default =
|
|
||||||
{ config, ... }:
|
|
||||||
{
|
|
||||||
imports = [ inputs.sops-nix.nixosModules.sops ];
|
|
||||||
config.sops = {
|
|
||||||
defaultSopsFile = "${cfg.root}/secrets/secrets.yaml";
|
|
||||||
age.sshKeyPaths = [
|
|
||||||
"/persist${config.users.defaultUserHome}/${username}/.ssh/id_ed25519"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
perSystem =
|
|
||||||
{ pkgs, ... }:
|
|
||||||
{
|
|
||||||
files.files = [
|
|
||||||
{
|
|
||||||
path_ = ".sops.yaml";
|
|
||||||
drv =
|
|
||||||
pkgs.writeText ".sops.yaml" # yaml
|
|
||||||
''
|
|
||||||
keys:
|
|
||||||
- &${username} ${trim (
|
|
||||||
readFile "${
|
|
||||||
pkgs.runCommand "" { } ''
|
|
||||||
mkdir $out; echo ${pubkey} | ${getExe pkgs.ssh-to-age} > $out/agepubkey
|
|
||||||
''
|
|
||||||
}/agepubkey"
|
|
||||||
)}
|
|
||||||
creation_rules:
|
|
||||||
- path_regex: \.(yaml)$
|
|
||||||
key_groups:
|
|
||||||
- age:
|
|
||||||
- *${username}
|
|
||||||
'';
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,7 +1,7 @@
|
||||||
{ config, lib, ... }:
|
{ config, lib, ... }:
|
||||||
let
|
let
|
||||||
cfg = config.flake;
|
cfg = config.flake;
|
||||||
inherit (cfg.lib.modules) userListToAttrs forAllUsers';
|
inherit (cfg.lib.modules) forAllUsers';
|
||||||
inherit (lib.lists) optional;
|
inherit (lib.lists) optional;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
@ -19,17 +19,13 @@ in
|
||||||
mutableUsers = false;
|
mutableUsers = false;
|
||||||
groups.users.gid = 100;
|
groups.users.gid = 100;
|
||||||
users = forAllUsers' (
|
users = forAllUsers' (
|
||||||
name: value: {
|
_: value: {
|
||||||
isNormalUser = true;
|
isNormalUser = true;
|
||||||
hashedPasswordFile = config.sops.secrets."${name}/hashedPassword".path;
|
|
||||||
extraGroups = optional (value.primary or false) "wheel";
|
extraGroups = optional (value.primary or false) "wheel";
|
||||||
openssh.authorizedKeys.keys = [ value.pubkey ];
|
openssh.authorizedKeys.keys = [ value.pubkey ];
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
sops.secrets = userListToAttrs (name: {
|
|
||||||
"${name}/hashedPassword".neededForUsers = true;
|
|
||||||
});
|
|
||||||
home-manager.users = forAllUsers' (
|
home-manager.users = forAllUsers' (
|
||||||
name: _: {
|
name: _: {
|
||||||
home.username = name;
|
home.username = name;
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
rafiq:
|
|
||||||
password: ENC[AES256_GCM,data:8KAfatz+YSaNozd5VGo=,iv:LNRxt47iBKSWzMZuBHSxv/qDZ2h6JiTIPps7OK/o7uU=,tag:oiSfLyRVswb/wxSTE69QMA==,type:str]
|
|
||||||
hashedPassword: ENC[AES256_GCM,data:NogYQ3kR1TseC79HIXARrXhIncCnvxzf9zMF2QrUyTmojTffPXRGtMdjNpfMEFj5dkKfZujBL/QTIpPFFTm1py7Dreg5/9VSKQ==,iv:IwfZsrsJbLYG1ELte6aBHUtff6hIQu9rHT5tSvILIGQ=,tag:oav3paDcUY+cl4FJlZa90A==,type:str]
|
|
||||||
sops:
|
|
||||||
age:
|
|
||||||
- recipient: age12l33pas8eptwjc7ewux3d8snyzfzwz0tn9qg5kw8le79fswmjgjqdjgyy6
|
|
||||||
enc: |
|
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBVd09tYkhKUkVjNTBRdld6
|
|
||||||
a1RkUnZqdnRqMlFTSGgwUFVCZlRhL0tLTnpVCjNXVjZldzNUOE9DQ0ZGejhWakY2
|
|
||||||
TmRIZnpobE0ydDhNSDdJQUp2U3pSTzgKLS0tIDkxU3Fxa2lMUkhZY0g1Wm02T2ZE
|
|
||||||
UkQwOWZtVXVPSGJiRk1qRHVHYkN2cDgKLiYiA0q5se/oHfGRqvHLn3gRRDfmefEZ
|
|
||||||
z2U2N1Tjt0QgCfYOOXVfPV9F36a7PpabFva5ElSazawHgvI+Bot6og==
|
|
||||||
-----END AGE ENCRYPTED FILE-----
|
|
||||||
lastmodified: "2025-07-07T08:56:26Z"
|
|
||||||
mac: ENC[AES256_GCM,data:2uGjIMxRgk7uWToQC4MrHpHFAt4bI7sEhaHvPU6Ae3bvRVH/TdJxZtikSPe95LEwReOuBmPajbcM580/d3Jt6VbA7nZzj1JduVscrRkSAFCzZp9Ti/mbOGITPJa6xWSGwVF1wSN3BnHXYIHDcKeSGtUdP7L7nBZr1KXPkok4NCo=,iv:+ELIes7lzb8M6CvOemAcyoq7Rx7L6NkNmHwntJN/RSc=,tag:ubyxO6VllH9cQK3VbvxiGg==,type:str]
|
|
||||||
unencrypted_suffix: _unencrypted
|
|
||||||
version: 3.10.2
|
|
Loading…
Add table
Add a link
Reference in a new issue