6 Commits

Author SHA1 Message Date
Danilo Reyes
e714a8d184 Update Keycloak configuration to use new secrets file and adjust environment variable references 2025-12-10 02:29:34 -06:00
Danilo Reyes
4d788d90ca linting 2025-12-10 02:29:25 -06:00
Danilo Reyes
303cd2db36 Add SOPS secrets for Keycloak database password and update configuration 2025-12-10 02:12:06 -06:00
Danilo Reyes
2cd3afe2b3 Rename Keycloak database configuration key from 'databaseName' to 'name' 2025-12-10 02:06:28 -06:00
Danilo Reyes
92492b6323 Update Keycloak database configuration to use 'databaseName' instead of 'database' 2025-12-10 02:04:17 -06:00
Danilo Reyes
6d5ae474c6 keycloak init 2025-12-10 02:00:12 -06:00
10 changed files with 128 additions and 46 deletions

39
TODO.md Normal file
View File

@@ -0,0 +1,39 @@
# Keycloak SSO Rollout (Server)
## Compatible services to cover (assume up-to-date versions)
- Gitea (OAuth2/OIDC)
- Nextcloud (Social Login app)
- Paperless-ngx (OIDC)
- Mealie (OIDC v1+)
- Jellyfin (OIDC plugin)
- Kavita (OIDC-capable builds)
- Readeck (OIDC-capable builds)
- Audiobookshelf (OIDC-capable builds)
- Matrix Synapse intentionally excluded (see below) but natively OIDC if needed
## Explicit exclusions (no SSO for now)
- Syncplay
- Matrix/Synapse
- Arr stack (sonarr, radarr, lidarr, prowlarr, bazarr)
- qbittorrent
- sabnzbd
- metube
- multi-scrobbler
- microbin
- ryot
- maloja
- plex
- atticd
## Phased rollout plan
1) Base identity
- Add Keycloak deployment/module and realm/client defaults.
2) Gateway/proxy auth
- Add oauth2-proxy (Keycloak provider) + nginx auth_request for non-OIDC apps (e.g., homepage-dashboard, stash).
3) Native OIDC wiring
- Configure native OIDC services (Gitea, Nextcloud, Paperless, Mealie, Jellyfin/Kavita/Readeck/Audiobookshelf) with Keycloak clients.
4) Per-service rollout
- Enable per app in priority order; document client IDs/secrets and callback URLs.
5) Verification
- Smoke-test login flows and cache any needed public keys/metadata.

View File

