authentik: Passkey-Step-up-Flow für Home Assistant und NetBird

Neuer Authorization-Flow `passkey-stepup-authorization` mit einer
WebAuthn-only Authenticator-Validation-Stage, per Blueprint auf die
OAuth2-Provider von Home Assistant und NetBird gebunden. Login in
diese Apps erfordert damit einen Passkey — auch mit bestehender
SSO-Session aus einem Passwort-Login.

- not_configured_action: configure — g.renner (HA-Zugriff, kein
  Passkey enrolled) wird beim ersten Login zur Enrollment geführt
  statt ausgesperrt
- last_auth_threshold hours=8 — kein Doppel-Touch direkt nach
  Passkey-Login; NetBirds /silent-auth (prompt=none) bleibt innerhalb
  des Fensters funktionsfähig
- Provider-Pflichtfelder (invalidation_flow, redirect_uris,
  client_type) spiegeln den Live-Stand vom 2026-07-07; ab jetzt
  besitzt Git diese Felder

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-07 08:54:30 +02:00
co-authored by Claude Fable 5
parent e2c48bfa3a
commit 3ff1b472d7
2 changed files with 106 additions and 4 deletions
@@ -612,3 +612,105 @@ data:
identifiers:
name: Caddy docs.renner.uno
state: absent
# Passkey (WebAuthn) step-up for selected apps. A dedicated
# AUTHORIZATION flow — unlike a per-provider authentication flow, the
# authorization flow runs on EVERY interactive authorize, so an
# existing password-only SSO session from another app cannot slip
# into the step-up apps without presenting a passkey.
passkey-stepup.yaml: |
version: 1
metadata:
name: Passkey step-up authorization (homelab)
entries:
- id: passkey-stepup-flow
model: authentik_flows.flow
identifiers:
slug: passkey-stepup-authorization
state: present
attrs:
name: Passkey step-up authorization
title: "Redirecting to %(app)s"
designation: authorization
# Unauthenticated users are bounced through the default
# authentication flow first, then land back here for the
# WebAuthn validation — same as the built-in implicit-consent
# flow this replaces.
authentication: require_authenticated
- id: passkey-stepup-webauthn-validation
model: authentik_stages_authenticator_validate.authenticatorvalidatestage
identifiers:
name: passkey-stepup-webauthn-validation
state: present
attrs:
device_classes:
- webauthn
# `configure`, not `deny`: g.renner has Home Assistant access
# but no enrolled WebAuthn device (live check 2026-07-07), so
# a hard deny would lock her out with no self-service path.
# `configure` injects the default WebAuthn enrollment stage
# inline — first login without a passkey becomes "enroll one
# now, then validate it". Still passkey-only: there is no way
# through this stage without a WebAuthn credential.
not_configured_action: configure
configuration_stages:
- !Find [authentik_stages_authenticator_webauthn.authenticatorwebauthnstage, [name, default-authenticator-webauthn-setup]]
# Skip re-validation if a passkey was already presented within
# the window. Non-zero for two reasons: (1) no double-touch
# when the login itself used a passkey seconds earlier;
# (2) NetBird's dashboard silently re-authorizes via
# /silent-auth (prompt=none) on token expiry — a flow that
# always demands interaction would fail those and force a
# visible re-login every access-token lifetime.
last_auth_threshold: hours=8
webauthn_user_verification: preferred
- model: authentik_flows.flowstagebinding
identifiers:
target: !KeyOf passkey-stepup-flow
stage: !KeyOf passkey-stepup-webauthn-validation
order: 10
state: present
# Re-point the (previously UI-managed) OAuth2 providers at the
# step-up flow. Blueprint apply validates the full serializer, so
# the required fields (invalidation_flow, redirect_uris) mirror
# the live values as of 2026-07-07 — git owns them from here on;
# UI edits to these fields will be reverted on the next apply
# cycle.
- model: authentik_providers_oauth2.oauth2provider
identifiers:
name: Homeassistant
state: present
attrs:
authorization_flow: !KeyOf passkey-stepup-flow
invalidation_flow: !Find [authentik_flows.flow, [slug, default-provider-invalidation-flow]]
client_type: confidential
redirect_uris:
- url: https://home.renner.uno/auth/openid/callback
matching_mode: strict
- url: http://homeassistant.srv.renner.uno:8123/auth/openid/callback
matching_mode: strict
- model: authentik_providers_oauth2.oauth2provider
identifiers:
name: Provider for Netbird
state: present
attrs:
authorization_flow: !KeyOf passkey-stepup-flow
invalidation_flow: !Find [authentik_flows.flow, [slug, default-provider-invalidation-flow]]
client_type: public
redirect_uris:
- url: http://localhost:53000
matching_mode: strict
- url: https://netbird.renner.uno/
matching_mode: strict
- url: https://netbird.renner.uno/auth
matching_mode: strict
- url: https://netbird.renner.uno/silent-auth
matching_mode: strict
- url: https://netbird.renner.uno/peers
matching_mode: strict
- url: 'https://netbird\.renner\.uno(/.*)?'
matching_mode: regex
+4 -4
View File
@@ -160,10 +160,10 @@ spec:
redis:
enabled: false
# Mount the K8s-outpost-integration blueprint so the worker re-points
# every Outpost at the in-cluster Kubernetes service connection on
# boot and drops the legacy Docker connection inherited from the
# Proxmox deployment. See blueprints-configmap.yaml.
# Mount the homelab blueprints (K8s outpost integration, passkey
# step-up authorization) — every key of the ConfigMap is applied by
# the worker on boot and on each apply cycle. See
# blueprints-configmap.yaml.
blueprints:
configMaps:
- authentik-blueprints-k8s-outposts