[habits] Adds beaver habits. [oidc] Sets up OIDC auth forwarding, it works, but not sure which header.

This commit is contained in:
2025-07-25 12:22:33 -07:00
parent b3c6e951ee
commit 19d8c5c097
7 changed files with 59 additions and 5 deletions

View File

@@ -12,7 +12,7 @@ offen:
secret: ENC[AES256_GCM,data:sH2siPc/QH1O2M7ZlJwqhqlHRIeLIG9r,iv:eD29ALx2ji0rm1t9j6RulTZT3f6VLK7dxpPOze3qDKA=,tag:zqJTgT2UeA/ecBS4VremUw==,type:str] secret: ENC[AES256_GCM,data:sH2siPc/QH1O2M7ZlJwqhqlHRIeLIG9r,iv:eD29ALx2ji0rm1t9j6RulTZT3f6VLK7dxpPOze3qDKA=,tag:zqJTgT2UeA/ecBS4VremUw==,type:str]
smtp-token: ENC[AES256_GCM,data:ZTfe65g3JykPvG2l0AN8UQ==,iv:GTruGo/vcP+imfJyqB3NX9ic8dz5jvTEh6SF+OeqMDM=,tag:kgwd59pG/WUt8OAaVzi39Q==,type:str] smtp-token: ENC[AES256_GCM,data:ZTfe65g3JykPvG2l0AN8UQ==,iv:GTruGo/vcP+imfJyqB3NX9ic8dz5jvTEh6SF+OeqMDM=,tag:kgwd59pG/WUt8OAaVzi39Q==,type:str]
traefik: traefik:
oauth2-client-secret: ENC[AES256_GCM,data:gV9/yBCqWPcNG/m7S0PRE3TduKzqRD1ii3RGGjNprQM=,iv:jmwBYWhPQJMZWHZine6Eb+7fdW44QOvkK52LQ6ISK4s=,tag:yNWRJ1IdPcxn6e0DXQe7Cw==,type:str] oauth2-client-secret: ENC[AES256_GCM,data:p7/6OsN2ytBj8mQiK0YL7J6NYLtMHOXIIs/6+bIDpsU=,iv:k6jLZifJEFLYKSFMkyn/kA7iBE+EFB8O/3/3fyTh1SY=,tag:6s49O2+tdlZoXyAGEamuMQ==,type:str]
oauth2-plugin-secret: ENC[AES256_GCM,data:sArqwKHAdW35o5kD7DGfXSYCXFUXqvKQdoVnXutsNLw=,iv:qWf597QS3BqkVQkeAb99HbpDB0kUhdD+qKdpUPZEB0o=,tag:vXnb93npaklItWkMZ+/M9Q==,type:str] oauth2-plugin-secret: ENC[AES256_GCM,data:sArqwKHAdW35o5kD7DGfXSYCXFUXqvKQdoVnXutsNLw=,iv:qWf597QS3BqkVQkeAb99HbpDB0kUhdD+qKdpUPZEB0o=,tag:vXnb93npaklItWkMZ+/M9Q==,type:str]
deploy-key: deploy-key:
mcp: ENC[AES256_GCM,data:eQcX8xdz5qZ6nU8ISOvZo+ZtP4Z/ePd+/ZZReX1BKvTUqGQPPFxConbLMwFzvzpD6xAUbA1MLkcR/bT98QbNx6LJYlhbofuDUg2DI79RB0fcrAcj/wUV0YPhmgofUdYYDaimH5A2PSvtmKfB3CtKKuA5HNeLymoXeLEpFzbckkGhzPee/CHiUmxayogp6za6btsDJsiT8hdHbrzyD2S6fhMJrzX+PlRzT32M/6eaFuFWE8EUO1gbkRlNfKPXw/EM2GXWJfR4qXfN2YKIKigqrtlAAoxnrUbp5EBrn/hGHS2ZYZXeRUFr3avFjcI0bLX423PWRHAylfQCPxgYVEtbcRv11CAFmq4rfFl0ZdvnAKbTLNmWcrQNijBATZPaAdQzgKPDHs8pwPUFR9Tcg8pZNbzw0mK9kPolniAOL2PBKUHv6LP/uEkB1E6Pxc7yms0kGpeJyo7hrFVOiVAckCey+SI9dpbJMSB3md070I1xk6Ik7PywrWh2QDeUtOU1U28UkYgnJ/9MJelWsNlUX9SR,iv:oCNeanaV/7UZ3dhmq4ZmJUZ5hb61AnHpHCfskM2Jsm8=,tag:F2uJKN5beM/rfiBMSyUP7w==,type:str] mcp: ENC[AES256_GCM,data:eQcX8xdz5qZ6nU8ISOvZo+ZtP4Z/ePd+/ZZReX1BKvTUqGQPPFxConbLMwFzvzpD6xAUbA1MLkcR/bT98QbNx6LJYlhbofuDUg2DI79RB0fcrAcj/wUV0YPhmgofUdYYDaimH5A2PSvtmKfB3CtKKuA5HNeLymoXeLEpFzbckkGhzPee/CHiUmxayogp6za6btsDJsiT8hdHbrzyD2S6fhMJrzX+PlRzT32M/6eaFuFWE8EUO1gbkRlNfKPXw/EM2GXWJfR4qXfN2YKIKigqrtlAAoxnrUbp5EBrn/hGHS2ZYZXeRUFr3avFjcI0bLX423PWRHAylfQCPxgYVEtbcRv11CAFmq4rfFl0ZdvnAKbTLNmWcrQNijBATZPaAdQzgKPDHs8pwPUFR9Tcg8pZNbzw0mK9kPolniAOL2PBKUHv6LP/uEkB1E6Pxc7yms0kGpeJyo7hrFVOiVAckCey+SI9dpbJMSB3md070I1xk6Ik7PywrWh2QDeUtOU1U28UkYgnJ/9MJelWsNlUX9SR,iv:oCNeanaV/7UZ3dhmq4ZmJUZ5hb61AnHpHCfskM2Jsm8=,tag:F2uJKN5beM/rfiBMSyUP7w==,type:str]
@@ -41,7 +41,7 @@ sops:
by9aNFY4dXNxaWxnTXFTQS9reHhuQWMKh5rZ93nFtBV9EpFVRp+E+GXZ6xzVy2Jw by9aNFY4dXNxaWxnTXFTQS9reHhuQWMKh5rZ93nFtBV9EpFVRp+E+GXZ6xzVy2Jw
vFh4deGcAb60q4odSaeWfk1Dr7L9Ua69oK9omjbCNUt+P7Kwlfca7Q== vFh4deGcAb60q4odSaeWfk1Dr7L9Ua69oK9omjbCNUt+P7Kwlfca7Q==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
lastmodified: "2025-06-25T22:38:40Z" lastmodified: "2025-07-25T19:04:18Z"
mac: ENC[AES256_GCM,data:2/rVuLHtxtiAW5H80vPYc+2QOFSA5nQRONOxbIPeg/KNgre0imaykFPFVXKidvod/QuHnoszKS6Js/HCXLKlesOjxVN4r7lLlGpOE9qkceaDOa5Fv/pwIWjYwovZEsjuJz2Uq7ouB0lBhuTinvP0uNV/LphAZDymeSv+FUkt6hU=,iv:Z48SytML7WgusUMzgWmQkWHwg5WJITj591+MFTWVwag=,tag:ENJWrbmjZMMZ4P9F0Im9bQ==,type:str] mac: ENC[AES256_GCM,data:86YT/B9fCgrEoalBQnanYXb0CYipDQoa/ZmIrMpbJr5SS7xyOAYXN4d7mA7dPhV2mjYbMtE2KRdVKCzvzdWLEysz9EZEuTR+Ea/2euxn/oRi7emjGTUgGZa9QMrkONgn/3/oJY4vMRqBPeh29b2akVlrvP/b2ai7dZpDnTICNqI=,iv:22tlDd3VzMrgKsZiZE9mPMS/nuYUd/nzyDkNd6r7CMc=,tag:Ej3joMSm9uDFFY7TK0DyOA==,type:str]
unencrypted_suffix: _unencrypted unencrypted_suffix: _unencrypted
version: 3.10.2 version: 3.10.2

