Bind tailnet auth flow to tailscale

This commit is contained in:
Conrad Kramer 2026-04-05 01:34:32 -07:00
parent c8aa036ade
commit 8de798469b
2 changed files with 28 additions and 12 deletions

View file

@ -4,6 +4,7 @@ set -euo pipefail
authentik_url="${AUTHENTIK_URL:-https://auth.burrow.net}" authentik_url="${AUTHENTIK_URL:-https://auth.burrow.net}"
bootstrap_token="${AUTHENTIK_BOOTSTRAP_TOKEN:-}" bootstrap_token="${AUTHENTIK_BOOTSTRAP_TOKEN:-}"
provider_slug="${AUTHENTIK_TAILNET_PROVIDER_SLUG:-ts}" provider_slug="${AUTHENTIK_TAILNET_PROVIDER_SLUG:-ts}"
provider_slugs_json="${AUTHENTIK_TAILNET_PROVIDER_SLUGS_JSON:-}"
authentication_flow_name="${AUTHENTIK_TAILNET_AUTHENTICATION_FLOW_NAME:-Burrow Tailnet Authentication}" authentication_flow_name="${AUTHENTIK_TAILNET_AUTHENTICATION_FLOW_NAME:-Burrow Tailnet Authentication}"
authentication_flow_slug="${AUTHENTIK_TAILNET_AUTHENTICATION_FLOW_SLUG:-burrow-tailnet-authentication}" authentication_flow_slug="${AUTHENTIK_TAILNET_AUTHENTICATION_FLOW_SLUG:-burrow-tailnet-authentication}"
identification_stage_name="${AUTHENTIK_TAILNET_IDENTIFICATION_STAGE_NAME:-burrow-tailnet-identification-stage}" identification_stage_name="${AUTHENTIK_TAILNET_IDENTIFICATION_STAGE_NAME:-burrow-tailnet-identification-stage}"
@ -21,6 +22,7 @@ Required environment:
Optional environment: Optional environment:
AUTHENTIK_URL AUTHENTIK_URL
AUTHENTIK_TAILNET_PROVIDER_SLUG AUTHENTIK_TAILNET_PROVIDER_SLUG
AUTHENTIK_TAILNET_PROVIDER_SLUGS_JSON
AUTHENTIK_TAILNET_AUTHENTICATION_FLOW_NAME AUTHENTIK_TAILNET_AUTHENTICATION_FLOW_NAME
AUTHENTIK_TAILNET_AUTHENTICATION_FLOW_SLUG AUTHENTIK_TAILNET_AUTHENTICATION_FLOW_SLUG
AUTHENTIK_TAILNET_IDENTIFICATION_STAGE_NAME AUTHENTIK_TAILNET_IDENTIFICATION_STAGE_NAME
@ -40,6 +42,15 @@ if [[ -z "$bootstrap_token" ]]; then
exit 1 exit 1
fi fi
if [[ -n "$provider_slugs_json" ]]; then
if ! printf '%s' "$provider_slugs_json" | jq -e 'type == "array" and length > 0 and all(.[]; type == "string" and length > 0)' >/dev/null; then
echo "error: AUTHENTIK_TAILNET_PROVIDER_SLUGS_JSON must be a non-empty JSON array of strings" >&2
exit 1
fi
else
provider_slugs_json="$(jq -cn --arg slug "$provider_slug" '[$slug]')"
fi
api() { api() {
local method="$1" local method="$1"
local path="$2" local path="$2"
@ -263,18 +274,20 @@ ensure_flow_binding() {
wait_for_authentik wait_for_authentik
provider_pk="$( mapfile -t provider_pks < <(
api GET "/api/v3/providers/oauth2/?page_size=200" \ api GET "/api/v3/providers/oauth2/?page_size=200" \
| jq -r --arg provider_slug "$provider_slug" ' | jq -r --argjson provider_slugs "$provider_slugs_json" '
.results[]? .results[]?
| select(.assigned_application_slug == $provider_slug or .slug == $provider_slug) | select(
(.assigned_application_slug != null and ($provider_slugs | index(.assigned_application_slug) != null))
or (.slug != null and ($provider_slugs | index(.slug) != null))
)
| .pk // empty | .pk // empty
' \ '
| head -n1 )
)"
if [[ -z "$provider_pk" ]]; then if [[ "${#provider_pks[@]}" -eq 0 ]]; then
echo "error: could not resolve Authentik Tailnet OAuth provider ${provider_slug}" >&2 echo "error: could not resolve any Authentik Tailnet OAuth providers from ${provider_slugs_json}" >&2
exit 1 exit 1
fi fi
@ -287,8 +300,10 @@ authentication_flow_pk="$(ensure_authentication_flow)"
ensure_flow_binding "$authentication_flow_pk" "$identification_stage_pk" 10 ensure_flow_binding "$authentication_flow_pk" "$identification_stage_pk" 10
ensure_flow_binding "$authentication_flow_pk" "$user_login_stage_pk" 30 ensure_flow_binding "$authentication_flow_pk" "$user_login_stage_pk" 30
api PATCH "/api/v3/providers/oauth2/${provider_pk}/" "$( for provider_pk in "${provider_pks[@]}"; do
api PATCH "/api/v3/providers/oauth2/${provider_pk}/" "$(
jq -cn --arg flow "$authentication_flow_pk" '{authentication_flow: $flow}' jq -cn --arg flow "$authentication_flow_pk" '{authentication_flow: $flow}'
)" >/dev/null )" >/dev/null
done
echo "Synced Burrow Tailnet authentication flow for provider ${provider_slug}." echo "Synced Burrow Tailnet authentication flow for providers ${provider_slugs_json}."

View file

@ -603,6 +603,7 @@ EOF
export AUTHENTIK_URL=https://${cfg.domain} export AUTHENTIK_URL=https://${cfg.domain}
export AUTHENTIK_TAILNET_PROVIDER_SLUG=${lib.escapeShellArg cfg.headscaleProviderSlug} export AUTHENTIK_TAILNET_PROVIDER_SLUG=${lib.escapeShellArg cfg.headscaleProviderSlug}
export AUTHENTIK_TAILNET_PROVIDER_SLUGS_JSON='["${cfg.headscaleProviderSlug}","${cfg.tailscaleProviderSlug}"]'
export AUTHENTIK_TAILNET_AUTHENTICATION_FLOW_NAME=${lib.escapeShellArg cfg.headscaleAuthenticationFlowName} export AUTHENTIK_TAILNET_AUTHENTICATION_FLOW_NAME=${lib.escapeShellArg cfg.headscaleAuthenticationFlowName}
export AUTHENTIK_TAILNET_AUTHENTICATION_FLOW_SLUG=${lib.escapeShellArg cfg.headscaleAuthenticationFlowSlug} export AUTHENTIK_TAILNET_AUTHENTICATION_FLOW_SLUG=${lib.escapeShellArg cfg.headscaleAuthenticationFlowSlug}
export AUTHENTIK_TAILNET_IDENTIFICATION_STAGE_NAME=${lib.escapeShellArg cfg.headscaleIdentificationStageName} export AUTHENTIK_TAILNET_IDENTIFICATION_STAGE_NAME=${lib.escapeShellArg cfg.headscaleIdentificationStageName}