feat(winnie): OIDC Zitadel en PKCE via un secret sops oidc_env

- secret oidc_env (secrets/winnie.yml, chiffre pour tower) materialise par le oneshot winnie-oidc-secret dans /var/lib/winnie/oidc.env, requis par winnie-backend (EnvironmentFile non optionnel)
- PKCE : pas de client_secret cote backend
- .sops.yaml : creation_rule pour secrets/winnie.yml
This commit is contained in:
Hermes Agent
2026-10-17 16:56:17 -04:00
parent 5cab1712a7
commit aadebcc0fd
3 changed files with 44 additions and 5 deletions
+4
View File
@@ -92,3 +92,7 @@ creation_rules:
key_groups:
- age:
- *tower
- path_regex: secrets/winnie\.yml$
key_groups:
- age:
- *tower
+16
View File
@@ -0,0 +1,16 @@
oidc_env: ENC[AES256_GCM,data:CDXc17/GNkFKzPmQDy1X2TLA8Z2h0x4s6KsOl065uuPyNpcpUF94Xc1F9FJeJANnon6MyvgaRImyry6QNoMZs4UQ0efHHTDzFZQO2DN3prEA0g5KmLYTtgzXzuXYWNJvElS/EVuzW1ZFAhjMXF+YTddNk391w3b1MukYiF/yXWN2lzYubGK0/l4Uyh987J+FMC7XT3X0GjI1nrD0HhRs2c6RdUPfrE3rmzZPOsDxbga7hdEtJw52xg==,iv:8KPlv0T6/effSBwu3gWEneJyqjgsoHOlC8z2rrMC5xw=,tag:ukwggk+6AbRfOlvuCJtH8Q==,type:str]
sops:
age:
- enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAwYVpLZnUwR0dnYng1SXFC
cEtMQmE3ZHhpOXhHVjI4NjRRR0s0ektlYWtrCm96WEJCdWdRTmUrT1BMRU44dzFS
TE1uSE5WK0tLVnhKeTBpZGVzaUdRdHcKLS0tIDMxQzEzMmFJbnRqV2tzWURJUnhk
dXhOUnp1b05DekdHR2NiVG1qZWJpdlEK09D1epeoG5/NWUCZvoi4VcBMMl3cMZ6V
iqZlg5MPpLb0QZFQY2IJ0r3mkPlcpuV7NVvpJsvI17T8D2kI0kG0vw==
-----END AGE ENCRYPTED FILE-----
recipient: age1usm3v0ugducrzcwud60dda7xfnj49fdhecj7kcsfm7dzwzrzeyqq2jc2hm
lastmodified: "2026-10-12T03:16:55Z"
mac: ENC[AES256_GCM,data:UtMkqPwSnJTzPvtlrLv8JSfku9znNFtLYJIwFYjrBOxukyS0cCcE9sz92fiEYNZpO8TkxIp+Lccf80JoSZPtTdRvp6WBkBUMhO1MFVt0LQ0MIH4CzrF1MrrfyVn4QiAUrLhNVNJHivbCmIg3fqOcfYpnIdv8qjowrlhVig/lQkM=,iv:NAswLKpeo2CtOFG13AZk6MCfpUNjiGAYbCnO/SZlrAQ=,tag:Ab2Dt//WqhpO6/WrEEomsA==,type:str]
unencrypted_suffix: _unencrypted
version: 3.13.3
+24 -5
View File
@@ -15,12 +15,19 @@
# routes media sont indisponibles.
# L'infrastructure (user/groupe winnie, base PostgreSQL + schema, secret JWT)
# vient bien du projet via l'import ci-dessous.
{ pkgs, lib, ... }:
{ config, pkgs, lib, ... }:
let
backendBin = pkgs.runCommand "winnie-backend-pinned" { } ''
install -Dm755 ${/home/marc/git/winnie/backend/target/release/winnie-backend} $out/bin/winnie-backend
'';
in {
sops.secrets."oidc_env" = {
sopsFile = ../../secrets/winnie.yml;
key = "oidc_env";
mode = "0640";
group = "winnie";
};
imports = [ /home/marc/git/winnie/services/winnie/default.nix ];
services.winnie.manageGarage = false;
@@ -29,6 +36,18 @@ in {
# projet : sans Garage il echoue, on empeche son demarrage au boot.
systemd.services.winnie-bucket.wantedBy = lib.mkForce [ ];
# OIDC env file from sops (PKCE - no client_secret)
systemd.services.winnie-oidc-secret = {
description = "Generate winnie OIDC env file from sops";
wantedBy = [ "multi-user.target" ];
before = [ "winnie-backend.service" ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
ExecStart = "${pkgs.coreutils}/bin/cp ${config.sops.secrets."oidc_env".path} /var/lib/winnie/oidc.env";
};
};
# Front Svelte 5 (web statique, Vite) : `npm run build` dans
# /home/marc/git/winnie/app -> app/dist, copie dans le store a l'evaluation,
# servi en loopback ; Pangolin l'expose sur winnie.marcpartensky.com.
@@ -63,16 +82,16 @@ in {
"postgresql.service"
"winnie-schema.service"
"winnie-jwt-secret.service"
"winnie-oidc-secret.service"
"network.target"
];
requires = [ "postgresql.service" "winnie-jwt-secret.service" ];
requires = [ "postgresql.service" "winnie-jwt-secret.service" "winnie-oidc-secret.service" ];
serviceConfig = {
User = "winnie";
Group = "winnie";
WorkingDirectory = "/var/lib/winnie";
# jwt.env est obligatoire, s3.env optionnel : sans S3 les routes media
# renvoient une erreur, le reste de l'API fonctionne.
EnvironmentFile = [ "/var/lib/winnie/jwt.env" "-/var/lib/winnie/s3.env" ];
# jwt.env est obligatoire, s3.env optionnel, oidc.env pour PKCE/Zitadel
EnvironmentFile = [ "/var/lib/winnie/jwt.env" "-/var/lib/winnie/s3.env" "/var/lib/winnie/oidc.env" ];
Environment = [
"DATABASE_URL=postgresql://winnie@127.0.0.1/winnie"
"SERVER_HOST=127.0.0.1"