@@ -38,7 +38,7 @@ _final: prev: {
waybar = prev.waybar.overrideAttrs (old: {
mesonFlags = old.mesonFlags ++ [ "-Dexperimental=true" ];
});
qbittorrent = prev.qbittorrent.overrideAttrs (old: rec {
qbittorrent = prev.qbittorrent.overrideAttrs (_old: rec {
version = "5.1.3";
src = prev.fetchFromGitHub {
owner = "qbittorrent";

View File

@@ -1,5 +1,4 @@
{ ... }:
{
_: {
users.users = {
sonarr = {
uid = 274;

66
flake.lock generated
View File

@@ -216,11 +216,11 @@
"nixpkgs-lib": "nixpkgs-lib"
},
"locked": {
"lastModified": 1765495779,
"narHash": "sha256-MhA7wmo/7uogLxiewwRRmIax70g6q1U/YemqTGoFHlM=",
"lastModified": 1763759067,
"narHash": "sha256-LlLt2Jo/gMNYAwOgdRQBrsRoOz7BPRkzvNaI/fzXi2Q=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "5635c32d666a59ec9a55cab87e898889869f7b71",
"rev": "2cccadc7357c0ba201788ae99c4dfa90728ef5e0",
"type": "github"
},
"original": {
@@ -234,11 +234,11 @@
"nixpkgs-lib": "nixpkgs-lib_2"
},
"locked": {
"lastModified": 1765495779,
"narHash": "sha256-MhA7wmo/7uogLxiewwRRmIax70g6q1U/YemqTGoFHlM=",
"lastModified": 1763759067,
"narHash": "sha256-LlLt2Jo/gMNYAwOgdRQBrsRoOz7BPRkzvNaI/fzXi2Q=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "5635c32d666a59ec9a55cab87e898889869f7b71",
"rev": "2cccadc7357c0ba201788ae99c4dfa90728ef5e0",
"type": "github"
},
"original": {
@@ -404,11 +404,11 @@
]
},
"locked": {
"lastModified": 1765605144,
"narHash": "sha256-RM2xs+1HdHxesjOelxoA3eSvXShC8pmBvtyTke4Ango=",
"lastModified": 1765170903,
"narHash": "sha256-O8VTGey1xxiRW+Fpb+Ps9zU7ShmxUA1a7cMTcENCVNg=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "90b62096f099b73043a747348c11dbfcfbdea949",
"rev": "20561be440a11ec57a89715480717baf19fe6343",
"type": "github"
},
"original": {
@@ -495,11 +495,11 @@
"xdph": "xdph"
},
"locked": {
"lastModified": 1765741609,
"narHash": "sha256-mBDW/2NPaxXw68ledipQYSL6GGU+/CCsObondH22+no=",
"lastModified": 1765141510,
"narHash": "sha256-IjlKl72fJ40zZFiag9VTF37249jHCRHAE4RP7bI0OXA=",
"owner": "hyprwm",
"repo": "Hyprland",
"rev": "7ccc57eb7cacded5e7a8835b705bba48963d3cb3",
"rev": "a5b7c91329313503e8864761f24ef43fb630f35c",
"type": "github"
},
"original": {
@@ -788,11 +788,11 @@
]
},
"locked": {
"lastModified": 1765764448,
"narHash": "sha256-GHM40ltWiRnGYvhcLRaNWXZoyGUOL4FgB0U7muHjn9s=",
"lastModified": 1765073338,
"narHash": "sha256-UGkNtTs0E1SzskcUkkkWoh3vfZwPiHrk0SMRoQL86oE=",
"owner": "fufexan",
"repo": "nix-gaming",
"rev": "7f4e526e0a1badaaea208a0180199d1d26596fa3",
"rev": "7480cfb8bba3e352edf2c9334ff4b7c3ac84eb87",
"type": "github"
},
"original": {
@@ -903,11 +903,11 @@
},
"nixpkgs-small": {
"locked": {
"lastModified": 1765750102,
"narHash": "sha256-0VK0PKOmryh4V2aBakcTpgshQZ7qRsRRwDm7Eqhs1ZI=",
"lastModified": 1765178948,
"narHash": "sha256-Kb3mIrj4xLg2LeMvok0tpiGPis1VnrNJO0l4kW+0xmc=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "8e8751ad07080fe4d5737a0430cd5c1d3ba5c005",
"rev": "f376a52d0dc796aec60b5606a2676240ff1565b9",
"type": "github"
},
"original": {
@@ -919,11 +919,11 @@
},
"nixpkgs-unstable": {
"locked": {
"lastModified": 1765472234,
"narHash": "sha256-9VvC20PJPsleGMewwcWYKGzDIyjckEz8uWmT0vCDYK0=",
"lastModified": 1764950072,
"narHash": "sha256-BmPWzogsG2GsXZtlT+MTcAWeDK5hkbGRZTeZNW42fwA=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "2fbfb1d73d239d2402a8fe03963e37aab15abe8b",
"rev": "f61125a668a320878494449750330ca58b78c557",
"type": "github"
},
"original": {
@@ -935,11 +935,11 @@
},
"nixpkgs_2": {
"locked": {
"lastModified": 1765762245,
"narHash": "sha256-3iXM/zTqEskWtmZs3gqNiVtRTsEjYAedIaLL0mSBsrk=",
"lastModified": 1764983851,
"narHash": "sha256-y7RPKl/jJ/KAP/VKLMghMgXTlvNIJMHKskl8/Uuar7o=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "c8cfcd6ccd422e41cc631a0b73ed4d5a925c393d",
"rev": "d9bc5c7dceb30d8d6fafa10aeb6aa8a48c218454",
"type": "github"
},
"original": {
@@ -978,11 +978,11 @@
]
},
"locked": {
"lastModified": 1765790735,
"narHash": "sha256-KZqns0oFKXtBpmhk7QIsoMQLFepTGVt+2adnTMSDCus=",
"lastModified": 1765185832,
"narHash": "sha256-z8duEjztk7g+Zm4DbZfAAYMAqb+ooaNPuOBhpvx7TiU=",
"owner": "nix-community",
"repo": "nur",
"rev": "88f0edd08dde26877c8e407ccdb2ed6d1449a7a5",
"rev": "7be17d29475559cb8d7e35b5ed185b5a8ed8d7b6",
"type": "github"
},
"original": {
@@ -1085,11 +1085,11 @@
]
},
"locked": {
"lastModified": 1765684837,
"narHash": "sha256-fJCnsYcpQxxy/wit9EBOK33c0Z9U4D3Tvo3gf2mvHos=",
"lastModified": 1765079830,
"narHash": "sha256-i9GMbBLkeZ7MVvy7+aAuErXkBkdRylHofrAjtpUPKt8=",
"owner": "Mic92",
"repo": "sops-nix",
"rev": "94d8af61d8a603d33d1ed3500a33fcf35ae7d3bc",
"rev": "aeb517262102f13683d7a191c7e496b34df8d24c",
"type": "github"
},
"original": {
@@ -1119,11 +1119,11 @@
"tinted-zed": "tinted-zed"
},
"locked": {
"lastModified": 1765478257,
"narHash": "sha256-GMCAQgs+h4aHhLP3LF6JxI5uNg+fLPlRhHwRrJJ+3+Y=",
"lastModified": 1765065096,
"narHash": "sha256-abrrONk8vzRtY6fHEkjZOyRJpKHjPlFqMBE0+/DxfAU=",
"owner": "danth",
"repo": "stylix",
"rev": "a7fb3944d1fb4daa073ba82e1a9d34b5f05adb9f",
"rev": "84d9d55885d463d461234f3aac07b2389a2577d8",
"type": "github"
},
"original": {

View File

@@ -0,0 +1,46 @@
{
lib,
config,
inputs,
...
}:
let
setup = import ../factories/mkserver.nix { inherit lib config; };
cfg = config.my.servers.keycloak;
in
{
options.my.servers.keycloak = setup.mkOptions "keycloak" "auth" 8090;
config = lib.mkIf (cfg.enable && config.my.secureHost) {
sops.secrets.keycloak = {
sopsFile = ../../secrets/env.yaml;
owner = "keycloak";
group = "keycloak";
};
sops.secrets.postgres-password = {
sopsFile = ../../secrets/secrets.yaml;
owner = "keycloak";
group = "keycloak";
};
services.keycloak = {
inherit (cfg) enable;
database = {
type = "postgresql";
host = "localhost";
createLocally = false;
username = "keycloak";
name = "keycloak";
passwordFile = config.sops.secrets."keycloak/db_password".path;
};
settings.hostname = cfg.host;
"hostname-strict" = true;
"hostname-strict-https" = false;
"http-enabled" = true;
"http-port" = cfg.port;
"proxy" = "edge";
};
systemd.services.keycloak.serviceConfig.EnvironmentFile = config.sops.secrets.keycloak.path;
services.nginx.virtualHosts.${cfg.host} = lib.mkIf (cfg.enableProxy && config.my.enableProxy) (
inputs.self.lib.proxyReverseFix cfg
);
};
}

View File

@@ -40,6 +40,7 @@ let
"sonarqube"
"gitea"
"atticd"
"keycloak"
];
in
{

View File

@@ -7,10 +7,6 @@
}:
let
inherit (inputs) qbit_manage;
pkgsU = import inputs.nixpkgs-unstable {
system = "x86_64-linux";
config.allowUnfree = true;
};
vuetorrent = pkgs.fetchzip {
url = "https://github.com/VueTorrent/VueTorrent/releases/download/v2.31.0/vuetorrent.zip";
sha256 = "sha256-kVDnDoCoJlY2Ew71lEMeE67kNOrKTJEMqNj2OfP01qw=";

View File

@@ -1,7 +1,6 @@
{
config,
lib,
inputs,
...
}:
{

View File

@@ -11,6 +11,7 @@ cloudflare-api: ENC[AES256_GCM,data:iNUMlY8rz5yHVitpK4HGaFSK7j+c8Pm7rOQMOQGmSJ3a
synapse: ENC[AES256_GCM,data:IR0pFwQBEM4O8mzzYXrPe2FjulSUGuitzLDLms2uovr6gEU82mCkRO/UCQOybNm03iOQeXX0Whz739kpYSGSInEyx69BNG/etH+bMu+GbYeMdrTEyXHSa7kcH4Ug,iv:Vn2ILYXnCj+Op/E2kWoxV+2ZtlxYJxO6XK3Ql41KW6w=,tag:9wogJFLlmfM5PRgPdwFlcw==,type:str]
readeck: ENC[AES256_GCM,data:TsIkHLji37dDHQRt78SquBhoSREHDgvgbc6+M1k2MLrgMGJ/Ejfy5AZXCIp/Qj5sXDzKP4j6Y6xFvGLswCqe02XjqGCpX13gZVCFPuKr8Nq051Xg,iv:Rc/pjYP+Vd/DvLCYsfJjDrnAlAiUlZOcNeeYzE6O3UY=,tag:OvR+CXMmrUFbsrHvduhnjA==,type:str]
lidarr-mb-gap: ENC[AES256_GCM,data:bNzD9Nf9BWAPkm0Yk0J4MJbmo908QX9VsD+40Rngnfec9nzH4vZ2DrelxRllgT1kgnXMQzvoSgNhBwkDN4fgX73hz1FjkytTwahlO0wcY6R+tw4aokh0QYy0TVx5pZ4u1FEQOAp3IMgBsP8HOqaL/NEsEo3yb0K9iC3AfFihkLDJmVh26Pg=,iv:go0qS7/BcfcAMPkAdGWCoL61gNqBG5lWDev++y9DJ/I=,tag:LgtEyTZH8NfhfrKTcAigZw==,type:str]
keycloak: ENC[AES256_GCM,data:BmwZxuJaOB8F7zmBNAf42lkw36s5TepimtdyT2xjdGVyuHgRHbTZqeVen7/0II39qrJjko4agZJgToIZ1uhaC/gpGSoHZlib3rJozPCqmBc42nO6SOtpIO8=,iv:kPModK85937/liNk6iLIRiQ/G5yB7S7h24ZzPb8A1zo=,tag:lWvDQAHVRiBz8XZUoADKvw==,type:str]
sops:
age:
- recipient: age1lufn6t35gs4wgevyr2gud4eec7lvkn7pgnnv4tja64ww3hef7gqq8fas37
@@ -49,7 +50,7 @@ sops:
QXRUYWtGcWZCVW11U3VYRktuUjlCbDgKsTK4WhUza/JuoDTU3uATa6fq/8eYzxtb
9BUK1ddzx9Mghea9XBMS17YGtGmW800OsLBomb3SINnOFvejcnKf8Q==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-11-11T23:18:34Z"
mac: ENC[AES256_GCM,data:i3U364pjZB5Y61Wf7ETbXhNWyfH1gw0oyPcNyT+nCIJmePh8JWiP9hnHmZfLS1BKkI2powQdezbz9R0XDvU7g2SkV8EsWmn/h3rFwbopUZbeRQ2SCoX7LGFez74l1oTPQjL8zWJVdrUtfAFgbZKSEWuz7rsDieKBVhIJwWaeePY=,iv:N4z+X3eD6jH+zQfY24qec+U6wkfhLGPm4MzY8T2Km/A=,tag:yluW5YSKMZ4Kk+wcXbkj8Q==,type:str]
lastmodified: "2025-12-10T08:26:05Z"
mac: ENC[AES256_GCM,data:rUc4vtnyqK7U6Zvx+BCVMT6yqhCBBsKY/Cfp13XzPzKqa/8sRI7PSEUBY+RSH0t2ShCUep+dWu0ghgFq9L2olJkwuOQ3MHPyIRw3ldwbuYwoRiCtvTkyvtZMaJouy/QrD+mHBr8a6UZRIl/6gnIxcqktzXUeKbCtJcSFj5ScHIg=,iv:j/mtZ3RJwMilVF5AFFUjo4Jm5IDlRIzZx1MdjOE+4gc=,tag:w4Niu71q3Lutu32VdFruHw==,type:str]
unencrypted_suffix: _unencrypted
version: 3.11.0

View File

@@ -14,6 +14,7 @@ stash:
unpackerr:
sonarr-api: ENC[AES256_GCM,data:74/aSs7Q2tcDh9hPGm88h2hIneOcJ+P9HaCqoeuL6FQ=,iv:1AOpCii7ED1EyOFNCzvgRp5tR2ic1U6oRi7yg0hUcLk=,tag:k1miUivDQPxRgBWhXi9f+w==,type:str]
radarr-api: ENC[AES256_GCM,data:bZiJNk/ewREIBss+z4daVwL1UyI4rt8GxVmC/bpTNvc=,iv:li2kMzOgdWtLLr4l244P082Z0jwDB2aEC6iRYt3o/HY=,tag:mi9SY/pT2qTIzR/ngp8bGg==,type:str]
postgres-password: ENC[AES256_GCM,data:V0g4T1cLUFnTN94zZZR83/KVJFUDGEWVEn6nyijnver4QCELUFkNr99s9g==,iv:1ymHA0JaVC2/aHdg4TmJmuKOG8JGZRRvynrgQIGdTss=,tag:xsCVpc+HBaNeswYvzo0PaA==,type:str]
sops:
age:
- recipient: age1lufn6t35gs4wgevyr2gud4eec7lvkn7pgnnv4tja64ww3hef7gqq8fas37
@@ -52,7 +53,7 @@ sops:
RmRyZldlMjUwMEdUUEpDS2JSa2tDTTAKp/pT+0cNnCuKVL+Z0fEMiw1PL9PB/nSM
QWVTo0Mt8Y6X0Xt0EAi9G5AYxADZ/mmEWPxB7RFgVAiMKtor5Gy1zw==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-10-02T20:02:38Z"
mac: ENC[AES256_GCM,data:DnbkeF+evVTMhYTg3OU528cRQ+jBiUl7Q7JZxyGRL6USjB2OdIRxqnnCH8L36K2hSAIkKQ/kojyJs+8Pgkx5uD/qsCbGlNT9pSBU1qPdSBxqJsVPxHZmkuf/QxGtE4pgV/50xJMrVyzAetWPZuxcYVfWAPszxDZcR5XDuD+Yjk4=,iv:i2Vt6nv6etIgaaoxsbVlxEnIhIx4adOQZFeyGM/4Saw=,tag:jugPmHU78lap7Hy7RJd9pg==,type:str]
lastmodified: "2025-12-10T08:27:18Z"
mac: ENC[AES256_GCM,data:Q9mdmt8HI+yzOu3IiEbxtZ7jg/2+6EHtHyRAJndrlwKCbTM59Nqza3YJ5+EpOrQw+ydYhiG2gXZ8qU/f70s0XdDUlpo/EgOkYoLDCgqFQ8TQu7R7Fwjv9Lw27IomGyCtTouWLfIQC1lZV1I1Df61P8HiPzUmV3pEr87o7qD0f/w=,iv:Cst3qxD65ijqmB+ftLNdpRGmRjSjqW7MrSskd33Ght8=,tag:+zgclBJw/PYTQYzPMAFQUA==,type:str]
unencrypted_suffix: _unencrypted
version: 3.10.2
version: 3.11.0