Compare commits

..

1 commit

Author SHA1 Message Date
Chris Kruining
69ecd4ff89
trying some stuff 2025-09-01 10:07:28 +02:00
48 changed files with 360 additions and 2685 deletions

2
.envrc
View file

@ -1,2 +0,0 @@
# shellcheck shell=bash
use flake

View file

@ -7,9 +7,10 @@ on:
- main
jobs:
kaas:
runs-on: nix
hello:
name: Print hello world
runs-on: default
steps:
- name: Echo
run: |
nix --version
echo "Hello, world!"

8
.gitignore vendored
View file

@ -1,8 +1,2 @@
# ---> Nix
# Ignore build outputs from performing a nix-build or `nix build` command
result
result-*
# Ignore automatically generated direnv output
.direnv
*.qcow2

View file

@ -1,14 +0,0 @@
set unstable := true
set quiet := true
_default: list
[doc('List machines')]
list:
ls -1 ../systems/x86_64-linux/
[doc('Update the target machine')]
[no-exit-message]
update machine:
just assert '-d "../systems/x86_64-linux/{{ machine }}"' "Machine {{ machine }} does not exist, must be one of: $(ls ../systems/x86_64-linux/ | tr '\n' ' ')"
nixos-rebuild switch --use-remote-sudo --target-host {{ machine }} --flake ..#{{ machine }}

View file

