Add Tailscale Authentik OIDC app

This commit is contained in:
Conrad Kramer 2026-04-04 23:53:33 -07:00
parent b15b6624cb
commit c8aa036ade
6 changed files with 344 additions and 2 deletions

View file

@ -10,6 +10,7 @@ let
dataVolume = "burrow-authentik-data:/data";
directorySyncScript = ../../Scripts/authentik-sync-burrow-directory.sh;
forgejoOidcSyncScript = ../../Scripts/authentik-sync-forgejo-oidc.sh;
tailscaleOidcSyncScript = ../../Scripts/authentik-sync-tailscale-oidc.sh;
googleSourceSyncScript = ../../Scripts/authentik-sync-google-source.sh;
tailnetAuthFlowSyncScript = ../../Scripts/authentik-sync-tailnet-auth-flow.sh;
authentikBlueprint = pkgs.writeText "burrow-authentik-blueprint.yaml" ''
@ -131,6 +132,24 @@ in
description = "Authentik application slug for Forgejo.";
};
tailscaleProviderSlug = lib.mkOption {
type = lib.types.str;
default = "tailscale";
description = "Authentik application slug for Tailscale custom OIDC sign-in.";
};
tailscaleClientId = lib.mkOption {
type = lib.types.str;
default = "tailscale.burrow.net";
description = "Client ID Authentik should present to Tailscale.";
};
tailscaleClientSecretFile = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
description = "Host-local file containing the Authentik Tailscale OIDC client secret.";
};
forgejoClientId = lib.mkOption {
type = lib.types.str;
default = "git.burrow.net";
@ -313,6 +332,13 @@ in
fi
''}
${lib.optionalString (cfg.tailscaleClientSecretFile != null) ''
if [ ! -s ${lib.escapeShellArg cfg.tailscaleClientSecretFile} ]; then
echo "Tailscale client secret missing: ${cfg.tailscaleClientSecretFile}" >&2
exit 1
fi
''}
install -d -m 0750 -o root -g root ${runtimeDir} ${blueprintDir}
install -m 0644 -o root -g root ${authentikBlueprint} ${blueprintFile}
@ -634,6 +660,53 @@ EOF
'';
};
systemd.services.burrow-authentik-tailscale-oidc = lib.mkIf (cfg.tailscaleClientSecretFile != null) {
description = "Reconcile the Burrow Authentik Tailscale OIDC application";
after = [
"burrow-authentik-ready.service"
"network-online.target"
];
wants = [
"burrow-authentik-ready.service"
"network-online.target"
];
wantedBy = [ "multi-user.target" ];
restartTriggers = [
tailscaleOidcSyncScript
cfg.envFile
cfg.tailscaleClientSecretFile
];
path = [
pkgs.bash
pkgs.coreutils
pkgs.curl
pkgs.jq
];
serviceConfig = {
Type = "oneshot";
User = "root";
Group = "root";
};
script = ''
set -euo pipefail
set -a
source ${lib.escapeShellArg cfg.envFile}
set +a
export AUTHENTIK_URL=https://${cfg.domain}
export AUTHENTIK_TAILSCALE_APPLICATION_SLUG=${lib.escapeShellArg cfg.tailscaleProviderSlug}
export AUTHENTIK_TAILSCALE_APPLICATION_NAME=Tailscale
export AUTHENTIK_TAILSCALE_PROVIDER_NAME=Tailscale
export AUTHENTIK_TAILSCALE_TEMPLATE_SLUG=${lib.escapeShellArg cfg.headscaleProviderSlug}
export AUTHENTIK_TAILSCALE_CLIENT_ID=${lib.escapeShellArg cfg.tailscaleClientId}
export AUTHENTIK_TAILSCALE_CLIENT_SECRET="$(tr -d '\r\n' < ${lib.escapeShellArg cfg.tailscaleClientSecretFile})"
export AUTHENTIK_TAILSCALE_LAUNCH_URL=https://login.tailscale.com/start/oidc
export AUTHENTIK_TAILSCALE_REDIRECT_URIS_JSON='["https://login.tailscale.com/a/oauth_response"]'
${pkgs.bash}/bin/bash ${tailscaleOidcSyncScript}
'';
};
services.caddy.virtualHosts."${cfg.domain}".extraConfig = ''
encode gzip zstd
reverse_proxy 127.0.0.1:${toString cfg.port}

View file

@ -258,13 +258,13 @@ in
"${cfg.siteDomain}".extraConfig = ''
encode gzip zstd
@oidcConfig path /.well-known/openid-configuration
redir @oidcConfig https://${config.services.burrow.authentik.domain}/application/o/${config.services.burrow.authentik.forgejoProviderSlug}/.well-known/openid-configuration 308
redir @oidcConfig https://${config.services.burrow.authentik.domain}/application/o/${config.services.burrow.authentik.tailscaleProviderSlug}/.well-known/openid-configuration 308
@tailnetConfig path /.well-known/burrow-tailnet
header @tailnetConfig Content-Type application/json
respond @tailnetConfig "{\"domain\":\"${cfg.siteDomain}\",\"provider\":\"headscale\",\"authority\":\"https://${config.services.burrow.headscale.domain}\",\"oidc_issuer\":\"https://${config.services.burrow.authentik.domain}/application/o/${config.services.burrow.authentik.headscaleProviderSlug}/\"}" 200
@webfinger path /.well-known/webfinger
header @webfinger Content-Type application/jrd+json
respond @webfinger "{\"subject\":\"{query.resource}\",\"links\":[{\"rel\":\"http://openid.net/specs/connect/1.0/issuer\",\"href\":\"https://${config.services.burrow.authentik.domain}/application/o/${config.services.burrow.authentik.forgejoProviderSlug}/\"},{\"rel\":\"https://burrow.net/rel/tailnet-control-server\",\"href\":\"https://${config.services.burrow.headscale.domain}\"}]}" 200
respond @webfinger "{\"subject\":\"{query.resource}\",\"links\":[{\"rel\":\"http://openid.net/specs/connect/1.0/issuer\",\"href\":\"https://${config.services.burrow.authentik.domain}/application/o/${config.services.burrow.authentik.tailscaleProviderSlug}/\"},{\"rel\":\"https://burrow.net/rel/tailnet-control-server\",\"href\":\"https://${config.services.burrow.headscale.domain}\"}]}" 200
@root path /
redir @root ${homeRepoUrl} 308
respond 404