5 Commits

Author SHA1 Message Date
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
NixOS Builder Bot
ac66f35d93 Weekly flake update: 2025-12-08 10:04 UTC 2025-12-08 04:04:46 -06:00
4 changed files with 133 additions and 42 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.

84
flake.lock generated
View File

@@ -20,11 +20,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1764370710, "lastModified": 1764714051,
"narHash": "sha256-7iZklFmziy6Vn5ZFy9mvTSuFopp3kJNuPxL5QAvtmFQ=", "narHash": "sha256-AjcMlM3UoavFoLzr0YrcvsIxALShjyvwe+o7ikibpCM=",
"owner": "hyprwm", "owner": "hyprwm",
"repo": "aquamarine", "repo": "aquamarine",
"rev": "561ae7fbe1ca15dfd908262ec815bf21a13eef63", "rev": "a43bedcceced5c21ad36578ed823e6099af78214",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -404,11 +404,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1764866045, "lastModified": 1765170903,
"narHash": "sha256-0GsEtXV9OquDQ1VclQfP16cU5VZh7NEVIOjSH4UaJuM=", "narHash": "sha256-O8VTGey1xxiRW+Fpb+Ps9zU7ShmxUA1a7cMTcENCVNg=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "f63d0fe9d81d36e5fc95497217a72e02b8b7bcab", "rev": "20561be440a11ec57a89715480717baf19fe6343",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -495,11 +495,11 @@
"xdph": "xdph" "xdph": "xdph"
}, },
"locked": { "locked": {
"lastModified": 1764880933, "lastModified": 1765141510,
"narHash": "sha256-0EGExxEEIuDEcd+jM1hnvp69XW8bPQTKWLP7Nj/KSCU=", "narHash": "sha256-IjlKl72fJ40zZFiag9VTF37249jHCRHAE4RP7bI0OXA=",
"owner": "hyprwm", "owner": "hyprwm",
"repo": "Hyprland", "repo": "Hyprland",
"rev": "52b3c8cbc699aa949f4f1887ca829898055ce4ad", "rev": "a5b7c91329313503e8864761f24ef43fb630f35c",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -541,11 +541,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1764616927, "lastModified": 1764812575,
"narHash": "sha256-wRT0MKkpPo11ijSX3KeMN+EQWnpSeUlRtyF3pFLtlRU=", "narHash": "sha256-1bK1yGgaR82vajUrt6z+BSljQvFn91D74WJ/vJsydtE=",
"owner": "hyprwm", "owner": "hyprwm",
"repo": "hyprland-guiutils", "repo": "hyprland-guiutils",
"rev": "25cedbfdc5b3ea391d8307c9a5bea315e5df3c52", "rev": "fd321368a40c782cfa299991e5584ca338e36ebe",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -672,11 +672,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1764637132, "lastModified": 1764962281,
"narHash": "sha256-vSyiKCzSY48kA3v39GFu6qgRfigjKCU/9k1KTK475gg=", "narHash": "sha256-rGbEMhTTyTzw4iyz45lch5kXseqnqcEpmrHdy+zHsfo=",
"owner": "hyprwm", "owner": "hyprwm",
"repo": "hyprutils", "repo": "hyprutils",
"rev": "2f2413801beee37303913fc3c964bbe92252a963", "rev": "fe686486ac867a1a24f99c753bb40ffed338e4b0",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -726,11 +726,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1764773840, "lastModified": 1764872015,
"narHash": "sha256-9UcCdwe7vPgEcJJ64JseBQL0ZJZoxp/2iFuvfRI+9zk=", "narHash": "sha256-INI9AVrQG5nJZFvGPSiUZ9FEUZJLfGdsqjF1QSak7Gc=",
"owner": "hyprwm", "owner": "hyprwm",
"repo": "hyprwire", "repo": "hyprwire",
"rev": "3f1997d6aeced318fb141810fded2255da811293", "rev": "7997451dcaab7b9d9d442f18985d514ec5891608",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -788,11 +788,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1764900011, "lastModified": 1765073338,
"narHash": "sha256-iG5HqIzZ12qzTi3xCwBinw/PR0xNlJNXLLQyV2En1OY=", "narHash": "sha256-UGkNtTs0E1SzskcUkkkWoh3vfZwPiHrk0SMRoQL86oE=",
"owner": "fufexan", "owner": "fufexan",
"repo": "nix-gaming", "repo": "nix-gaming",
"rev": "e1829ce2d33b1e289b3ecca7530dee84da8d9e85", "rev": "7480cfb8bba3e352edf2c9334ff4b7c3ac84eb87",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -903,11 +903,11 @@
}, },
"nixpkgs-small": { "nixpkgs-small": {
"locked": { "locked": {
"lastModified": 1764905945, "lastModified": 1765178948,
"narHash": "sha256-NtlwimMawcO5wSLWw/BQPOdsL1Ew98/PgE95Evf0UzQ=", "narHash": "sha256-Kb3mIrj4xLg2LeMvok0tpiGPis1VnrNJO0l4kW+0xmc=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "bb835c14c21853c531131dcaeddd16b9ffe2d0b3", "rev": "f376a52d0dc796aec60b5606a2676240ff1565b9",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -919,11 +919,11 @@
}, },
"nixpkgs-unstable": { "nixpkgs-unstable": {
"locked": { "locked": {
"lastModified": 1764667669, "lastModified": 1764950072,
"narHash": "sha256-7WUCZfmqLAssbDqwg9cUDAXrSoXN79eEEq17qhTNM/Y=", "narHash": "sha256-BmPWzogsG2GsXZtlT+MTcAWeDK5hkbGRZTeZNW42fwA=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "418468ac9527e799809c900eda37cbff999199b6", "rev": "f61125a668a320878494449750330ca58b78c557",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -935,11 +935,11 @@
}, },
"nixpkgs_2": { "nixpkgs_2": {
"locked": { "locked": {
"lastModified": 1764831616, "lastModified": 1764983851,
"narHash": "sha256-OtzF5wBvO0jgW1WW1rQU9cMGx7zuvkF7CAVJ1ypzkxA=", "narHash": "sha256-y7RPKl/jJ/KAP/VKLMghMgXTlvNIJMHKskl8/Uuar7o=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "c97c47f2bac4fa59e2cbdeba289686ae615f8ed4", "rev": "d9bc5c7dceb30d8d6fafa10aeb6aa8a48c218454",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -978,11 +978,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1764926586, "lastModified": 1765185832,
"narHash": "sha256-CoTxfBQIL1jE1Ea2iWWvKX4oDjG7LozprKSrOHJ55xI=", "narHash": "sha256-z8duEjztk7g+Zm4DbZfAAYMAqb+ooaNPuOBhpvx7TiU=",
"owner": "nix-community", "owner": "nix-community",
"repo": "nur", "repo": "nur",
"rev": "18265766af189ce24259f2256a197686f627b860", "rev": "7be17d29475559cb8d7e35b5ed185b5a8ed8d7b6",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -1026,11 +1026,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1763988335, "lastModified": 1765016596,
"narHash": "sha256-QlcnByMc8KBjpU37rbq5iP7Cp97HvjRP0ucfdh+M4Qc=", "narHash": "sha256-rhSqPNxDVow7OQKi4qS5H8Au0P4S3AYbawBSmJNUtBQ=",
"owner": "cachix", "owner": "cachix",
"repo": "git-hooks.nix", "repo": "git-hooks.nix",
"rev": "50b9238891e388c9fdc6a5c49e49c42533a1b5ce", "rev": "548fc44fca28a5e81c5d6b846e555e6b9c2a5a3c",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -1085,11 +1085,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1764483358, "lastModified": 1765079830,
"narHash": "sha256-EyyvCzXoHrbL467YSsQBTWWg4sR96MH1sPpKoSOelB4=", "narHash": "sha256-i9GMbBLkeZ7MVvy7+aAuErXkBkdRylHofrAjtpUPKt8=",
"owner": "Mic92", "owner": "Mic92",
"repo": "sops-nix", "repo": "sops-nix",
"rev": "5aca6ff67264321d47856a2ed183729271107c9c", "rev": "aeb517262102f13683d7a191c7e496b34df8d24c",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -1119,11 +1119,11 @@
"tinted-zed": "tinted-zed" "tinted-zed": "tinted-zed"
}, },
"locked": { "locked": {
"lastModified": 1764836393, "lastModified": 1765065096,
"narHash": "sha256-J2jgYyXiXctr91MSuBQ6dwB1YaC7DpzKp+Rkj6pqS8o=", "narHash": "sha256-abrrONk8vzRtY6fHEkjZOyRJpKHjPlFqMBE0+/DxfAU=",
"owner": "danth", "owner": "danth",
"repo": "stylix", "repo": "stylix",
"rev": "6f3b50c8fa9c468fc787e211b700e46592bf9d56", "rev": "84d9d55885d463d461234f3aac07b2389a2577d8",
"type": "github" "type": "github"
}, },
"original": { "original": {

View File

@@ -0,0 +1,51 @@
{
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/admin_password" = {
sopsFile = ../../secrets/secrets.yaml;
owner = "keycloak";
group = "keycloak";
};
sops.secrets."keycloak/db_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/admin_password".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" "sonarqube"
"gitea" "gitea"
"atticd" "atticd"
"keycloak"
]; ];
in in
{ {