@ -1,33 +0,0 @@
set unstable := true
set quiet := true
base_path := invocation_directory() / "systems/x86_64-linux"
_default:
just --list
[doc('list all vars of the target machine')]
list machine:
sops decrypt {{ base_path }}/{{ machine }}/secrets.yml
edit machine:
sops edit {{ base_path }}/{{ machine }}/secrets.yml
@set machine key value:
sops set {{ base_path }}/{{ machine }}/secrets.yml "$(printf '%s\n' '["{{ key }}"]' | sed -E 's#/#"]["#g; s/\["([0-9]+)"\]/[\1]/g')" "\"$(echo '{{ value }}' | sed 's/\"/\\\"/g')\""
git add {{ base_path }}/{{ machine }}/secrets.yml
git commit -m 'chore(secrets): set secret "{{ key }}" for machine "{{ machine }}"' -- {{ base_path }}/{{ machine }}/secrets.yml > /dev/null
echo "Done"
get machine key:
sops decrypt {{ base_path }}/{{ machine }}/secrets.yml | yq ".$(echo "{{ key }}" | sed -E 's/\//./g')"
remove machine key:
sops unset {{ base_path }}/{{ machine }}/secrets.yml "$(printf '%s\n' '["{{ key }}"]' | sed -E 's#/#"]["#g; s/\["([0-9]+)"\]/[\1]/g')"
git add {{ base_path }}/{{ machine }}/secrets.yml
git commit -m 'chore(secrets): removed secret "{{ key }}" from machine "{{ machine }}"' -- {{ base_path }}/{{ machine }}/secrets.yml > /dev/null
echo "Done"

View file

@ -1,40 +0,0 @@
_default:
just --list --list-submodules
set unstable
set quiet
mod vars '.just/vars.just'
mod machine '.just/machine.just'
[doc('Show information about project')]
show:
echo "show"
[doc('update the flake dependencies')]
update:
nix flake update
git commit -m 'chore: update dependencies' -- ./flake.lock > /dev/null
echo "Done"
[doc('Rebase branch on main')]
rebase:
git stash -q \
&& git fetch \
&& git rebase origin/main \
&& git stash pop -q
echo "Done"
[doc('Introspection on flake output')]
select key:
nix eval --json .#{{ key }} | jq .
#===============================================================================================
# Utils
# ===============================================================================================
[no-cd]
[no-exit-message]
[private]
assert condition message:
[ {{ condition }} ] || { echo -e 1>&2 "\n\x1b[1;41m Error \x1b[0m {{ message }}\n"; exit 1; }

View file

@ -1,11 +0,0 @@
keys:
- &ulmo_1 age19qfpf980tadguqq44zf6xwvjvl428dyrj46ha3n6aeqddwhtnuqqml7etq
- &ulmo_2 age1ewes0f5snqx3sh5ul6fa6qtxzhd25829v6mf5rx2wnheat6fefps5rme2x
creation_rules:
# All Machine secrets
- path_regex: systems/[^/]+/[^/]+/[^/]+\.(yml|yaml)$
key_groups:
- age:
- *ulmo_1
- *ulmo_2

8
.sops.yml Normal file
View file

@ -0,0 +1,8 @@
keys:
- &primary age10c5hmykkduvy75yvqfnchm5lcesr5puarhkwp4l7xdwpykdm397q6xdxuy
creation_rules:
- path_regex: secrets/secrets.yml$
key_groups:
- age:
- *primary

30
_secrets/secrets.yaml Normal file
View file

@ -0,0 +1,30 @@
#ENC[AES256_GCM,data:jozDiJTPaF427kVL4MDV8VOVhft52sOS9YIfj0n8WUJmQzVoiNY=,iv:8kyaDw0l82KZfYKkfKDj0wvcIkY6zas5e8puubEr1mA=,tag:LvuVGvU195BihU8TbPN1xg==,type:comment]
example_key: ENC[AES256_GCM,data:9jefDfjJLP8Ha135Lg==,iv:9SUpjO1t65gA3LiwYN6nMj7icwInxTCQz7JsNEfQ2XA=,tag:Y8BBSLwUQem8wSXAlvnEXg==,type:str]
#ENC[AES256_GCM,data:IU1T4k/+44s8qFnjnreDMihjQRmMd5qSTtfA/ung5/1f1JmBXGP7EwYJBFF9BSBkBqBfv24A9Ok=,iv:tHzL3pW/qsNdWGT3c+ni0uTlkBMWOu/SsraymCuAkqs=,tag:nWZgWdPNiKQ0j/t9Z/5l5g==,type:comment]
#ENC[AES256_GCM,data:BhUTbsJB5voz4m1w8u1Y/MI8kR5lpRW8RpZO65IyGg232uNSoBLXB2QSl1GseyTC8bZHPiCF2gnttPD+76kqVlfzhhDu4EKU,iv:Ic8ZpR2QBBGhF2++S/TR/DRutkTghpMiby+yvNy0CSE=,tag:Z1JEtowycGDNWuznlkId8A==,type:comment]
example:
my_subdir:
my_secret: ENC[AES256_GCM,data:hccfc6uU4tGT,iv:HYjmo9kAVCcXSpDKWGku3vaJVvZHzYB3l079xXw5OEQ=,tag:c2b8BSqlL1LTcDf1nSPfVA==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age10c5hmykkduvy75yvqfnchm5lcesr5puarhkwp4l7xdwpykdm397q6xdxuy
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBpeHZXWkZ2andYSytmYWpR
ckttNVJZaWxDK2ZwME1iY2wrWFNwR0hzWUNFCjVSaWpmTHkzdHpPNjhueTQ5ZUEz
YW1BcnIwU1hsb2lodk1QcHJvTUdrVVUKLS0tIFNpWlBqb2pOWDVLV0FvU1FUODJB
dTg0QXZuSkJXV3ZRSUlKcktDNElia28KKZ62gTVpeiz1CfK7awURrPZ7zAYx9vfR
Ajxk0cw1gleE6EU2iIlLOWtmyZbcNk1X32a+otXijlH8fDGtoxA97Q==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-03-09T11:37:49Z"
mac: ENC[AES256_GCM,data:ZEqJc6slPb3YMR9kn/jFImjkQQIT3KyUK3qE3JMty+IAAr9GT8r+rHOwku4TOwL6YzON6L5vkUQFFKnOz9GiJuGkStc6AbML4SfOlRDsaFU4kwO+27UvDBYRqi6iHtJ2pu/uD4wELVhdbElxHvFlCjtgqBWaWmlXw3ATjkiZnik=,iv:zJNM/TqNfBO/mr8ZK/I/FfXwknyn9YpJ0eo4EpHSJvQ=,tag:G4FLx/Hwknq5hYEb8SWQLg==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.9.4
zitadel:
masterKey: thisWillBeAnEncryptedValueInTheFuture

567
flake.lock generated
View file

@ -5,11 +5,11 @@
"fromYaml": "fromYaml"
},
"locked": {
"lastModified": 1755819240,
"narHash": "sha256-qcMhnL7aGAuFuutH4rq9fvAhCpJWVHLcHVZLtPctPlo=",
"lastModified": 1746562888,
"narHash": "sha256-YgNJQyB5dQiwavdDFBMNKk1wyS77AtdgDk/VtU6wEaI=",
"owner": "SenchoPens",
"repo": "base16.nix",
"rev": "75ed5e5e3fce37df22e49125181fa37899c3ccd6",
"rev": "806a1777a5db2a1ef9d5d6f493ef2381047f2b89",
"type": "github"
},
"original": {
@ -21,17 +21,16 @@
"base16-fish": {
"flake": false,
"locked": {
"lastModified": 1754405784,
"narHash": "sha256-l9xHIy+85FN+bEo6yquq2IjD1rSg9fjfjpyGP1W8YXo=",
"lastModified": 1622559957,
"narHash": "sha256-PebymhVYbL8trDVVXxCvZgc0S5VxI7I1Hv4RMSquTpA=",
"owner": "tomyun",
"repo": "base16-fish",
"rev": "23ae20a0093dca0d7b39d76ba2401af0ccf9c561",
"rev": "2f6dd973a9075dabccd26f1cded09508180bf5fe",
"type": "github"
},
"original": {
"owner": "tomyun",
"repo": "base16-fish",
"rev": "23ae20a0093dca0d7b39d76ba2401af0ccf9c561",
"type": "github"
}
},
@ -68,92 +67,17 @@
"type": "github"
}
},
"clan-core": {
"inputs": {
"data-mesher": "data-mesher",
"disko": "disko",
"flake-parts": "flake-parts",
"nix-darwin": "nix-darwin",
"nix-select": "nix-select",
"nixos-facter-modules": "nixos-facter-modules",
"nixpkgs": [
"nixpkgs"
],
"sops-nix": "sops-nix",
"systems": "systems",
"treefmt-nix": "treefmt-nix"
},
"locked": {
"lastModified": 1763547157,
"narHash": "sha256-lJcMap2uT+x1R8WUUKKQ6ndynysJ/JOkrMThMGz6DP0=",
"rev": "2cb2134a6ee32d427097077c4fb4c416b52ae988",
"type": "tarball",
"url": "https://git.clan.lol/api/v1/repos/clan/clan-core/archive/2cb2134a6ee32d427097077c4fb4c416b52ae988.tar.gz"
},
"original": {
"type": "tarball",
"url": "https://git.clan.lol/clan/clan-core/archive/main.tar.gz"
}
},
"data-mesher": {
"inputs": {
"flake-parts": [
"clan-core",
"flake-parts"
],
"nixpkgs": [
"clan-core",
"nixpkgs"
],
"treefmt-nix": [
"clan-core",
"treefmt-nix"
]
},
"locked": {
"lastModified": 1762942435,
"narHash": "sha256-zIWGs5FIytTtJN+dhDb8Yx+q4TQI/yczuL539yVcyPE=",
"rev": "0ee328404b12c65e8106bde9e9fab8abf4ecada4",
"type": "tarball",
"url": "https://git.clan.lol/api/v1/repos/clan/data-mesher/archive/0ee328404b12c65e8106bde9e9fab8abf4ecada4.tar.gz"
},
"original": {
"type": "tarball",
"url": "https://git.clan.lol/clan/data-mesher/archive/main.tar.gz"
}
},
"disko": {
"inputs": {
"nixpkgs": [
"clan-core",
"nixpkgs"
]
},
"locked": {
"lastModified": 1762276996,
"narHash": "sha256-TtcPgPmp2f0FAnc+DMEw4ardEgv1SGNR3/WFGH0N19M=",
"owner": "nix-community",
"repo": "disko",
"rev": "af087d076d3860760b3323f6b583f4d828c1ac17",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "disko",
"type": "github"
}
},
"erosanix": {
"inputs": {
"flake-compat": "flake-compat",
"nixpkgs": "nixpkgs"
},
"locked": {
"lastModified": 1762360792,
"narHash": "sha256-YR7vqk+XEvFUQ/miuBAD3+p+97QUN86ya9Aw0K5feJE=",
"lastModified": 1755108317,
"narHash": "sha256-j7RGK7nyoHuJzQjVFBngpsVowIn4DAtprn66UyAFNRQ=",
"owner": "emmanuelrosa",
"repo": "erosanix",
"rev": "9075dff5685d3e7269284e53ca496da0beb24596",
"rev": "5aa322a6e586a2b46af65ab6c9a3d6042a95ff2e",
"type": "github"
},
"original": {
@ -170,11 +94,11 @@
"rust-analyzer-src": "rust-analyzer-src"
},
"locked": {
"lastModified": 1763534658,
"narHash": "sha256-i/51/Zi/1pM9hZxxSuA3nVPpyqlGoWwJwajyA/loOpo=",
"lastModified": 1755153894,
"narHash": "sha256-DEKeIg3MQy5GMFiFRUzcx1hGGBN2ypUPTo0jrMAdmH4=",
"owner": "nix-community",
"repo": "fenix",
"rev": "69e40ddf45698d0115a62a7a15d8412f35dd4c09",
"rev": "f6874c6e512bc69d881d979a45379b988b80a338",
"type": "github"
},
"original": {
@ -190,11 +114,11 @@
"nixpkgs": "nixpkgs_2"
},
"locked": {
"lastModified": 1763504432,
"narHash": "sha256-kpmPI67TdoTxiK7LsmgmkKW3iHoyvZJwZeiJhpwPfmw=",
"lastModified": 1755083788,
"narHash": "sha256-CXiS6gfw0NH+luSpNhtRZjy4NqVFrmsYpoetu3N/fMk=",
"owner": "nix-community",
"repo": "flake-firefox-nightly",
"rev": "49d5d8d42a7650e5353f8467c813839290cb7c9f",
"rev": "523078b104590da5850a61dfe291650a6b49809c",
"type": "github"
},
"original": {
@ -206,11 +130,11 @@
"firefox-gnome-theme": {
"flake": false,
"locked": {
"lastModified": 1758112371,
"narHash": "sha256-lizRM2pj6PHrR25yimjyFn04OS4wcdbc38DCdBVa2rk=",
"lastModified": 1748383148,
"narHash": "sha256-pGvD/RGuuPf/4oogsfeRaeMm6ipUIznI2QSILKjKzeA=",
"owner": "rafaelmardojai",
"repo": "firefox-gnome-theme",
"rev": "0909cfe4a2af8d358ad13b20246a350e14c2473d",
"rev": "4eb2714fbed2b80e234312611a947d6cb7d70caf",
"type": "github"
},
"original": {
@ -237,11 +161,11 @@
},
"flake-compat_2": {
"locked": {
"lastModified": 1761640442,
"narHash": "sha256-AtrEP6Jmdvrqiv4x2xa5mrtaIp3OEe8uBYCDZDS+hu8=",
"lastModified": 1746162366,
"narHash": "sha256-5SSSZ/oQkwfcAz/o/6TlejlVGqeK08wyREBQ5qFFPhM=",
"owner": "nix-community",
"repo": "flake-compat",
"rev": "4a56054d8ffc173222d09dad23adf4ba946c8884",
"rev": "0f158086a2ecdbb138cd0429410e44994f1b7e4b",
"type": "github"
},
"original": {
@ -301,16 +225,16 @@
"flake-parts": {
"inputs": {
"nixpkgs-lib": [
"clan-core",
"nvf",
"nixpkgs"
]
},
"locked": {
"lastModified": 1762980239,
"narHash": "sha256-8oNVE8TrD19ulHinjaqONf9QWCKK+w4url56cdStMpM=",
"lastModified": 1754487366,
"narHash": "sha256-pHYj8gUBapuUzKV/kN/tR3Zvqc7o6gdFB9XKXIp1SQ8=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "52a2caecc898d0b46b2b905f058ccc5081f842da",
"rev": "af66ad14b28a127c5c0f3bbb298218fc63528a18",
"type": "github"
},
"original": {
@ -320,27 +244,6 @@
}
},
"flake-parts_2": {
"inputs": {
"nixpkgs-lib": [
"nvf",
"nixpkgs"
]
},
"locked": {
"lastModified": 1760948891,
"narHash": "sha256-TmWcdiUUaWk8J4lpjzu4gCGxWY6/Ok7mOK4fIFfBuU4=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "864599284fc7c0ba6357ed89ed5e2cd5040f0c04",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"flake-parts_3": {
"inputs": {
"nixpkgs-lib": [
"stylix",
@ -348,32 +251,11 @@
]
},
"locked": {
"lastModified": 1756770412,
"narHash": "sha256-+uWLQZccFHwqpGqr2Yt5VsW/PbeJVTn9Dk6SHWhNRPw=",
"lastModified": 1751413152,
"narHash": "sha256-Tyw1RjYEsp5scoigs1384gIg6e0GoBVjms4aXFfRssQ=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "4524271976b625a4a605beefd893f270620fd751",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"flake-parts_4": {
"inputs": {
"nixpkgs-lib": [
"terranix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1736143030,
"narHash": "sha256-+hu54pAoLDEZT9pjHlqL9DNzWz0NbUn8NEAHP7PQPzU=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "b905f6fc23a9051a6e1b741e1438dbfc0634c6de",
"rev": "77826244401ea9de6e3bac47c2db46005e1f30b5",
"type": "github"
},
"original": {
@ -384,7 +266,7 @@
},
"flake-utils": {
"inputs": {
"systems": "systems_2"
"systems": "systems"
},
"locked": {
"lastModified": 1731533236,
@ -421,7 +303,7 @@
},
"flake-utils_2": {
"inputs": {
"systems": "systems_3"
"systems": "systems_2"
},
"locked": {
"lastModified": 1731533236,
@ -439,7 +321,7 @@
},
"flake-utils_3": {
"inputs": {
"systems": "systems_4"
"systems": "systems_3"
},
"locked": {
"lastModified": 1731533236,
@ -457,7 +339,7 @@
},
"flake-utils_4": {
"inputs": {
"systems": "systems_6"
"systems": "systems_5"
},
"locked": {
"lastModified": 1694529238,
@ -510,20 +392,18 @@
"gnome-shell": {
"flake": false,
"locked": {
"host": "gitlab.gnome.org",
"lastModified": 1762869044,
"narHash": "sha256-nwm/GJ2Syigf7VccLAZ66mFC8mZJFqpJmIxSGKl7+Ds=",
"lastModified": 1748186689,
"narHash": "sha256-UaD7Y9f8iuLBMGHXeJlRu6U1Ggw5B9JnkFs3enZlap0=",
"owner": "GNOME",
"repo": "gnome-shell",
"rev": "680e3d195a92203f28d4bf8c6e8bb537cc3ed4ad",
"type": "gitlab"
"rev": "8c88f917db0f1f0d80fa55206c863d3746fa18d0",
"type": "github"
},
"original": {
"host": "gitlab.gnome.org",
"owner": "GNOME",
"ref": "gnome-49",
"ref": "48.2",
"repo": "gnome-shell",
"type": "gitlab"
"type": "github"
}
},
"grub2-themes": {
@ -531,11 +411,11 @@
"nixpkgs": "nixpkgs_4"
},
"locked": {
"lastModified": 1757136219,
"narHash": "sha256-tKU+vq34KHu/A2wD7WdgP5A4/RCmSD8hB0TyQAUlixA=",
"lastModified": 1755072091,
"narHash": "sha256-FCkbELHIFXlVREaopW13QFMzwLPr/otjucmyNLQQXeg=",
"owner": "vinceliuice",
"repo": "grub2-themes",
"rev": "80dd04ddf3ba7b284a7b1a5df2b1e95ee2aad606",
"rev": "03d8c9cf0d1bcf67765ac5fa35263f1b08c584fa",
"type": "github"
},
"original": {
@ -549,15 +429,14 @@
"flake-utils": "flake-utils_2",
"nixpkgs": [
"nixpkgs"
],
"rust-overlay": "rust-overlay"
]
},
"locked": {
"lastModified": 1763486183,
"narHash": "sha256-10EvBTF9ELezWg+KoKZJ3bxrPzT1Xz95ifurC6HixLY=",
"lastModified": 1754593854,
"narHash": "sha256-fiWzQKZP92+2nm9wGBa/UYuEdVJkshHqNpCFfklas8k=",
"owner": "himmelblau-idm",
"repo": "himmelblau",
"rev": "fb27f4bee812e4b4df9df9f78bd5280f0aa2193c",
"rev": "e0b9a3efdcf0c6c59ed3352ffb2b003ab6aa2fed",
"type": "github"
},
"original": {
@ -573,32 +452,11 @@
]
},
"locked": {
"lastModified": 1763416652,
"narHash": "sha256-8EBEEvtzQ11LCxpQHMNEBQAGtQiCu/pqP9zSovDSbNM=",
"lastModified": 1755121891,
"narHash": "sha256-UtYkukiGnPRJ5rpd4W/wFVrLMh8fqtNkqHTPgHEtrqU=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "ea164b7c9ccdc2321379c2ff78fd4317b4c41312",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "home-manager",
"type": "github"
}
},
"home-manager_2": {
"inputs": {
"nixpkgs": [
"zen-browser",
"nixpkgs"
]
},
"locked": {
"lastModified": 1762964643,
"narHash": "sha256-RYHN8O/Aja59XDji6WSJZPkJpYVUfpSkyH+PEupBJqM=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "827f2a23373a774a8805f84ca5344654c31f354b",
"rev": "279ca5addcdcfa31ac852b3ecb39fc372684f426",
"type": "github"
},
"original": {
@ -615,11 +473,11 @@
]
},
"locked": {
"lastModified": 1763453666,
"narHash": "sha256-Hu8lDUlbMFvcYX30LBXX7Gq5FbU35bERH0pSX5qHf/Q=",
"lastModified": 1755151620,
"narHash": "sha256-fVMalQZ+tRXR8oue2SdWu4CdlsS2NII+++rI40XQ8rU=",
"owner": "Jovian-Experiments",
"repo": "Jovian-NixOS",
"rev": "b843b551415c7aecc97c8b3ab3fff26fd0cd8bbf",
"rev": "16e12d22754d97064867006acae6e16da7a142a6",
"type": "github"
},
"original": {
@ -649,11 +507,11 @@
},
"mnw": {
"locked": {
"lastModified": 1758834834,
"narHash": "sha256-Y7IvY4F8vajZyp3WGf+KaiIVwondEkMFkt92Cr9NZmg=",
"lastModified": 1748710831,
"narHash": "sha256-eZu2yH3Y2eA9DD3naKWy/sTxYS5rPK2hO7vj8tvUCSU=",
"owner": "Gerg-L",
"repo": "mnw",
"rev": "cfbc7d1cc832e318d0863a5fc91d940a96034001",
"rev": "cff958a4e050f8d917a6ff3a5624bc4681c6187d",
"type": "github"
},
"original": {
@ -662,27 +520,6 @@
"type": "github"
}
},
"nix-darwin": {
"inputs": {
"nixpkgs": [
"clan-core",
"nixpkgs"
]
},
"locked": {
"lastModified": 1763136804,
"narHash": "sha256-6p2ljK42s0S8zS0UU59EsEqupz0GVCaBYRylpUadeBM=",
"owner": "nix-darwin",
"repo": "nix-darwin",
"rev": "973db96394513fd90270ea5a1211a82a4a0ba47f",
"type": "github"
},
"original": {
"owner": "nix-darwin",
"repo": "nix-darwin",
"type": "github"
}
},
"nix-github-actions": {
"inputs": {
"nixpkgs": [
@ -712,11 +549,11 @@
"nixpkgs": "nixpkgs_5"
},
"locked": {
"lastModified": 1763171892,
"narHash": "sha256-6cg9zSiqKA89yJzVtYhBaBptqq6bX4pr4g7WLAHOD4Y=",
"lastModified": 1755137329,
"narHash": "sha256-9MxuOLH7jk58IVUUDWwLeqk9U4ATE6X37955Ld+4/zw=",
"owner": "Infinidoge",
"repo": "nix-minecraft",
"rev": "316858c27d278b20e776cd4dd8f787812f587ba2",
"rev": "d9330bc35048238597880e89fb173799de9db5e9",
"type": "github"
},
"original": {
@ -725,19 +562,6 @@
"type": "github"
}
},
"nix-select": {
"locked": {
"lastModified": 1763303120,
"narHash": "sha256-yxcNOha7Cfv2nhVpz9ZXSNKk0R7wt4AiBklJ8D24rVg=",
"rev": "3d1e3860bef36857a01a2ddecba7cdb0a14c35a9",
"type": "tarball",
"url": "https://git.clan.lol/api/v1/repos/clan/nix-select/archive/3d1e3860bef36857a01a2ddecba7cdb0a14c35a9.tar.gz"
},
"original": {
"type": "tarball",
"url": "https://git.clan.lol/clan/nix-select/archive/main.tar.gz"
}
},
"nixlib": {
"locked": {
"lastModified": 1736643958,
@ -768,21 +592,6 @@
"type": "github"
}
},
"nixos-facter-modules": {
"locked": {
"lastModified": 1762264948,
"narHash": "sha256-iaRf6n0KPl9hndnIft3blm1YTAyxSREV1oX0MFZ6Tk4=",
"owner": "nix-community",
"repo": "nixos-facter-modules",
"rev": "fa695bff9ec37fd5bbd7ee3181dbeb5f97f53c96",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nixos-facter-modules",
"type": "github"
}
},
"nixos-generators": {
"inputs": {
"nixlib": "nixlib",
@ -812,11 +621,11 @@
]
},
"locked": {
"lastModified": 1763537456,
"narHash": "sha256-/WRqcqeE9C+mxxWgI7jy5blMrvg2lHFSlTFjC8pRWos=",
"lastModified": 1755171343,
"narHash": "sha256-h6bbfhqWcHlx9tcyYa7dhaEiNpusLCcFYkJ/AnltLW8=",
"owner": "nix-community",
"repo": "nixos-wsl",
"rev": "cd9eb5225fc91eb67629966844d2ff371824abb1",
"rev": "e37cfef071466a9ca649f6899aff05226ce17e9e",
"type": "github"
},
"original": {
@ -827,11 +636,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1761828793,
"narHash": "sha256-xjdPwMD4wVuDD85U+3KST62VzFkJueI6oBwIzpzUHLY=",
"lastModified": 1754002724,
"narHash": "sha256-1NBby4k2UU9FR7a9ioXtCOpv8jYO0tZAGarMsxN8sz8=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "843859a08e114403f44aaf5b996b44c38094aa46",
"rev": "8271ed4b2e366339dd622f329151e45745ade121",
"type": "github"
},
"original": {
@ -856,13 +665,29 @@
"type": "github"
}
},
"nixpkgs_2": {
"nixpkgs_10": {
"locked": {
"lastModified": 1763469780,
"narHash": "sha256-IW67Db/wBNQwJ5e0fF9Yk4SmdivMcecrUVDs7QJoC/s=",
"lastModified": 1727348695,
"narHash": "sha256-J+PeFKSDV+pHL7ukkfpVzCOO7mBSrrpJ3svwBFABbhI=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "a70b03ca5dc9d46294740f165abdef9f9bea5632",
"rev": "1925c603f17fc89f4c8f6bf6f631a802ad85d784",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1755061300,
"narHash": "sha256-eov82CkCrpiECJa3dyQ2da1sPGnAP3HK0UEra5eupaM=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "d4df8d6cc1ccfd3e4349a1d54e4fb1171e7ec1f5",
"type": "github"
},
"original": {
@ -890,11 +715,11 @@
},
"nixpkgs_4": {
"locked": {
"lastModified": 1763547551,
"narHash": "sha256-YOdXVAqEGmrPUgs71r8ziuu9qqpn3jJEiIxsIls+VQA=",
"lastModified": 1755178357,
"narHash": "sha256-rzgUmlO5/pt7uPAlY6E70clNjg9JmrgBxalEj2zKq08=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "06aa4d5f488875b6af46e10b45b8000ed0906860",
"rev": "6eac4364f979ef460fb6ebd17ca65b8dae03cba4",
"type": "github"
},
"original": {
@ -922,11 +747,11 @@
},
"nixpkgs_6": {
"locked": {
"lastModified": 1763421233,
"narHash": "sha256-Stk9ZYRkGrnnpyJ4eqt9eQtdFWRRIvMxpNRf4sIegnw=",
"lastModified": 1755027561,
"narHash": "sha256-IVft239Bc8p8Dtvf7UAACMG5P3ZV+3/aO28gXpGtMXI=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "89c2b2330e733d6cdb5eae7b899326930c2c0648",
"rev": "005433b926e16227259a1843015b5b2b7f7d1fc3",
"type": "github"
},
"original": {
@ -938,11 +763,11 @@
},
"nixpkgs_7": {
"locked": {
"lastModified": 1761880412,
"narHash": "sha256-QoJjGd4NstnyOG4mm4KXF+weBzA2AH/7gn1Pmpfcb0A=",
"lastModified": 1755049066,
"narHash": "sha256-ANrc15FSoOAdNbfKHxqEJjZLftIwIsenJGRb/04K41s=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "a7fc11be66bdfb5cdde611ee5ce381c183da8386",
"rev": "e45f8f193029378d0aaee5431ba098dc80054e9a",
"type": "github"
},
"original": {
@ -954,11 +779,11 @@
},
"nixpkgs_8": {
"locked": {
"lastModified": 1763191728,
"narHash": "sha256-esRhOS0APE6k40Hs/jjReXg+rx+J5LkWw7cuWFKlwYA=",
"lastModified": 1744868846,
"narHash": "sha256-5RJTdUHDmj12Qsv7XOhuospjAjATNiTMElplWnJE9Hs=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "1d4c88323ac36805d09657d13a5273aea1b34f0c",
"rev": "ebe4301cbd8f81c4f8d3244b3632338bbeb6d49c",
"type": "github"
},
"original": {
@ -970,11 +795,11 @@
},
"nixpkgs_9": {
"locked": {
"lastModified": 1762977756,
"narHash": "sha256-4PqRErxfe+2toFJFgcRKZ0UI9NSIOJa+7RXVtBhy4KE=",
"lastModified": 1751792365,
"narHash": "sha256-J1kI6oAj25IG4EdVlg2hQz8NZTBNYvIS0l4wpr9KcUo=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "c5ae371f1a6a7fd27823bc500d9390b38c05fa55",
"rev": "1fd8bada0b6117e6c7eb54aad5813023eed37ccb",
"type": "github"
},
"original": {
@ -996,11 +821,11 @@
]
},
"locked": {
"lastModified": 1758998580,
"narHash": "sha256-VLx0z396gDCGSiowLMFz5XRO/XuNV+4EnDYjdJhHvUk=",
"lastModified": 1751906969,
"narHash": "sha256-BSQAOdPnzdpOuCdAGSJmefSDlqmStFNScEnrWzSqKPw=",
"owner": "nix-community",
"repo": "NUR",
"rev": "ba8d9c98f5f4630bcb0e815ab456afd90c930728",
"rev": "ddb679f4131e819efe3bbc6457ba19d7ad116f25",
"type": "github"
},
"original": {
@ -1012,17 +837,17 @@
"nvf": {
"inputs": {
"flake-compat": "flake-compat_4",
"flake-parts": "flake-parts_2",
"flake-parts": "flake-parts",
"mnw": "mnw",
"nixpkgs": "nixpkgs_7",
"systems": "systems_5"
"systems": "systems_4"
},
"locked": {
"lastModified": 1762622004,
"narHash": "sha256-NpzzgaoMK8aRHnndHWbYNKLcZN0r1y6icCoJvGoBsoE=",
"lastModified": 1755115677,
"narHash": "sha256-98Ad2F5w1xW94KymQiBohNBYpFqMa0K28v9S1SzyTY8=",
"owner": "notashelf",
"repo": "nvf",
"rev": "09470524a214ed26633ddc2b6ec0c9bf31a8b909",
"rev": "c5dc7192496a1fad38134e54f8b4fca8ac51a9fe",
"type": "github"
},
"original": {
@ -1041,11 +866,11 @@
]
},
"locked": {
"lastModified": 1762784320,
"narHash": "sha256-odsk96Erywk5hs0dhArF38zb7Oe0q6LZ70gXbxAPKno=",
"lastModified": 1754501628,
"narHash": "sha256-FExJ54tVB5iu7Dh2tLcyCSWpaV+lmUzzWKZUkemwXvo=",
"owner": "nix-community",
"repo": "plasma-manager",
"rev": "7911a0f8a44c7e8b29d031be3149ee8943144321",
"rev": "cca090f8115c4172b9aef6c5299ae784bdd5e133",
"type": "github"
},
"original": {
@ -1056,7 +881,6 @@
},
"root": {
"inputs": {
"clan-core": "clan-core",
"erosanix": "erosanix",
"fenix": "fenix",
"firefox": "firefox",
@ -1073,20 +897,19 @@
"nvf": "nvf",
"plasma-manager": "plasma-manager",
"snowfall-lib": "snowfall-lib",
"sops-nix": "sops-nix_2",
"sops-nix": "sops-nix",
"stylix": "stylix",
"terranix": "terranix",
"zen-browser": "zen-browser"
}
},
"rust-analyzer-src": {
"flake": false,
"locked": {
"lastModified": 1762860488,
"narHash": "sha256-rMfWMCOo/pPefM2We0iMBLi2kLBAnYoB9thi4qS7uk4=",
"lastModified": 1755004716,
"narHash": "sha256-TbhPR5Fqw5LjAeI3/FOPhNNFQCF3cieKCJWWupeZmiA=",
"owner": "rust-lang",
"repo": "rust-analyzer",
"rev": "2efc80078029894eec0699f62ec8d5c1a56af763",
"rev": "b2a58b8c6eff3c3a2c8b5c70dbf69ead78284194",
"type": "github"
},
"original": {
@ -1096,27 +919,6 @@
"type": "github"
}
},
"rust-overlay": {
"inputs": {
"nixpkgs": [
"himmelblau",
"nixpkgs"
]
},
"locked": {
"lastModified": 1759977258,
"narHash": "sha256-hOxEFSEBoqDmJb7BGX1CzT1gvUPK6r+Qs+n3IxBgfTs=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "1d0c6173f57d07db7957b50e799240d4f2d7520f",
"type": "github"
},
"original": {
"owner": "oxalica",
"repo": "rust-overlay",
"type": "github"
}
},
"snowfall-lib": {
"inputs": {
"flake-compat": "flake-compat_5",
@ -1140,36 +942,15 @@
}
},
"sops-nix": {
"inputs": {
"nixpkgs": [
"clan-core",
"nixpkgs"
]
},
"locked": {
"lastModified": 1763264763,
"narHash": "sha256-N0BEoJIlJ+M6sWZJ8nnfAjGY9VLvM6MXMitRenmhBkY=",
"owner": "Mic92",
"repo": "sops-nix",
"rev": "882e56c8293e44d57d882b800a82f8b2ee7a858f",
"type": "github"
},
"original": {
"owner": "Mic92",
"repo": "sops-nix",
"type": "github"
}
},
"sops-nix_2": {
"inputs": {
"nixpkgs": "nixpkgs_8"
},
"locked": {
"lastModified": 1763509310,
"narHash": "sha256-s2WzTAD3vJtPACBCZXezNUMTG/wC6SFsU9DxazB9wDI=",
"lastModified": 1754988908,
"narHash": "sha256-t+voe2961vCgrzPFtZxha0/kmFSHFobzF00sT8p9h0U=",
"owner": "Mic92",
"repo": "sops-nix",
"rev": "3ee33c0ed7c5aa61b4e10484d2ebdbdc98afb03e",
"rev": "3223c7a92724b5d804e9988c6b447a0d09017d48",
"type": "github"
},
"original": {
@ -1185,11 +966,11 @@
"base16-helix": "base16-helix",
"base16-vim": "base16-vim",
"firefox-gnome-theme": "firefox-gnome-theme",
"flake-parts": "flake-parts_3",
"flake-parts": "flake-parts_2",
"gnome-shell": "gnome-shell",
"nixpkgs": "nixpkgs_9",
"nur": "nur",
"systems": "systems_7",
"systems": "systems_6",
"tinted-foot": "tinted-foot",
"tinted-kitty": "tinted-kitty",
"tinted-schemes": "tinted-schemes",
@ -1197,11 +978,11 @@
"tinted-zed": "tinted-zed"
},
"locked": {
"lastModified": 1763497248,
"narHash": "sha256-OGP6MYc+lVkLVQOTS6ORszDcCnZm7kDOGpFBdDoLd0k=",
"lastModified": 1755027820,
"narHash": "sha256-hBSU7BEhd05y/pC9tliYjkFp8AblkbNEkPei229+0Pg=",
"owner": "nix-community",
"repo": "stylix",
"rev": "f19ac46f6aa26188b2020ed40066a5b832be9c53",
"rev": "c592717e9f713bbae5f718c784013d541346363d",
"type": "github"
},
"original": {
@ -1300,58 +1081,6 @@
"type": "github"
}
},
"systems_7": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_8": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"terranix": {
"inputs": {
"flake-parts": "flake-parts_4",
"nixpkgs": [
"nixpkgs"
],
"systems": "systems_8"
},
"locked": {
"lastModified": 1762472226,
"narHash": "sha256-iVS4sxVgGn+T74rGJjEJbzx+kjsuaP3wdQVXBNJ79A0=",
"owner": "terranix",
"repo": "terranix",
"rev": "3b5947a48da5694094b301a3b1ef7b22ec8b19fc",
"type": "github"
},
"original": {
"owner": "terranix",
"repo": "terranix",
"type": "github"
}
},
"tinted-foot": {
"flake": false,
"locked": {
@ -1388,11 +1117,11 @@
"tinted-schemes": {
"flake": false,
"locked": {
"lastModified": 1757716333,
"narHash": "sha256-d4km8W7w2zCUEmPAPUoLk1NlYrGODuVa3P7St+UrqkM=",
"lastModified": 1750770351,
"narHash": "sha256-LI+BnRoFNRa2ffbe3dcuIRYAUcGklBx0+EcFxlHj0SY=",
"owner": "tinted-theming",
"repo": "schemes",
"rev": "317a5e10c35825a6c905d912e480dfe8e71c7559",
"rev": "5a775c6ffd6e6125947b393872cde95867d85a2a",
"type": "github"
},
"original": {
@ -1404,11 +1133,11 @@
"tinted-tmux": {
"flake": false,
"locked": {
"lastModified": 1757811970,
"narHash": "sha256-n5ZJgmzGZXOD9pZdAl1OnBu3PIqD+X3vEBUGbTi4JiI=",
"lastModified": 1751159871,
"narHash": "sha256-UOHBN1fgHIEzvPmdNMHaDvdRMgLmEJh2hNmDrp3d3LE=",
"owner": "tinted-theming",
"repo": "tinted-tmux",
"rev": "d217ba31c846006e9e0ae70775b0ee0f00aa6b1e",
"rev": "bded5e24407cec9d01bd47a317d15b9223a1546c",
"type": "github"
},
"original": {
@ -1420,11 +1149,11 @@
"tinted-zed": {
"flake": false,
"locked": {
"lastModified": 1757811247,
"narHash": "sha256-4EFOUyLj85NRL3OacHoLGEo0wjiRJzfsXtR4CZWAn6w=",
"lastModified": 1751158968,
"narHash": "sha256-ksOyv7D3SRRtebpXxgpG4TK8gZSKFc4TIZpR+C98jX8=",
"owner": "tinted-theming",
"repo": "base16-zed",
"rev": "824fe0aacf82b3c26690d14e8d2cedd56e18404e",
"rev": "86a470d94204f7652b906ab0d378e4231a5b3384",
"type": "github"
},
"original": {
@ -1433,44 +1162,20 @@
"type": "github"
}
},
"treefmt-nix": {
"inputs": {
"nixpkgs": [
"clan-core",
"nixpkgs"
]
},
"locked": {
"lastModified": 1762938485,
"narHash": "sha256-AlEObg0syDl+Spi4LsZIBrjw+snSVU4T8MOeuZJUJjM=",
"owner": "numtide",
"repo": "treefmt-nix",
"rev": "5b4ee75aeefd1e2d5a1cc43cf6ba65eba75e83e4",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "treefmt-nix",
"type": "github"
}
},
"zen-browser": {
"inputs": {
"home-manager": "home-manager_2",
"nixpkgs": [
"nixpkgs"
]
"nixpkgs": "nixpkgs_10"
},
"locked": {
"lastModified": 1763521945,
"narHash": "sha256-Zcrafbe4niRJMbzaVOwg7+iedJhwBFttre2DpyCC6qA=",
"owner": "0xc000022070",
"lastModified": 1727721329,
"narHash": "sha256-QYlWZwUSwrM7BuO+dXclZIwoPvBIuJr6GpFKv9XKFPI=",
"owner": "MarceColl",
"repo": "zen-browser-flake",
"rev": "24d7381b9231c23daceec5d372cc28e877f7785d",
"rev": "e6ab73f405e9a2896cce5956c549a9cc359e5fcc",
"type": "github"
},
"original": {
"owner": "0xc000022070",
"owner": "MarceColl",
"repo": "zen-browser-flake",
"type": "github"
}

View file

@ -41,10 +41,7 @@
inputs.nixpkgs.follows = "nixpkgs";
};
zen-browser = {
url = "github:0xc000022070/zen-browser-flake";
inputs.nixpkgs.follows = "nixpkgs";
};
zen-browser.url = "github:MarceColl/zen-browser-flake";
nix-minecraft.url = "github:Infinidoge/nix-minecraft";
@ -78,16 +75,6 @@
flake-compat.follows = "";
};
};
terranix = {
url = "github:terranix/terranix";
inputs.nixpkgs.follows = "nixpkgs";
};
clan-core = {
url = "https://git.clan.lol/clan/clan-core/archive/main.tar.gz";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = inputs: inputs.snowfall-lib.mkFlake {
@ -106,15 +93,8 @@
channels-config = {
allowUnfree = true;
permittedInsecurePackages = [
# Due to *arr stack
"dotnet-sdk-6.0.428"
"aspnetcore-runtime-6.0.36"
# I think this is because of zen
"qtwebengine-5.15.19"
# For Nheko, the matrix client
"olm-3.2.16"
];
};
@ -124,13 +104,9 @@
flux.overlays.default
];
systems.modules = with inputs; [
clan-core.nixosModules.default
];
homes.modules = with inputs; [
stylix.homeModules.stylix
plasma-manager.homeModules.plasma-manager
plasma-manager.homeManagerModules.plasma-manager
];
};
}

View file

@ -35,7 +35,6 @@
bitwarden.enable = true;
discord.enable = true;
ladybird.enable = true;
matrix.enable = true;
obs.enable = true;
onlyoffice.enable = true;
signal.enable = true;

View file

@ -1,38 +0,0 @@
{ lib, ...}:
let
inherit (builtins) isString typeOf;
inherit (lib) mkOption types throwIfNot concatStringsSep splitStringBy toLower map;
in
{
options = {
mkUrlOptions =
defaults:
{
host = mkOption {
type = types.str;
example = "host.tld";
description = ''
Hostname
'';
} // (defaults.host or {});
port = mkOption {
type = types.port;
default = 1234;
example = "1234";
description = ''
Port
'';
} // (defaults.port or {});
protocol = mkOption {
type = types.str;
default = "https";
example = "https";
description = ''
Which protocol to use when creating a url string
'';
} // (defaults.protocol or {});
};
};
}

View file

@ -1,39 +0,0 @@
{ lib, ...}:
let
inherit (builtins) isString typeOf match toString head;
inherit (lib) throwIfNot concatStringsSep splitStringBy toLower map concatMapAttrsStringSep;
in
{
strings = {
#========================================================================================
# Converts a string to snake case
#
# simply replaces any uppercase letter to its lowercase variant preceeded by an underscore
#========================================================================================
toSnakeCase =
str:
throwIfNot (isString str) "toSnakeCase only accepts string values, but got ${typeOf str}" (
str
|> splitStringBy (prev: curr: builtins.match "[a-z]" prev != null && builtins.match "[A-Z]" curr != null) true
|> map (p: toLower p)
|> concatStringsSep "_"
);
#========================================================================================
# Converts a set of url parts to a string
#========================================================================================
toUrl =
{ protocol ? null, host, port ? null, path ? null, query ? null, hash ? null }:
let
trim_slashes = str: str |> match "^\/*(.+?)\/*$" |> head;
encode_to_str = set: concatMapAttrsStringSep "&" (n: v: "${n}=${v}") set;
_protocol = if protocol != null then "${protocol}://" else "";
_port = if port != null then ":${toString port}" else "";
_path = if path != null then "/${path |> trim_slashes}" else "";
_query = if query != null then "?${query |> encode_to_str}" else "";
_hash = if hash != null then "#${hash |> encode_to_str}" else "";
in
"${_protocol}${host}${_port}${_path}${_query}${_hash}";
};
}

View file

@ -1,19 +0,0 @@
{ config, lib, pkgs, namespace, osConfig ? {}, ... }:
let
inherit (lib) mkIf mkEnableOption;
cfg = config.${namespace}.application.matrix;
in
{
options.${namespace}.application.matrix = {
enable = mkEnableOption "enable Matrix client (Fractal)";
};
config = mkIf cfg.enable {
home.packages = with pkgs; [ fractal element-desktop ];
programs.element-desktop = {
enable = true;
};
};
}

View file

@ -5,61 +5,35 @@ let
cfg = config.${namespace}.application.zen;
in
{
imports = [
inputs.zen-browser.homeModules.default
];
options.${namespace}.application.zen = {
enable = mkEnableOption "enable zen";
};
config = mkIf cfg.enable {
home.packages = [ inputs.zen-browser.packages.${pkgs.system}.specific ];
home.sessionVariables = {
MOZ_ENABLE_WAYLAND = "1";
};
programs.zen-browser = {
enable = true;
policies = {
AutofillAddressEnabled = true;
AutofillCreditCardEnabled = false;
AppAutoUpdate = false;
DisableAppUpdate = true;
ManualAppUpdateOnly = true;
DisableFeedbackCommands = true;
DisableFirefoxStudies = true;
DisablePocket = true;
DisableTelemetry = true;
DontCheckDefaultBrowser = false;
# DontCheckDefaultBrowser = false;
NoDefaultBookmarks = true;
OfferToSaveLogins = false;
# OfferToSaveLogins = false;
EnableTrackingProtection = {
Value = true;
Locked = true;
Cryptomining = true;
Fingerprinting = true;
};
HttpAllowlist = [
"http://ulmo"
];
};
policies.ExtensionSettings = let
mkExtension = id: {
install_url = "https://addons.mozilla.org/firefox/downloads/latest/${builtins.toString id}/latest.xpi";
installation_mode = "force_installed";
};
in
{
ublock_origin = 4531307;
ghostry = 4562168;
bitwarden = 4562769;
sponsorblock = 4541835;
};
};
};

View file

@ -64,7 +64,7 @@ in
};
kwalletrc = {
Wallet.Enabled = true;
Wallet.Enabled = false;
};
plasmarc = {

View file

@ -15,7 +15,7 @@ in {
programs.zed-editor = {
enable = true;
extensions = [ "nix" "toml" "html" "just-ls" ];
extensions = [ "nix" "toml" "html" ];
userSettings = {
assistant.enabled = false;

View file

@ -4,9 +4,7 @@ let
in
{
systemd.user.startServices = "sd-switch";
programs.home-manager = {
enable = true;
};
programs.home-manager.enable = true;
home.stateVersion = mkDefault (osConfig.system.stateVersion or "25.05");
}

View file

@ -17,7 +17,6 @@ in
eza.enable = true;
fzf.enable = true;
git.enable = true;
just.enable = true;
starship.enable = true;
tmux.enable = true;
yazi.enable = true;

View file

@ -31,11 +31,9 @@ in
package = pkgs.gitFull;
difftastic = {
enable = true;
options = {
background = "dark";
color = "always";
display = "inline";
};
background = "dark";
color = "always";
display = "inline";
};
ignores = [

View file

@ -1,15 +0,0 @@
{ config, lib, pkgs, namespace, ... }:
let
inherit (lib) mkEnableOption mkIf;
cfg = config.${namespace}.shell.toolset.just;
in
{
options.${namespace}.shell.toolset.just = {
enable = mkEnableOption "version-control system";
};
config = mkIf cfg.enable {
home.packages = with pkgs; [ just gum ];
};
}

View file

@ -31,9 +31,7 @@ in {
base16Scheme = "${pkgs.base16-schemes}/share/themes/${cfg.theme}.yaml";
image = ./${cfg.theme}.jpg;
polarity = cfg.polarity;
# targets.qt.platform = mkDefault "kde";
targets.zen-browser.profileNames = [ "Chris" ];
targets.qt.platform = mkDefault "kde6";
fonts = {
serif = {
@ -52,7 +50,7 @@ in {
};
emoji = {
package = pkgs.noto-fonts-color-emoji;
package = pkgs.noto-fonts-emoji;
name = "Noto Color Emoji";
};
};

View file

@ -12,18 +12,7 @@ in
};
config = mkIf cfg.enable {
environment.plasma6.excludePackages = with pkgs.kdePackages; [
elisa
kmahjongg
kmines
konversation
kpat
ksudoku
konsole
kate
ghostwriter
oxygen
];
environment.plasma6.excludePackages = with pkgs.kdePackages; [ konsole kate ghostwriter oxygen ];
environment.sessionVariables.NIXOS_OZONE_WL = "1";
services = {

View file

@ -17,6 +17,11 @@ in
};
amdgpu = {
amdvlk = {
enable = true;
support32Bit.enable = true;
};
initrd.enable = true;
};
};

View file

@ -1,6 +0,0 @@
{ ... }:
{
config = {
home-manager.backupFileExtension = "homeManagerBackup";
};
}

View file

@ -1,20 +1,24 @@
{ pkgs, lib, namespace, config, ... }:
let
inherit (lib) mkIf mkEnableOption;
cfg = config.${namespace}.nix;
in
{
options.${namespace}.nix = {};
options.${namespace}.nix = {
enable = mkEnableOption "Enable nix command";
};
config = {
config = mkIf cfg.enable {
programs.git.enable = true;
nix = {
package = pkgs.nixVersions.latest;
extraOptions = "experimental-features = nix-command flakes pipe-operators";
extraOptions = "experimental-features = nix-command flakes";
settings = {
experimental-features = [ "nix-command" "flakes" "pipe-operators" ];
experimental-features = [ "nix-command" "flakes" ];
allowed-users = [ "@wheel" ];
trusted-users = [ "@wheel" ];

View file

@ -1,595 +1,33 @@
{ config, lib, pkgs, namespace, system, inputs, ... }:
{ config, lib, pkgs, namespace, ... }:
let
inherit (lib) mkIf mkEnableOption mkOption types toUpper toSentenceCase nameValuePair mapAttrs mapAttrs' concatMapAttrs concatMapStringsSep filterAttrsRecursive listToAttrs imap0 head drop length literalExpression attrNames;
inherit (lib.${namespace}.strings) toSnakeCase;
inherit (lib) mkIf mkEnableOption mkForce;
cfg = config.${namespace}.services.authentication.zitadel;
database = "zitadel";
db_name = "zitadel";
db_user = "zitadel";
in
{
options.${namespace}.services.authentication.zitadel = {
enable = mkEnableOption "Zitadel";
organization = mkOption {
type = types.attrsOf (types.submodule ({ name, ... }: {
options =
let
org = name;
in
{
isDefault = mkOption {
type = types.bool;
default = false;
example = "true";
description = ''
True sets the org as default org for the instance. Only one org can be default org.
Nothing happens if you set it to false until you set another org as default org.
'';
};
project = mkOption {
default = {};
type = types.attrsOf (types.submodule {
options = {
hasProjectCheck = mkOption {
type = types.bool;
default = false;
example = "true";
description = ''
ZITADEL checks if the org of the user has permission to this project.
'';
};
privateLabelingSetting = mkOption {
type = types.nullOr (types.enum [ "unspecified" "enforceProjectResourceOwnerPolicy" "allowLoginUserResourceOwnerPolicy" ]);
default = null;
example = "enforceProjectResourceOwnerPolicy";
description = ''
Defines from where the private labeling should be triggered,
supported values:
- unspecified
- enforceProjectResourceOwnerPolicy
- allowLoginUserResourceOwnerPolicy
'';
};
projectRoleAssertion = mkOption {
type = types.bool;
default = false;
example = "true";
description = ''
Describes if roles of user should be added in token.
'';
};
projectRoleCheck = mkOption {
type = types.bool;
default = false;
example = "true";
description = ''
ZITADEL checks if the user has at least one on this project.
'';
};
role = mkOption {
default = {};
type = types.attrsOf (types.submodule ({ name, ... }: {
options =
let
roleName = name;
in
{
displayName = mkOption {
type = types.str;
default = toSentenceCase name;
example = "RoleName";
description = ''
Name used for project role.
'';
};
group = mkOption {
type = types.nullOr types.str;
default = null;
example = "some_group";
description = ''
Group used for project role.
'';
};
};
}));
};
assign = mkOption {
default = {};
type = types.attrsOf (types.listOf types.str);
};
application = mkOption {
default = {};
type = types.attrsOf (types.submodule {
options = {
redirectUris = mkOption {
type = types.nonEmptyListOf types.str;
example = ''
[ "https://example.com/redirect/url" ]
'';
description = ''
.
'';
};
grantTypes = mkOption {
type = types.nonEmptyListOf (types.enum [ "authorizationCode" "implicit" "refreshToken" "deviceCode" "tokenExchange" ]);
example = ''
[ "authorizationCode" ]
'';
description = ''
.
'';
};
responseTypes = mkOption {
type = types.nonEmptyListOf (types.enum [ "code" "idToken" "idTokenToken" ]);
example = ''
[ "code" ]
'';
description = ''
.
'';
};
exportMap =
let
strOpt = mkOption { type = types.nullOr types.str; default = null; };
in
mkOption {
type = types.submodule { options = { client_id = strOpt; client_secret = strOpt; }; };
default = {};
example = literalExpression ''
{
client_id = "SSO_CLIENT_ID";
client_secret = "SSO_CLIENT_SECRET";
}
'';
description = ''
Remap the outputted variables to another key.
'';
};
};
});
};
};
});
};
user = mkOption {
default = {};
type = types.attrsOf (types.submodule ({ name, ... }: {
options =
let
username = name;
in
{
email = mkOption {
type = types.str;
example = "someone@some.domain";
description = ''
Username.
'';
};
userName = mkOption {
type = types.nullOr types.str;
default = username;
example = "some_user_name";
description = ''
Username. Default value is the key of the config object you created, you can overwrite that by setting this option
'';
};
firstName = mkOption {
type = types.str;
example = "John";
description = ''
First name of the user.
'';
};
lastName = mkOption {
type = types.str;
example = "Doe";
description = ''
Last name of the user.
'';
};
roles = mkOption {
type = types.listOf types.str;
default = [];
example = "[ \"ORG_OWNER\" ]";
description = ''
List of roles granted to organisation.
'';
};
instanceRoles = mkOption {
type = types.listOf types.str;
default = [];
example = "[ \"IAM_OWNER\" ]";
description = ''
List of roles granted to instance.
'';
};
};
}));
};
action = mkOption {
default = {};
type = types.attrsOf (types.submodule ({ name, ... }: {
options = {
script = mkOption {
type = types.str;
example = ''
(ctx, api) => {
api.v1.claims.setClaim('some_claim', 'some_value');
};
'';
description = ''
The script to run. This must be a function that receives 2 parameters, and returns void. During the creation of the action's script this module simly does `const {{name}} = {{script}}`.
'';
};
timeout = mkOption {
type = (types.ints.between 0 20);
default = 10;
example = "10";
description = ''
After which time the action will be terminated if not finished.
'';
};
allowedToFail = mkOption {
type = types.bool;
default = true;
example = "true";
description = ''
Allowed to fail.
'';
};
};
}));
};
triggers = mkOption {
default = [];
type = types.listOf (types.submodule {
options = {
flowType = mkOption {
type = types.enum [ "authentication" "customiseToken" "internalAuthentication" "samlResponse" ];
example = "customiseToken";
description = ''
Type of the flow to which the action triggers belong.
'';
};
triggerType = mkOption {
type = types.enum [ "postAuthentication" "preCreation" "postCreation" "preUserinfoCreation" "preAccessTokenCreation" "preSamlResponse" ];
example = "postAuthentication";
description = ''
Trigger type on when the actions get triggered.
'';
};
actions = mkOption {
type = types.nonEmptyListOf types.str;
example = ''[ "action_name" ]'';
description = ''
Names of actions to trigger
'';
};
};
});
};
};
}));
};
};
config = let
_refTypeMap = {
org = { type = "org"; };
project = { type = "project"; };
user = { type = "user"; tfType = "human_user"; };
};
mapRef' = { type, tfType ? type }: name: { "${type}Id" = "\${ resource.zitadel_${tfType}.${toSnakeCase name}.id }"; };
mapRef = type: name: mapRef' (_refTypeMap.${type}) name;
mapEnum = prefix: value: "${prefix}_${value |> toSnakeCase |> toUpper}";
mapValue = type: value: ({
appType = mapEnum "OIDC_APP_TYPE" value;
grantTypes = map (t: mapEnum "OIDC_GRANT_TYPE" t) value;
responseTypes = map (t: mapEnum "OIDC_RESPONSE_TYPE" t) value;
authMethodType = mapEnum "OIDC_AUTH_METHOD_TYPE" value;
flowType = mapEnum "FLOW_TYPE" value;
triggerType = mapEnum "TRIGGER_TYPE" value;
accessTokenType = mapEnum "OIDC_TOKEN_TYPE" value;
}."${type}" or value);
toResource = name: value: nameValuePair
(toSnakeCase name)
(lib.mapAttrs' (k: v: nameValuePair (toSnakeCase k) (mapValue k v)) value);
withRef = type: name: attrs: attrs // (mapRef type name);
select = keys: callback: set:
if (length keys) == 0 then
mapAttrs' callback set
else let key = head keys; in
concatMapAttrs (k: v: select (drop 1 keys) (callback k) (v.${key} or {})) set
;
append = attrList: set: set // (listToAttrs attrList);
forEach = src: key: set:
let
_key = concatMapStringsSep "_" (k: "\${item.${k}}") key;
in
{
forEach = "{ for item in ${src} : \"${_key}\" => item }";
}
// set;
config' = config;
# this is a nix package, the generated json file to be exact
terraformConfiguration = inputs.terranix.lib.terranixConfiguration {
inherit system;
modules = [
({ config, lib, ... }: {
config = {
terraform.required_providers.zitadel = {
source = "zitadel/zitadel";
version = "2.2.0";
};
provider.zitadel = {
domain = "auth.kruining.eu";
insecure = "false";
jwt_profile_file = "/var/lib/zitadel/machine-key.json";
};
locals = {
extra_users = lib.tfRef "
flatten([ for org, users in jsondecode(file(\"${config'.sops.secrets."zitadel/users".path}\")): [
for name, details in users: {
org = org
name = name
email = details.email
firstName = details.firstName
lastName = details.lastName
}
] ])
";
orgs = cfg.organization |> mapAttrs (org: _: lib.tfRef "resource.zitadel_org.${org}.id");
};
resource = {
# Organizations
zitadel_org = cfg.organization |> select [] (name: { isDefault, ... }:
{ inherit name isDefault; }
|> toResource name
);
# Projects per organization
zitadel_project = cfg.organization |> select [ "project" ] (org: name: { hasProjectCheck, privateLabelingSetting, projectRoleAssertion, projectRoleCheck, ... }:
{
inherit name hasProjectCheck privateLabelingSetting projectRoleAssertion projectRoleCheck;
}
|> withRef "org" org
|> toResource "${org}_${name}"
);
# Each OIDC app per project
zitadel_application_oidc = cfg.organization |> select [ "project" "application" ] (org: project: name: { redirectUris, grantTypes, responseTypes, ...}:
{
inherit name redirectUris grantTypes responseTypes;
accessTokenRoleAssertion = true;
idTokenRoleAssertion = true;
accessTokenType = "JWT";
}
|> withRef "org" org
|> withRef "project" "${org}_${project}"
|> toResource "${org}_${project}_${name}"
);
# Each project role
zitadel_project_role = cfg.organization |> select [ "project" "role" ] (org: project: name: value:
{ inherit (value) displayName group; roleKey = name; }
|> withRef "org" org
|> withRef "project" "${org}_${project}"
|> toResource "${org}_${project}_${name}"
);
# Each project role assignment
zitadel_user_grant = cfg.organization |> select [ "project" "assign" ] (org: project: user: roles:
{ roleKeys = roles; }
|> withRef "org" org
|> withRef "project" "${org}_${project}"
|> withRef "user" "${org}_${user}"
|> toResource "${org}_${project}_${user}"
);
# Users
zitadel_human_user =
cfg.organization
|> select [ "user" ] (org: name: { email, userName, firstName, lastName, ... }:
{
inherit email userName firstName lastName;
isEmailVerified = true;
}
|> withRef "org" org
|> toResource "${org}_${name}"
)
|> append
[
(forEach "local.extra_users" [ "org" "name" ] {
orgId = lib.tfRef "local.orgs[each.value.org]";
userName = lib.tfRef "each.value.name";
email = lib.tfRef "each.value.email";
firstName = lib.tfRef "each.value.firstName";
lastName = lib.tfRef "each.value.lastName";
isEmailVerified = true;
}
|> toResource "extraUsers")
]
;
# Global user roles
zitadel_instance_member =
cfg.organization
|> filterAttrsRecursive (n: v: !(v ? "instanceRoles" && (length v.instanceRoles) == 0))
|> select [ "user" ] (org: name: { instanceRoles, ... }:
{ roles = instanceRoles; }
|> withRef "user" "${org}_${name}"
|> toResource "${org}_${name}"
);
# Organazation specific roles
zitadel_org_member =
cfg.organization
|> filterAttrsRecursive (n: v: !(v ? "roles" && (length v.roles) == 0))
|> select [ "user" ] (org: name: { roles, ... }:
{ inherit roles; }
|> withRef "org" org
|> withRef "user" "${org}_${name}"
|> toResource "${org}_${name}"
);
# Organazation's actions
zitadel_action = cfg.organization |> select [ "action" ] (org: name: { timeout, allowedToFail, script, ...}:
{
inherit allowedToFail name;
timeout = "${toString timeout}s";
script = "const ${name} = ${script}";
}
|> withRef "org" org
|> toResource "${org}_${name}"
);
# Organazation's action assignments
zitadel_trigger_actions =
cfg.organization
|> concatMapAttrs (org: { triggers, ... }:
triggers
|> imap0 (i: { flowType, triggerType, actions, ... }: (let name = "trigger_${toString i}"; in
{
inherit flowType triggerType;
actionIds =
actions
|> map (action: (lib.tfRef "zitadel_action.${org}_${toSnakeCase action}.id"));
}
|> withRef "org" org
|> toResource "${org}_${name}"
))
|> listToAttrs
);
# SMTP config
zitadel_smtp_config.default = {
sender_address = "chris@kruining.eu";
sender_name = "no-reply (Zitadel)";
tls = true;
host = "black-mail.nl:587";
user = "chris@kruining.eu";
password = lib.tfRef "file(\"${config'.sops.secrets."zitadel/email".path}\")";
set_active = true;
};
# Client credentials per app
local_sensitive_file = cfg.organization |> select [ "project" "application" ] (org: project: name: { exportMap, ... }:
nameValuePair "${org}_${project}_${name}" {
content = ''
${if exportMap.client_id != null then exportMap.client_id else "CLIENT_ID"}=${lib.tfRef "resource.zitadel_application_oidc.${org}_${project}_${name}.client_id"}
${if exportMap.client_secret != null then exportMap.client_secret else "CLIENT_SECRET"}=${lib.tfRef "resource.zitadel_application_oidc.${org}_${project}_${name}.client_secret"}
'';
filename = "/var/lib/zitadel/clients/${org}_${project}_${name}";
}
);
};
};
})
];
};
in
mkIf cfg.enable {
${namespace}.services.persistance.postgresql.enable = true;
config = mkIf cfg.enable {
environment.systemPackages = with pkgs; [
zitadel
];
systemd.tmpfiles.rules = [
"d /tmp/zitadelApplyTerraform 0755 zitadel zitadel -"
"d /var/lib/zitadel/clients 0755 zitadel zitadel -"
];
systemd.services.zitadelApplyTerraform = {
description = "Zitadel terraform apply";
wantedBy = [ "multi-user.target" ];
wants = [ "zitadel.service" ];
script = ''
#!/usr/bin/env bash
if [ "$(systemctl is-active zitadel)" != "active" ]; then
echo "Zitadel is not running"
exit 1
fi
# Print the path to the source for easier debugging
echo "config location: ${terraformConfiguration}"
# Copy infra code into workspace
cp -f ${terraformConfiguration} config.tf.json
# Initialize OpenTofu
${lib.getExe pkgs.opentofu} init
# Run the infrastructure code
# ${lib.getExe pkgs.opentofu} plan
${lib.getExe pkgs.opentofu} apply -auto-approve
'';
serviceConfig = {
Type = "oneshot";
User = "zitadel";
Group = "zitadel";
WorkingDirectory = "/tmp/zitadelApplyTerraform";
};
};
services = {
zitadel = {
enable = true;
openFirewall = true;
masterKeyFile = config.sops.secrets."zitadel/masterKey".path;
# masterKeyFile = config.sops.secrets."zitadel/masterKey".path;
masterKeyFile = "/var/lib/zitadel/master_key";
tlsMode = "external";
settings = {
Port = 9092;
ExternalDomain = "auth.kruining.eu";
ExternalDomain = "auth.amarth.cloud";
ExternalPort = 443;
ExternalSecure = true;
@ -602,13 +40,39 @@ in
SecretHasher.Hasher.Algorithm = "argon2id";
};
DefaultInstance = {
PasswordComplexityPolicy = {
MinLength = 20;
HasLowercase = false;
HasUppercase = false;
HasNumber = false;
HasSymbol = false;
};
LoginPolicy = {
AllowRegister = false;
ForceMFA = true;
};
LockoutPolicy = {
MaxPasswordAttempts = 5;
MaxOTPAttempts = 10;
};
SMTPConfiguration = {
SMTP = {
Host = "black-mail.nl:587";
User = "info@amarth.cloud";
Password = "__TODO_USE_SOPS__";
};
FromName = "Amarth Zitadel";
};
};
Database.postgres = {
Host = "localhost";
# Zitadel will report error if port is not set
Port = 5432;
Database = database;
Database = db_name;
User = {
Username = database;
Username = db_user;
SSL.Mode = "disable";
};
Admin = {
@ -619,16 +83,9 @@ in
};
steps = {
FirstInstance = {
# Not sure, this option seems to be mostly irrelevant
InstanceName = "eu";
MachineKeyPath = "/var/lib/zitadel/machine-key.json";
# PatPath = "/var/lib/zitadel/machine-key.pat";
# LoginClientPatPath = "/var/lib/zitadel/machine-key.json";
InstanceName = "auth.amarth.cloud";
Org = {
Name = "kruining";
Name = "Amarth";
Human = {
UserName = "chris";
FirstName = "Chris";
@ -639,49 +96,39 @@ in
};
Password = "KaasIsAwesome1!";
};
Machine = {
Machine = {
Username = "terraform-service-user";
Name = "Terraform";
};
MachineKey = { ExpirationDate = "2026-01-01T00:00:00Z"; Type = 1; };
# Pat = { ExpirationDate = "2026-01-01T00:00:00Z"; };
};
# LoginClient.Machine = {
# Username = "terraform-service-user";
# Name = "Terraform";
# };
};
};
};
# extraStepsPaths = [
# config.sops.templates."secrets.yaml".path
# ];
};
postgresql = {
enable = true;
ensureDatabases = [ database ];
ensureDatabases = [ db_name ];
ensureUsers = [
{
name = database;
name = db_user;
ensureDBOwnership = true;
}
];
authentication = mkForce ''
# Generated file, do not edit!
# TYPE DATABASE USER ADDRESS METHOD
local all all trust
host all all 127.0.0.1/32 trust
host all all ::1/128 trust
'';
};
caddy = {
enable = true;
virtualHosts = {
"auth.kruining.eu".extraConfig = ''
reverse_proxy h2c://::1:9092
"auth.amarth.cloud".extraConfig = ''
reverse_proxy h2c://127.0.0.1:9092
'';
};
extraConfig = ''
(auth) {
forward_auth h2c://::1:9092 {
(auth-z) {
forward_auth h2c://127.0.0.1:9092 {
uri /api/authz/forward-auth
copy_headers Remote-User Remote-Groups Remote-Email Remote-Name
}
@ -690,36 +137,11 @@ in
};
};
networking.firewall.allowedTCPPorts = [ 80 443 ];
# Secrets
sops = {
secrets = {
"zitadel/masterKey" = {
owner = "zitadel";
group = "zitadel";
restartUnits = [ "zitadel.service" ]; #EMGDB#6O$8qpGoLI1XjhUhnng1san@0
};
"zitadel/email" = {
owner = "zitadel";
group = "zitadel";
key = "email/chris_kruining_eu";
restartUnits = [ "zitadel.service" ];
};
"zitadel/users" = {
owner = "zitadel";
group = "zitadel";
restartUnits = [ "zitadelApplyTerraform.service" ];
};
};
templates = {
"users.yml" = {
};
};
sops.secrets."zitadel/masterKey" = {
owner = "zitadel";
group = "zitadel";
restartUnits = [ "zitadel.service" ];
};
};
}

View file

@ -1,35 +0,0 @@
{ config, lib, pkgs, namespace, ... }:
let
inherit (lib) mkIf mkEnableOption;
cfg = config.${namespace}.services.backup.borg;
in
{
options.${namespace}.services.backup.borg = {
enable = mkEnableOption "Borg Backup";
};
config = mkIf cfg.enable {
programs.ssh.extraConfig = ''
Host beheer.hazelhof.nl
Port 222
User chris
AddressFamily inet
IdentityFile /home/chris/.ssh/id_ed25519
'';
services = {
borgbackup.jobs = {
media = {
paths = "/var/media/test";
encryption.mode = "none";
# environment.BORG_SSH = "ssh -4 -i /home/chris/.ssh/id_ed25519";
environment.BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK = "yes";
repo = "ssh://beheer.hazelhof.nl//media";
compression = "auto,zstd";
startAt = "daily";
};
};
};
};
}

View file

@ -1,200 +0,0 @@
{ config, lib, pkgs, namespace, ... }:
let
inherit (builtins) toString toJSON;
inherit (lib) mkIf mkEnableOption;
cfg = config.${namespace}.services.communication.matrix;
domain = "kruining.eu";
fqn = "matrix.${domain}";
port = 4001;
database = "synapse";
in
{
options.${namespace}.services.communication.matrix = {
enable = mkEnableOption "Matrix server (Synapse)";
};
config = mkIf cfg.enable {
${namespace}.services = {
persistance.postgresql.enable = true;
# virtualisation.podman.enable = true;
};
networking.firewall.allowedTCPPorts = [ 4001 ];
services = {
matrix-synapse = {
enable = true;
extras = [ "oidc" ];
extraConfigFiles = [
config.sops.templates."synapse-oidc.yaml".path
];
settings = {
server_name = domain;
public_baseurl = "https://${fqn}";
enable_metrics = true;
registration_shared_secret = "tZtBnlhEmLbMwF0lQ112VH1Rl5MkZzYH9suI4pEoPXzk6nWUB8FJF4eEnwLkbstz";
url_preview_enabled = true;
precence.enabled = true;
# Since we'll be using OIDC for auth disable all local options
enable_registration = false;
enable_registration_without_verification = false;
password_config.enabled = false;
backchannel_logout_enabled = true;
sso = {
client_whitelist = [ "http://[::1]:9092" ];
update_profile_information = true;
};
database = {
# this is postgresql (also the default, but I prefer to be explicit)
name = "psycopg2";
args = {
database = database;
user = database;
};
};
listeners = [
{
bind_addresses = ["::"];
port = port;
type = "http";
tls = false;
x_forwarded = true;
resources = [
{
names = [ "client" "federation" "openid" "metrics" "media" "health" ];
compress = true;
}
];
}
];
};
};
mautrix-signal = {
enable = true;
registerToSynapse = true;
settings = {
appservice = {
provisioning.enabled = false;
# port = 40011;
};
homeserver = {
address = "http://[::1]:${toString port}";
domain = domain;
};
bridge = {
permissions = {
"@chris:${domain}" = "admin";
};
};
};
};
mautrix-whatsapp = {
enable = true;
registerToSynapse = true;
settings = {
appservice = {
provisioning.enabled = false;
# port = 40012;
};
homeserver = {
address = "http://[::1]:${toString port}";
domain = domain;
};
bridge = {
permissions = {
"@chris:${domain}" = "admin";
};
};
};
};
postgresql = {
enable = true;
ensureDatabases = [ database ];
ensureUsers = [
{
name = database;
ensureDBOwnership = true;
}
];
};
caddy = {
enable = true;
virtualHosts = let
server = {
"m.server" = "${fqn}:443";
};
client = {
"m.homeserver".base_url = "https://${fqn}";
"m.identity_server".base_url = "https://auth.kruining.eu";
};
in {
"${domain}".extraConfig = ''
header /.well-known/matrix/* Content-Type application/json
header /.well-known/matrix/* Access-Control-Allow-Origin *
respond /.well-known/matrix/server `${toJSON server}`
respond /.well-known/matrix/client `${toJSON client}`
'';
"${fqn}".extraConfig = ''
reverse_proxy /_matrix/* http://::1:4001
reverse_proxy /_synapse/client/* http://::1:4001
'';
};
};
};
sops = {
secrets = {
"synapse/oidc_id" = {};
"synapse/oidc_secret" = {};
};
templates = {
"synapse-oidc.yaml" = {
owner = "matrix-synapse";
content = ''
oidc_providers:
- discover: true
idp_id: zitadel
idp_name: Zitadel
issuer: "https://auth.kruining.eu"
scopes:
- openid
- profile
client_id: '${config.sops.placeholder."synapse/oidc_id"}'
client_secret: '${config.sops.placeholder."synapse/oidc_secret"}'
backchannel_logout_enabled: true
user_mapping_provider:
config:
localpart_template: "{{ user.preferred_username }}"
display_name_template: "{{ user.name }}"
'';
restartUnits = [ "matrix-synapse.service" ];
};
};
};
};
}

View file

@ -1,7 +1,6 @@
{ config, lib, pkgs, namespace, ... }:
let
inherit (builtins) toString;
inherit (lib) mkIf mkEnableOption mkOption;
inherit (lib) mkIf mkEnableOption;
cfg = config.${namespace}.services.development.forgejo;
domain = "git.amarth.cloud";
@ -9,22 +8,10 @@ in
{
options.${namespace}.services.development.forgejo = {
enable = mkEnableOption "Forgejo";
port = mkOption {
type = lib.types.port;
default = 5002;
example = "1234";
description = ''
Which port to bind forgejo to
'';
};
};
config = mkIf cfg.enable {
${namespace}.services = {
persistance.postgresql.enable = true;
virtualisation.podman.enable = true;
};
${namespace}.services.virtualisation.podman.enable = true;
environment.systemPackages = with pkgs; [ forgejo ];
@ -43,7 +30,7 @@ in
server = {
DOMAIN = domain;
ROOT_URL = "https://${domain}/";
HTTP_PORT = cfg.port;
HTTP_PORT = 5002;
LANDING_PAGE = "explore";
};
@ -93,7 +80,7 @@ in
openid = {
ENABLE_OPENID_SIGNIN = true;
ENABLE_OPENID_SIGNUP = true;
WHITELISTED_URIS = "https://auth.kruining.eu";
WHITELISTED_URIS = "https://auth.amarth.cloud";
};
oauth2_client = {
@ -104,7 +91,6 @@ in
actions = {
ENABLED = true;
# DEFAULT_ACTIONS_URL = "https://data.forgejo.org";
};
other = {
@ -112,16 +98,12 @@ in
SHOW_FOOTER_TEMPLATE_LOAD_TIME = false;
};
metrics = {
ENABLED = true;
};
api = {
ENABLE_SWAGGER = false;
};
mirror = {
ENABLED = true;
ENABLED = false;
};
session = {
@ -134,9 +116,9 @@ in
PROTOCOL = "smtp+starttls";
SMTP_ADDR = "black-mail.nl";
SMTP_PORT = 587;
FROM = "chris@kruining.eu";
USER = "chris@kruining.eu";
PASSWD_URI = "file:${config.sops.secrets."forgejo/email".path}";
FROM = "info@amarth.cloud";
USER = "info@amarth.cloud";
PASSWD = "__TODO_USE_SOPS__";
};
};
};
@ -144,22 +126,20 @@ in
openssh.settings.AllowUsers = [ "forgejo" ];
gitea-actions-runner = {
package = pkgs.forgejo-runner;
package = pkgs.forgejo-actions-runner;
instances.default = {
enable = true;
name = "default";
url = "https://git.amarth.cloud";
# Obtaining the path to the runner token file may differ
# tokenFile should be in format TOKEN=<secret>, since it's EnvironmentFile for systemd
tokenFile = config.sops.secrets."forgejo/action_runner_token".path;
# token = "ZBetud1F0IQ9VjVFpZ9bu0FXgx9zcsy1x25yvjhw";
# tokenFile = config.age.secrets.forgejo-runner-token.path;
token = "ZBetud1F0IQ9VjVFpZ9bu0FXgx9zcsy1x25yvjhw";
labels = [
"default:docker://nixos/nix:latest"
"ubuntu:docker://ubuntu:24-bookworm"
"nix:docker://git.amarth.cloud/amarth/runners/default:latest"
"default:docker://node:22-bullseye"
];
settings = {
log.level = "info";
};
};
};
@ -167,32 +147,17 @@ in
caddy = {
enable = true;
virtualHosts = {
"${domain}".extraConfig = ''
# import auth
${domain}.extraConfig = ''
# import auth-z
# stupid dumb way to prevent the login page and go to zitadel instead
# be aware that this does not disable local login at all!
# rewrite /user/login /user/oauth2/Zitadel
rewrite /user/login /user/oauth2/Zitadel
reverse_proxy http://127.0.0.1:${toString cfg.port}
reverse_proxy http://127.0.0.1:5002
'';
};
};
};
sops.secrets = {
"forgejo/action_runner_token" = {
owner = "gitea-runner";
group = "gitea-runner";
restartUnits = [ "gitea-runner-default.service" ];
};
"forgejo/email" = {
owner = "forgejo";
group = "forgejo";
key = "email/chris_kruining_eu";
restartUnits = [ "forgejo.service" ];
};
};
};
}

View file

@ -1,11 +1,9 @@
{ pkgs, lib, namespace, config, inputs, system, ... }:
{ pkgs, lib, namespace, config, ... }:
let
inherit (lib) mkIf mkEnableOption mkOption;
inherit (lib.types) str;
cfg = config.${namespace}.services.media;
arr = ["radarr" ];
in
{
options.${namespace}.services.media = {
@ -62,74 +60,44 @@ in
"d '${cfg.path}/reiverr/config' 0700 ${cfg.user} ${cfg.group} - -"
"d '${cfg.path}/downloads/incomplete' 0700 ${cfg.user} ${cfg.group} - -"
"d '${cfg.path}/downloads/done' 0700 ${cfg.user} ${cfg.group} - -"
"d /var/lib/radarrApplyTerraform 0755 ${cfg.user} ${cfg.group} -"
];
#=========================================================================
# Services
#=========================================================================
services = let
arr-services =
arr
|> lib.imap (i: service: {
name = service;
value = {
enable = true;
openFirewall = true;
environmentFiles = [
config.sops.templates."${service}/config.env".path
];
settings = {
auth.authenticationMethod = "External";
server = {
bindaddress = "0.0.0.0";
port = 2000 + i;
};
postgres = {
host = "localhost";
port = "5432";
user = service;
maindb = service;
logdb = service;
};
};
}
// (if service != "prowlarr" then { user = cfg.user; group = cfg.group; } else {});
})
|> lib.listToAttrs
;
in
arr-services // {
bazarr = {
enable = true;
openFirewall = true;
user = cfg.user;
group = cfg.group;
listenPort = 2005;
};
# port is harcoded in nixpkgs module
jellyfin = {
serviceConf = {
enable = true;
openFirewall = true;
user = cfg.user;
group = cfg.group;
};
in {
jellyfin = serviceConf;
radarr = serviceConf;
sonarr = serviceConf;
bazarr = serviceConf;
lidarr = serviceConf;
flaresolverr = {
enable = true;
openFirewall = true;
port = 2007;
};
jellyseerr = {
enable = true;
openFirewall = true;
};
prowlarr = {
enable = true;
openFirewall = true;
};
qbittorrent = {
enable = true;
openFirewall = true;
webuiPort = 2008;
webuiPort = 5000;
serverConfig = {
LegalNotice.Accepted = true;
@ -139,7 +107,6 @@ in
group = cfg.group;
};
# port is harcoded in nixpkgs module
sabnzbd = {
enable = true;
openFirewall = true;
@ -149,159 +116,46 @@ in
group = cfg.group;
};
postgresql =
let
databases = arr |> lib.concatMap (s: [ s "${s}-log" ]);
in
{
enable = true;
ensureDatabases = arr;
ensureUsers = arr |> lib.map (service: {
name = service;
ensureDBOwnership = true;
});
};
caddy = {
enable = true;
virtualHosts = {
"media.kruining.eu".extraConfig = ''
import auth
reverse_proxy http://127.0.0.1:9494
'';
"jellyfin.kruining.eu".extraConfig = ''
reverse_proxy http://[::1]:8096
reverse_proxy http://127.0.0.1:8096
'';
};
};
};
systemd.services.radarrApplyTerraform =
let
# this is a nix package, the generated json file to be exact
terraformConfiguration = inputs.terranix.lib.terranixConfiguration {
inherit system;
modules = [
({ config, lib, ... }: {
config = {
variable = {
api_key = {
type = "string";
description = "Radarr api key";
};
};
terraform.required_providers.radarr = {
source = "devopsarr/radarr";
version = "2.2.0";
};
provider.radarr = {
url = "http://127.0.0.1:2001";
api_key = lib.tfRef "var.api_key";
};
resource = {
radarr_root_folder.local = {
path = "/var/media/movies";
};
};
};
})
];
};
in
{
description = "Radarr terraform apply";
wantedBy = [ "multi-user.target" ];
wants = [ "radarr.service" ];
script = ''
#!/usr/bin/env bash
if [ "$(systemctl is-active radarr)" != "active" ]; then
echo "Radarr is not running"
exit 1
fi
# Sleep for a bit to give radarr the chance to start up
sleep 5s
# Print the path to the source for easier debugging
echo "config location: ${terraformConfiguration}"
# Copy infra code into workspace
cp -f ${terraformConfiguration} config.tf.json
# Initialize OpenTofu
${lib.getExe pkgs.opentofu} init
# Run the infrastructure code
# ${lib.getExe pkgs.opentofu} plan -var-file='${config.sops.templates."radarr/config.tfvars".path}'
${lib.getExe pkgs.opentofu} apply -auto-approve -var-file='${config.sops.templates."radarr/config.tfvars".path}'
'';
serviceConfig = {
Type = "oneshot";
User = cfg.user;
Group = cfg.group;
WorkingDirectory = "/var/lib/radarrApplyTerraform";
EnvironmentFile = [
config.sops.templates."radarr/config.env".path
];
};
};
systemd.services.jellyfin.serviceConfig.killSignal = lib.mkForce "SIGKILL";
sops = {
secrets =
arr
|> lib.map (service: {
name = "${service}/apikey";
value = {
owner = cfg.user;
group = cfg.group;
restartUnits = [ "${service}.service" ];
${namespace}.services.virtualisation.podman.enable = true;
virtualisation = {
oci-containers = {
backend = "podman";
containers = {
# flaresolverr = {
# image = "flaresolverr/flaresolverr";
# autoStart = true;
# ports = [ "127.0.0.1:8191:8191" ];
# };
reiverr = {
image = "ghcr.io/aleksilassila/reiverr:v2.2.0";
autoStart = true;
ports = [ "127.0.0.1:9494:9494" ];
volumes = [ "${cfg.path}/reiverr/config:/config" ];
};
})
|> lib.listToAttrs
;
templates =
let
apikeys =
arr
|> lib.map (service: {
name = "${service}/config.env";
value = {
owner = cfg.user;
group = cfg.group;
restartUnits = [ "${service}.service" ];
content = ''
${lib.toUpper service}__AUTH__APIKEY="${config.sops.placeholder."${service}/apikey"}"
'';
};
})
|> lib.listToAttrs;
tfvars =
arr
|> lib.map(service: {
name = "${service}/config.tfvars";
value = {
owner = cfg.user;
group = cfg.group;
restartUnits = [ "${service}ApplyTerraform.service" ];
content = ''
api_key = "${config.sops.placeholder."${service}/apikey"}"
'';
};
})
|> lib.listToAttrs;
in
apikeys // tfvars
;
};
};
};
networking.firewall.allowedTCPPorts = [ 80 443 6969 ];
};
}

View file

@ -1,161 +0,0 @@
{ config, lib, namespace, ... }:
let
inherit (lib) mkIf mkEnableOption;
cfg = config.${namespace}.services.media.homer;
in
{
options.${namespace}.services.media.homer = {
enable = mkEnableOption "Enable homer";
};
config = mkIf cfg.enable {
networking.firewall.allowedTCPPorts = [ 2000 ];
services = {
homer = {
enable = true;
virtualHost = {
caddy.enable = true;
domain = "http://:2000";
};
settings = {
title = "Ulmo dashboard";
columns = 4;
connectivityCheck = true;
links = [];
services = [
{
name = "Services";
items = [
{
name = "Zitadel";
logo = "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/zitadel.svg";
tag = "app";
url = "https://auth.kruining.eu";
target = "_blank";
}
{
name = "Forgejo";
logo = "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/forgejo.svg";
tag = "app";
type = "Gitea";
url = "https://git.amarth.cloud";
target = "_blank";
}
{
name = "Vaultwarden";
logo = "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/vaultwarden.svg";
type = "Vaultwarden";
tag = "app";
url = "https://vault.kruining.eu";
target = "_blank";
}
];
}
{
name = "Observability";
items = [
{
name = "Grafana";
type = "Grafana";
logo = "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/grafana.svg";
tag = "app";
url = "http://${config.networking.hostName}:${builtins.toString config.services.grafana.settings.server.http_port}";
target = "_blank";
}
{
name = "Prometheus";
type = "Prometheus";
logo = "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/prometheus.svg";
tag = "app";
url = "http://${config.networking.hostName}:${builtins.toString config.services.prometheus.port}";
target = "_blank";
}
];
}
{
name = "Media";
items = [
{
name = "Jellyfin (Movies)";
logo = "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/jellyfin.svg";
tag = "app";
type = "Emby";
url = "http://${config.networking.hostName}:8096";
apikey = "e3ceed943eeb409ba8342738db7cc1f5";
libraryType = "movies";
target = "_blank";
}
{
name = "Radarr";
type = "Radarr";
logo = "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/radarr.svg";
tag = "app";
url = "http://${config.networking.hostName}:2001";
target = "_blank";
}
{
name = "Sonarr";
type = "Sonarr";
logo = "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/sonarr.svg";
tag = "app";
url = "http://${config.networking.hostName}:2002";
target = "_blank";
}
{
name = "Lidarr";
type = "Lidarr";
logo = "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/lidarr.svg";
tag = "app";
url = "http://${config.networking.hostName}:2003";
target = "_blank";
}
{
name = "Prowlarr";
type = "Prowlarr";
logo = "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/prowlarr.svg";
tag = "app";
url = "http://${config.networking.hostName}:2004";
target = "_blank";
}
{
name = "qBittorrent";
type = "qBittorrent";
logo = "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/qbittorrent.svg";
tag = "app";
url = "http://${config.networking.hostName}:${builtins.toString config.services.qbittorrent.webuiPort}";
target = "_blank";
}
{
name = "SABnzbd";
type = "SABnzbd";
logo = "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/sabnzdb-light.svg";
tag = "app";
url = "http://${config.networking.hostName}:8080";
target = "_blank";
}
];
}
];
};
};
};
};
}

View file

@ -1,214 +0,0 @@
{ pkgs, config, lib, namespace, inputs, system, ... }:
let
inherit (builtins) toString;
inherit (lib) mkIf mkEnableOption mkOption types;
cfg = config.${namespace}.services.media.servarr;
in
{
options.${namespace}.services.media = {
servarr = mkOption {
type = types.attrsOf (types.submodule ({ name, ... }: {
options = {
enable = mkEnableOption "Enable ${name}";
debug = mkEnableOption "Use tofu plan instead of tofu apply for ${name} ";
port = mkOption {
type = types.port;
};
rootFolders = mkOption {
type = types.listOf types.str;
default = [];
};
};
}));
default = {};
};
};
config = {
services =
cfg
|> lib.mapAttrsToList (service: { enable, port, ... }: (mkIf enable {
"${service}" = {
enable = true;
openFirewall = true;
environmentFiles = [
config.sops.templates."${service}/config.env".path
];
settings = {
auth.authenticationMethod = "External";
server = {
bindaddress = "0.0.0.0";
port = port;
};
postgres = {
host = "localhost";
port = "5432";
user = service;
maindb = service;
logdb = service;
};
};
};
}))
|> lib.mergeAttrsList
|> (set: set // {
postgres = {
ensureDatabases = cfg |> lib.attrNames;
ensureUsers = cfg |> lib.attrNames |> lib.map (service: {
name = service;
ensureDBOwnership = true;
});
};
})
;
systemd =
cfg
|> lib.mapAttrsToList (service: { enable, debug, port, rootFolders, ... }: (mkIf enable {
tmpfiles.rules = [
"d /var/lib/${service}ApplyTerraform 0755 ${service} ${service} -"
];
services."${service}ApplyTerraform" =
let
terraformConfiguration = inputs.terranix.lib.terranixConfiguration {
inherit system;
modules = [
({ config, lib, ... }: {
config = {
variable = {
api_key = {
type = "string";
description = "${service} api key";
};
};
terraform.required_providers.${service} = {
source = "devopsarr/${service}";
version = "2.2.0";
};
provider.${service} = {
url = "http://127.0.0.1:${toString port}";
api_key = lib.tfRef "var.api_key";
};
resource = {
"${service}_root_folder" =
rootFolders
|> lib.imap (i: f: lib.nameValuePair "local${toString i}" { path = f; })
|> lib.listToAttrs
;
};
};
})
];
};
in
{
description = "${service} terraform apply";
wantedBy = [ "multi-user.target" ];
wants = [ "${service}.service" ];
script = ''
#!/usr/bin/env bash
# Sleep for a bit to give the service a chance to start up
sleep 5s
if [ "$(systemctl is-active ${service})" != "active" ]; then
echo "${service} is not running"
exit 1
fi
# Print the path to the source for easier debugging
echo "config location: ${terraformConfiguration}"
# Copy infra code into workspace
cp -f ${terraformConfiguration} config.tf.json
# Initialize OpenTofu
${lib.getExe pkgs.opentofu} init
# Run the infrastructure code
${lib.getExe pkgs.opentofu} \
${if debug then "plan" else "apply -auto-approve"} \
-var-file='${config.sops.templates."${service}/config.tfvars".path}'
'';
serviceConfig = {
Type = "oneshot";
User = service;
Group = service;
WorkingDirectory = "/var/lib/${service}ApplyTerraform";
EnvironmentFile = [
config.sops.templates."${service}/config.env".path
];
};
};
}))
|> lib.mergeAttrsList
;
users.users =
cfg
|> lib.mapAttrsToList (service: { enable, ... }: (mkIf enable {
"${service}".extraGroups = [ "media" ];
}))
|> lib.mergeAttrsList
;
sops =
cfg
|> lib.mapAttrsToList (service: { enable, ... }: (mkIf enable {
secrets."${service}/apikey" = {
owner = service;
group = service;
restartUnits = [ "${service}.service" ];
};
templates = {
"${service}/config.env" = {
owner = service;
group = service;
restartUnits = [ "${service}.service" ];
content = ''
${lib.toUpper service}__AUTH__APIKEY="${config.sops.placeholder."${service}/apikey"}"
'';
};
"${service}/config.tfvars" = {
owner = service;
group = service;
restartUnits = [ "${service}.service" ];
content = ''
api_key = "${config.sops.placeholder."${service}/apikey"}"
'';
};
};
}))
|> lib.mergeAttrsList
;
};
# cfg
# |> lib.mapAttrsToList (service: { enable, debug, port, rootFolders, ... }: (mkIf enable {
# # sops = {
# # };
# }))
# |> lib.mergeAttrsList
# ;
}

View file

@ -42,9 +42,9 @@ in
login_attribute_path = "username";
name_attribute_path = "full_name";
role_attribute_path = "contains(urn:zitadel:iam:org:project:roles[*], 'owner') && 'GrafanaAdmin' || contains(urn:zitadel:iam:org:project:roles[*], 'contributer') && 'Editor' || 'Viewer'";
auth_url = "https://auth.kruining.eu/oauth/v2/authorize";
token_url = "https://auth.kruining.eu/oauth/v2/token";
api_url = "https://auth.kruining.eu/oidc/v1/userinfo";
auth_url = "https://auth.amarth.cloud/oauth/v2/authorize";
token_url = "https://auth.amarth.cloud/oauth/v2/token";
api_url = "https://auth.amarth.cloud/oidc/v1/userinfo";
allow_sign_up = true;
auto_login = true;
use_pkce = true;

View file

@ -23,7 +23,7 @@ in
common = {
ring = {
instance_addr = "127.0.0.1";
kvstore.store = "inmemory";
kvstore.store = "inmmemory";
};
replication_factor = 1;
path_prefix = "/tmp/loki";

View file

@ -29,11 +29,9 @@ in
filename = "filename";
};
clients = [
{
url = "http://::1:9003/loki/api/v1/push";
}
];
clients = {
url = "http://127.0.0.1:3100/loki/api/v1/push";
};
scrape_configs = [
{

View file

@ -1,25 +0,0 @@
{ pkgs, config, lib, namespace, ... }:
let
inherit (builtins) toString;
inherit (lib) mkIf mkEnableOption;
cfg = config.${namespace}.services.observability.uptime-kuma;
in
{
options.${namespace}.services.observability.uptime-kuma = {
enable = mkEnableOption "enable uptime kuma";
};
config = mkIf cfg.enable {
services.uptime-kuma = {
enable = true;
settings = {
PORT = toString 9006;
HOST = "0.0.0.0";
};
};
networking.firewall.allowedTCPPorts = [ 9006 ];
};
}

View file

@ -1,26 +0,0 @@
{ config, lib, pkgs, namespace, ... }:
let
inherit (lib) mkIf mkEnableOption;
cfg = config.${namespace}.services.persistance.postgresql;
in
{
options.${namespace}.services.persistance.postgresql = {
enable = mkEnableOption "Postgresql";
};
config = mkIf cfg.enable {
services = {
postgresql = {
enable = true;
authentication = ''
# Generated file, do not edit!
# TYPE DATABASE USER ADDRESS METHOD
local all all trust
host all all 127.0.0.1/32 trust
host all all ::1/128 trust
'';
};
};
};
}

View file

@ -1,87 +1,13 @@
{ pkgs, config, lib, namespace, ... }:
let
inherit (builtins) toString;
inherit (lib) mkIf mkEnableOption mkOption types getAttrs toUpper concatMapAttrsStringSep;
inherit (lib) mkIf mkEnableOption;
cfg = config.${namespace}.services.security.vaultwarden;
databaseProviderSqlite = types.submodule ({ ... }: {
options = {
type = mkOption {
type = types.enum [ "sqlite" ];
};
file = mkOption {
type = types.str;
description = '''';
};
};
});
databaseProviderPostgresql = types.submodule ({ ... }:
let
urlOptions = lib.${namespace}.options.mkUrlOptions {
host = {
description = ''
Hostname of the postgresql server
'';
};
port = {
default = 5432;
example = "5432";
description = ''
Port of the postgresql server
'';
};
protocol = mkOption {
default = "postgres";
example = "postgres";
};
};
in
{
options = {
type = mkOption {
type = types.enum [ "postgresql" ];
};
sslMode = mkOption {
type = types.enum [ "verify-ca" "verify-full" "require" "prefer" "allow" "disabled" ];
default = "verify-full";
example = "verify-ca";
description = ''
How to verify the server's ssl
| mode | eavesdropping protection | MITM protection | Statement |
|-------------|--------------------------|----------------------|---------------------------------------------------------------------------------------------------------------------------------------------|
| disable | No | No | I don't care about security, and I don't want to pay the overhead of encryption. |
| allow | Maybe | No | I don't care about security, but I will pay the overhead of encryption if the server insists on it. |
| prefer | Maybe | No | I don't care about encryption, but I wish to pay the overhead of encryption if the server supports it. |
| require | Yes | No | I want my data to be encrypted, and I accept the overhead. I trust that the network will make sure I always connect to the server I want. |
| verify-ca | Yes | Depends on CA policy | I want my data encrypted, and I accept the overhead. I want to be sure that I connect to a server that I trust. |
| verify-full | Yes | Yes | I want my data encrypted, and I accept the overhead. I want to be sure that I connect to a server I trust, and that it's the one I specify. |
[Source](https://www.postgresql.org/docs/current/libpq-ssl.html#LIBPQ-SSL-SSLMODE-STATEMENTS)
'';
};
} // (urlOptions |> getAttrs [ "protocol" "host" "port" ]);
});
in
{
options.${namespace}.services.security.vaultwarden = {
enable = mkEnableOption "enable vaultwarden";
database = mkOption {
type = types.oneOf [
(types.addCheck databaseProviderSqlite (x: x ? type && x.type == "sqlite"))
(types.addCheck databaseProviderPostgresql (x: x ? type && x.type == "postgresql"))
null
];
default = null;
description = '''';
};
};
config = mkIf cfg.enable {
@ -89,8 +15,6 @@ in
"d '/var/lib/vaultwarden' 0700 vaultwarden vaultwarden - -"
];
# systemd.services.vaultwarden.wants = [ "zitadelApplyTerraform.service" ];
services = {
vaultwarden = {
enable = true;
@ -102,6 +26,8 @@ in
SIGNUPS_ALLOWED = false;
DOMAIN = "https://vault.kruining.eu";
ADMIN_TOKEN = "";
DATABASE_URL = "postgres://localhost:5432/vaultwarden?sslmode=disable";
WEB_VAULT_ENABLED = true;
@ -113,8 +39,11 @@ in
SSO_ROLES_ENABLED = true;
SSO_ORGANIZATIONS_ENABLED = true;
SSO_ORGANIZATIONS_REVOCATION = true;
SSO_AUTHORITY = "https://auth.kruining.eu/";
SSO_AUTHORITY = "https://auth.amarth.cloud/";
SSO_SCOPES = "email profile offline_access";
SSO_AUDIENCE_TRUSTED = "^333297815511892227$";
SSO_CLIENT_ID = "335178854421299459";
SSO_CLIENT_SECRET = "";
ROCKET_ADDRESS = "::1";
ROCKET_PORT = 8222;
@ -123,15 +52,11 @@ in
SMTP_HOST = "black-mail.nl";
SMTP_PORT = 587;
SMTP_SECURITY = "starttls";
SMTP_USERNAME = "chris@kruining.eu";
SMTP_FROM = "chris@kruining.eu";
SMTP_USERNAME = "info@amarth.cloud";
SMTP_PASSWORD = "";
SMTP_FROM = "info@amarth.cloud";
SMTP_FROM_NAME = "Chris' Vaultwarden";
};
environmentFile = [
"/var/lib/zitadel/clients/nix_ulmo_vaultwarden"
config.sops.templates."vaultwarden/config.env".path
];
};
postgresql = {
@ -151,12 +76,6 @@ in
"vault.kruining.eu".extraConfig = ''
encode zstd gzip
handle_path /admin {
respond 401 {
close
}
}
reverse_proxy http://localhost:${toString config.services.vaultwarden.config.ROCKET_PORT} {
header_up X-Real-IP {remote_host}
}
@ -164,54 +83,5 @@ in
};
};
};
sops = {
secrets = {
"vaultwarden/email" = {
owner = config.users.users.vaultwarden.name;
group = config.users.users.vaultwarden.name;
key = "email/chris_kruining_eu";
restartUnits = [ "vaultwarden.service" ];
};
};
templates = {
"vaultwarden/config.env" = {
content = ''
SMTP_PASSWORD='${config.sops.placeholder."vaultwarden/email"}';
'';
owner = config.users.users.vaultwarden.name;
group = config.users.groups.vaultwarden.name;
};
temp-db-output.content =
let
config =
cfg.database
|> ({ type, ... }@db:
if type == "sqlite" then
{ inherit (db) type file; }
else if type == "postgresql" then
{
inherit (db) type;
url = lib.${namespace}.strings.toUrl {
inherit (db) protocol host port;
path = "vaultwarden";
query = {
sslmode = db.sslMode;
};
};
}
else
{}
)
|> concatMapAttrsStringSep "\n" (n: v: "${toUpper n}=${v}")
;
in
''
# GENERATED VALUES
${config}
'';
};
};
};
}

View file

@ -12,7 +12,6 @@ in
config = mkIf cfg.enable {
virtualisation = {
containers.enable = true;
oci-containers.backend = "podman";
podman = {
enable = true;

View file

@ -1,4 +1,4 @@
{ pkgs, config, namespace, inputs, system, ... }:
{ pkgs, config, namespace, inputs, ... }:
let
cfg = config.${namespace}.system.security.sops;
in
@ -13,14 +13,10 @@ in
environment.systemPackages = with pkgs; [ sops ];
sops = {
defaultSopsFile = ../../../../../_secrets/secrets.yaml;
defaultSopsFormat = "yaml";
defaultSopsFile = inputs.self + "/systems/${system}/${config.networking.hostName}/secrets.yml";
age = {
# keyFile = "~/.config/sops/age/keys.txt";
# sshKeyPaths = [ "~/.ssh/id_ed25519" ];
# generateKey = true;
};
age.keyFile = "/home/";
};
};
}

View file

@ -1,12 +0,0 @@
{ mkShell, inputs, pkgs, ... }:
mkShell {
packages = with pkgs; [
bash
sops
just
yq
pwgen
inputs.clan-core.packages.x86_64-linux.clan-cli
];
}

View file

@ -5,8 +5,6 @@
./hardware.nix
];
system.activationScripts.remove-gtkrc.text = "rm -f /home/chris/.gtkrc-2.0";
sneeuwvlok = {
hardware.has = {
gpu.amd = true;

View file

@ -26,9 +26,9 @@ in
fsType = "nfs";
};
# "/home/chris/mandos" = {
# device = "mandos:/";
# fsType = "nfs";
# };
"/home/chris/mandos" = {
device = "mandos:/";
fsType = "nfs";
};
};
}

View file

@ -5,200 +5,28 @@
./hardware.nix
];
networking = {
interfaces.enp2s0 = {
ipv6.addresses = [
{ address = "2a0d:6e00:1dc9:0::dead:beef"; prefixLength = 64; }
];
useDHCP = true;
};
defaultGateway = {
address = "192.168.1.1";
interface = "enp2s0";
};
defaultGateway6 = {
address = "fe80::1";
interface = "enp2s0";
};
};
# Expose amarht cloud stuff like this until I have a proper solution
services.caddy.virtualHosts = {
"auth.amarth.cloud".extraConfig = ''
reverse_proxy http://192.168.1.223:9092
'';
"amarth.cloud".extraConfig = ''
reverse_proxy http://192.168.1.223:8080
'';
};
sneeuwvlok = {
services = {
backup.borg.enable = true;
authentication.zitadel = {
enable = true;
organization = {
nix = {
user = {
chris = {
email = "chris@kruining.eu";
firstName = "Chris";
lastName = "Kruining";
roles = [ "ORG_OWNER" ];
instanceRoles = [ "IAM_OWNER" ];
};
kaas = {
email = "chris+kaas@kruining.eu";
firstName = "Kaas";
lastName = "Kruining";
};
};
project = {
ulmo = {
projectRoleCheck = true;
projectRoleAssertion = true;
hasProjectCheck = true;
role = {
jellyfin = {
group = "jellyfin";
};
jellyfin_admin = {
group = "jellyfin";
};
};
assign = {
chris = [ "jellyfin" "jellyfin_admin" ];
kaas = [ "jellyfin" ];
};
application = {
jellyfin = {
redirectUris = [ "https://jellyfin.kruining.eu/sso/OID/redirect/zitadel" ];
grantTypes = [ "authorizationCode" ];
responseTypes = [ "code" ];
};
forgejo = {
redirectUris = [ "https://git.amarth.cloud/user/oauth2/zitadel/callback" ];
grantTypes = [ "authorizationCode" ];
responseTypes = [ "code" ];
};
vaultwarden = {
redirectUris = [ "https://vault.kruining.eu/identity/connect/oidc-signin" ];
grantTypes = [ "authorizationCode" ];
responseTypes = [ "code" ];
exportMap = {
client_id = "SSO_CLIENT_ID";
client_secret = "SSO_CLIENT_SECRET";
};
};
matrix = {
redirectUris = [ "https://matrix.kruining.eu/_synapse/client/oidc/callback" ];
grantTypes = [ "authorizationCode" ];
responseTypes = [ "code" ];
};
};
};
};
action = {
flattenRoles = {
script = ''
(ctx, api) => {
if (ctx.v1.user.grants == undefined || ctx.v1.user.grants.count == 0) {
return;
}
const roles = ctx.v1.user.grants.grants.flatMap(({ roles, projectId }) => roles.map(role => projectId + ':' + role));
api.v1.claims.setClaim('nix:zitadel:custom', JSON.stringify({ roles }));
};
'';
};
};
triggers = [
{ flowType = "customiseToken"; triggerType = "preUserinfoCreation"; actions = [ "flattenRoles" ]; }
{ flowType = "customiseToken"; triggerType = "preAccessTokenCreation"; actions = [ "flattenRoles" ]; }
];
};
};
};
communication.matrix.enable = true;
authentication.authelia.enable = true;
authentication.zitadel.enable = true;
development.forgejo.enable = true;
networking.ssh.enable = true;
media.enable = true;
media.homer.enable = true;
media.nfs.enable = true;
media.servarr = {
# radarr = {
# port = 2001;
# };
sonarr = {
enable = true;
# debug = true;
port = 2002;
rootFolders = [
"/var/media/series"
];
};
lidarr = {
enable = true;
debug = true;
port = 2003;
rootFolders = [
"/var/media/music"
];
};
prowlarr = {
enable = true;
debug = true;
port = 2004;
};
};
observability = {
grafana.enable = true;
prometheus.enable = true;
loki.enable = true;
promtail.enable = true;
# uptime-kuma.enable = true;
};
persistance.convex.enable = true;
security.vaultwarden = {
enable = true;
database = {
# type = "sqlite";
# file = "/var/lib/vaultwarden/state.db";
type = "postgresql";
host = "localhost";
port = 5432;
sslMode = "disabled";
};
};
security.vaultwarden.enable = true;
};
editor = {

View file

@ -5,7 +5,9 @@ in
{
# TODO :: Implement disko at some point
swapDevices = [];
swapDevices = [
{ device = "/dev/disk/by-uuid/0ddf001a-5679-482e-b254-04a1b9094794"; }
];
boot.supportedFilesystems = [ "nfs" ];

View file

@ -1,45 +0,0 @@
email:
chris_kruining_eu: ENC[AES256_GCM,data:/JS+dQ6ABlkdjRZP+sGeUY3js30swS4=,iv:d5CcoY6DD3DJ/e3t0OU/KUULccJpTN0uBQPQzl/3R0s=,tag:aTN7RdzXkIpci9tEBjevSA==,type:str]
info_amarth_cloud: ENC[AES256_GCM,data:/x7aAFAxXYYf79tB08VQmmuTIy2TvdSTFfAzIWdIr+I=,iv:plNxS6oOin+oEql+1xsePOsUfLJkf+ZPBviPRTbIghE=,tag:hjtK3rysd2NNBA2mWdv8cw==,type:str]
zitadel:
masterKey: ENC[AES256_GCM,data:4MPvBo407qrS7NF4oUTf84tZoPkSRmiHdD7qpkYeHME=,iv:H2NIAN0xBUDqnyco9gA3zYAsKtSeA/JpqYrPhc1eqc0=,tag:6OFGDfsucG5gDerImgpuXA==,type:str]
nix: {}
users: ENC[AES256_GCM,data:xkjm0+PBt6gmZyfi3n3OIEe5b+d4OtN0Y3UfmdcbcJHbJZuiz+60oUjlAN0vjtsi0muufoAqtGJTIpm9nDZzzN7b7LK43TAhcuSlIm5LpbZFp1U3H4laRbTwauAT6wA0aDCfAkwTozxAuEUk1jAu+65ktJNJb7b0PR7s/I/wf7IgW2+K4Jv3LIOZIipUwfuvXuTzsxCElYRvGZXmIuXrYq1EaymksHHggemrKeMWLAae7mzz5v3aBbwxiVjQNkQkS4ApsO/5nZUat0oqXA==,iv:fptZn4NmX3iYKSEPLJAOFpt+KQ6TR1w9KaY9IF4p/Wk=,tag:UKvMOSIT5/mhfZA3usbLhQ==,type:str]
forgejo:
action_runner_token: ENC[AES256_GCM,data:yJ6OnRq5kinbuhvH06K5o3l86EafuBoojMwg/qhP+cgeH+BwPeE+Ng==,iv:IeXJahPxgLNIUFmkgp495tLVh8UyQBmJ2SnVEUhlhHs=,tag:XYQi613CxSp8AQeilJMrsg==,type:str]
synapse:
oidc_id: ENC[AES256_GCM,data:XbCpyGq0LeRJWq8dv/5Dipvp,iv:YDhgl26z1NBbIQLoLdGVz0+ze6o1ZcmgVHPfwoRj57I=,tag:y2vUuqnDmtTvVQmZCAlnLg==,type:str]
oidc_secret: ENC[AES256_GCM,data:nVFi5EFbNMZ0mvrDHVYC0NiwJlo2eEw44D+Fcv9SKSb2oO00lGEDkP/oXDj5YgDq6RLQSe3f/SUOn77ntwnZYg==,iv:awe7VNUYOn9ofl1QlQTrEN5d0i5WkVM35qndruL4VXo=,tag:8Yoc9lFF9aWbtAa5fzQGEA==,type:str]
kaas: ENC[AES256_GCM,data:3yI6lH0rw+f2OFJ94Z7zb0pYwy4FDFs9rJi2wpd9VVWghmey5g4O788ypXa34XqKCQDDHDgTxwyDs6KpvCQQaLV1PDhXd4Po0SSlIOkUtCWhOf6Tp3PM2ASoE+AAAzJLJUc6AZdBJRyYU9V+UvO9jW+WmlpZpsg5crnVMzZo7f2AF0ep9A/A5BL1Y2UhYQE4LDVkLC9AL3hl8IhF5xSdZdO0ugrP0x7CKVUxA7fJyOjx7/IKVwvgKD4xlhIgv9lYPTvE2vUs+w==,iv:e6b98ZnBqf7hh3SSKGdTl63OpQm1oK95lHXdwTiLft8=,tag:IS/lDgvJvSd7OmDLP+uG1g==,type:str]
radarr:
apikey: ENC[AES256_GCM,data:G141GW4PyS5pbAV39HcVscMw3s30txOgTZzWaL7o+ccZfnfDLv796O6xKXdqGZ8saLsveghLw9Z6a5luusHyQ3Q5ESL6W7SVeZVTuSqSC3i/4jl75FJxhnsgVsfrnYxzLGpKiw==,iv:sZl/XLh6y3WgSAn6nH3sFB6atBifZdghm+QsCNDbcjY=,tag:Tw+R80nrF0T0yDti0Uf+ig==,type:str]
sonarr:
apikey: ENC[AES256_GCM,data:s8bgDJ+LpIH1Mt3KSiIKB8LnxztOkHdc8J6+50o+HoDUAfIIsZkA2oX/m7UecrTSRi6ay8D9yjhe6ZwSNXhJh6wQqTS7gZWn8f6QfrfI+8DKdc9enh91suQxjkz8Q+wnKK0zBg==,iv:LmAe6v+6ItVnHB6gko6mhiGOuVBksBYP4dXfbxpAIPE=,tag:DZ8kwOwaWwWTGWEGu5S0Kg==,type:str]
lidarr:
apikey: ENC[AES256_GCM,data:I2eKaxidmxem7C7ukmyIfwASNqrkS4vEOiCcU5kSNY6DR0pXsYg0PBdgu8vzK6llbXODLdG5t55BordIWvVRJGAauo0FMvtp59NSNpza7cK68tdKGvNefD6bqhUIR06BY11niQ==,iv:48AD7cd17TlWY5yAagepLOIVwgxhD/d13Pnup6GsWDA=,tag:teOVtW8opE99hqAXQwvlrA==,type:str]
prowlarr:
apikey: ENC[AES256_GCM,data:pyZ2WGEs/PlIdhDsQq2TPGJbplkd5fLF0ZkBjITqIJlnAzYHb+rl+KOM4rHqQcI6yAJM8X1Y3ymGrD7vG7GiRxB7yoEG13SKhZIWOddTnxIhbkz81RfrL2fUJIydOaP6sS//9Q==,iv:Tr6MWoC6nC7rdVTOjT1T2itT+lVL4GnUiAr5/+IHAs0=,tag:keIJNuGeVht8+xSN3FnBGA==,type:str]
sops:
age:
- recipient: age19qfpf980tadguqq44zf6xwvjvl428dyrj46ha3n6aeqddwhtnuqqml7etq
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBwdDZyZkxvNU4zM3NHb2gx
ZlhLZk5JWUFGMWZGeUVHNkFFU1NtZlBQVVhjCmZGai9NdmdUeU5VcW9ROVZKTW5q
cmZaQ2JlaldaTWduQklocUZLT2FUcGcKLS0tIHlqVU0wdXJ0dTE4dlZSVEczd2Yv
RVFxVHFxbkVNbEZsaVcwYXZCdUc5R1kKQdAN6LEKmGLCSkKhNuEr0YK2zl9Aw1kK
6C25lN532mG55zIRectZda1Fmi1GMZ/2v3b5qz7x+TDMA9m/47OjmA==
-----END AGE ENCRYPTED FILE-----
- recipient: age1ewes0f5snqx3sh5ul6fa6qtxzhd25829v6mf5rx2wnheat6fefps5rme2x
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBoK3lqRDhEMXEvaUp3OWdV
eFlZSGpJcGs0RTdRbllWdmdZTzl3RTlDNlIwCm92R290NjNyK2NNbWpINTBhazNS
NTJYWEw0SGc1TUtrd0NZSmowakMvSlEKLS0tIG5uUEIrZGVORkRNVnBVOHgyMXZG
TTRWaHhpNWlkVDFmMFN4ZTNHMUxyNVkKV693pzTKRkZboQCMPr9IyMGSgxfuHXcb
Y6BNcp6Qg6PWtX5QI7wRkPNINAK1TEbRBba+b8h6gMmVU4DliQyFiQ==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-11-19T09:51:26Z"
mac: ENC[AES256_GCM,data:pMMkxHPochpI8si/oHhU7MHqC1JjNhMP7HCRNQQEkwBQI489xiC02t+qUwpmG4oIheqi8lEcZPpL4t9HzRN9sZImaI2LrJn3cHFojHzXzo7FPfvfUilZe1+JXLfm+wn+bflAEutIcfDiZc/MjiKOxRHwZy5Pr41Mj6uPIUr62zk=,iv:GwvMVgJ6m1DQcRZMVzshbuMK/Kx8vE8Ym83KbxuvYRg=,tag:wVSol9LDRzoFjQppB8J9gA==,type:str]
unencrypted_suffix: _unencrypted
version: 3.11.0