View File

@@ -114,6 +114,7 @@
"traefik.enable" = "true"; "traefik.enable" = "true";
"traefik.http.routers.${serviceName}.rule" = "${routerRule}"; "traefik.http.routers.${serviceName}.rule" = "${routerRule}";
"traefik.http.routers.${serviceName}.service" = "${serviceName}"; "traefik.http.routers.${serviceName}.service" = "${serviceName}";
"traefik.http.routers.${serviceName}.entrypoints" = "web,websecure";
"traefik.http.services.${serviceName}.loadbalancer.server.port" = "${toString port}"; "traefik.http.services.${serviceName}.loadbalancer.server.port" = "${toString port}";
} }
// oauthLabels // oauthLabels

View File

@@ -0,0 +1,18 @@
{ ... }:
{
virtualisation.web-containers.containers.beaver-habits = {
hostname = "habits";
domain = "havenisms.com";
image = "daya0576/beaverhabits:latest";
port = 8080;
oauthProxy = true;
volumes = [
"/tank/beaver-habits:/app/.user/"
];
environment = {
HABITS_STORAGE = "DATABASE";
INDEX_HABIT_DATE_COLUMNS = "7";
TRUSTED_EMAIL_HEADER = "X-Oidc-Email";
};
};
}

View File

@@ -1,6 +1,8 @@
{ ... }: { ... }:
{ {
imports = [ imports = [
./beaver-habits.nix
./chat.nix ./chat.nix
./storyden.nix
]; ];
} }

View File

@@ -0,0 +1,17 @@
{ config, ... }:
let
inherit (import ../lib.nix config) havenisms;
in
{
virtualisation.web-containers.containers.storyden = {
image = "ghcr.io/southclaws/storyden";
port = 8000;
hostname = "storyden";
domain = havenisms;
environment = {
PUBLIC_WEB_ADDRESS = "https://storyden.${havenisms}";
PUBLIC_API_ADDRESS = "https://storyden.${havenisms}";
};
};
}

View File

@@ -25,14 +25,28 @@ in
oidc-auth: oidc-auth:
plugin: plugin:
traefik-oidc-auth: traefik-oidc-auth:
LogLevel: DEBUG
Secret: "${config.sops.placeholder."traefik/oauth2-plugin-secret"}" Secret: "${config.sops.placeholder."traefik/oauth2-plugin-secret"}"
CallbackUri: "https://auth.blazestar.net/oidc/callback" # Omitting the Callback URL means it will use the current domain for the callback.
# CallbackUri: "https://oidc.blazestar.net/oidc/callback"
Provider: Provider:
Url: "https://auth.blazestar.net/" Url: "https://auth.blazestar.net/"
ClientId: "3e3f7d9a-a684-4412-866c-ea7281954a9f" ClientId: "3e3f7d9a-a684-4412-866c-ea7281954a9f"
ClientSecret: "${config.sops.placeholder."traefik/oauth2-client-secret"}" ClientSecret: "${config.sops.placeholder."traefik/oauth2-client-secret"}"
TokenValidation: "IdToken" TokenValidation: "IdToken"
UsePkce: false
Scopes: ["openid", "profile", "email"] Scopes: ["openid", "profile", "email"]
Headers:
- Name: "X-Oidc-Username"
Value: "{{`{{ .claims.preferred_username }}`}}"
- Name: "X-Oidc-Email"
Value: "{{`{{ .claims.email }}`}}"
- Name: "X-Oidc-Subject"
Value: "sub"
- Name: "Authorization"
Value: "{{`Bearer {{ .accessToken }}`}}"
- Name: "IdToken"
Value: "{{`Bearer {{ .idToken }}`}}"
''; '';
virtualisation.oci-containers.containers.traefik = mkContainer { virtualisation.oci-containers.containers.traefik = mkContainer {

View File

@@ -46,9 +46,11 @@ metrics:
entryPoint: "metrics" entryPoint: "metrics"
# Plugins must be defined in static config # Plugins must be defined in static config
# Configuration of the plugin is in traefik.nix because it contains secrets.
# TODO: Convert this whole file to a template in Nix
experimental: experimental:
plugins: plugins:
traefik-oidc-auth: traefik-oidc-auth:
moduleName: "github.com/sevensolutions/traefik-oidc-auth" moduleName: "github.com/sevensolutions/traefik-oidc-auth"
version: "v0.11.0" version: "v0.13.0"