longhorn: log in through authentik on the Gateway

Longhorn has no users of its own; nginx guarded it with basic auth using apr1 hashes, which Envoy Gateway does not support. An Envoy Gateway SecurityPolicy now sends visitors through an authentik OIDC application that only admins may use. The client secret lives in Vault at kv/longhorn-oidc and reaches both authentik and Envoy through External Secrets.
This commit is contained in:
Ruben Hensen committed 2026-10-23 21:07:31 +02:00
1 parent 009b8ce510
commit 910b792452
6 files changed
+179

No files matched your search

+17
View File
@@ -86,6 +86,11 @@ spec:
secretKeyRef:
name: actualbudget-oidc-client-secret
key: client_secret
- name: LONGHORN_OIDC_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: longhorn-oidc-client-secret
key: client_secret
# Point OpenSSL and requests (which uses certifi otherwise) at
# patched-ca-bundle, mounted below until the image drops the
# compromised eMudhra intermediates.
@@ -119,6 +124,9 @@ spec:
- name: blueprint-session
configMap:
name: authentik-blueprint-session
- name: blueprint-longhorn
configMap:
name: authentik-blueprint-longhorn
volumeMounts:
- name: blueprint-vault
mountPath: /blueprints/custom/vault-oidc.yaml
@@ -141,6 +149,9 @@ spec:
- name: blueprint-session
mountPath: /blueprints/custom/session-duration.yaml
subPath: session-duration.yaml
- name: blueprint-longhorn
mountPath: /blueprints/custom/longhorn-oidc.yaml
subPath: longhorn-oidc.yaml
- name: patched-ca-bundle
mountPath: /etc/ssl/certs
readOnly: true
@@ -181,6 +192,9 @@ spec:
- name: blueprint-session
configMap:
name: authentik-blueprint-session
- name: blueprint-longhorn
configMap:
name: authentik-blueprint-longhorn
volumeMounts:
- name: blueprint-vault
mountPath: /blueprints/custom/vault-oidc.yaml
@@ -203,6 +217,9 @@ spec:
- name: blueprint-session
mountPath: /blueprints/custom/session-duration.yaml
subPath: session-duration.yaml
- name: blueprint-longhorn
mountPath: /blueprints/custom/longhorn-oidc.yaml
subPath: longhorn-oidc.yaml
- name: patched-ca-bundle
mountPath: /etc/ssl/certs
readOnly: true
+53
View File
@@ -0,0 +1,53 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: authentik-blueprint-longhorn
data:
longhorn-oidc.yaml: |
version: 1
metadata:
name: Longhorn OIDC
entries:
# Envoy Gateway does the login for Longhorn, which has no users of its
# own (see longhorn/httproute.yaml).
- model: authentik_providers_oauth2.oauth2provider
id: longhorn-provider
state: present
identifiers:
name: Longhorn
attrs:
name: Longhorn
authorization_flow: !Find [authentik_flows.flow, [slug, default-provider-authorization-implicit-consent]]
authentication_flow: !Find [authentik_flows.flow, [slug, default-authentication-flow]]
invalidation_flow: !Find [authentik_flows.flow, [slug, default-provider-invalidation-flow]]
client_type: confidential
client_id: longhorn
client_secret: !Env [LONGHORN_OIDC_CLIENT_SECRET, ""]
redirect_uris:
- matching_mode: strict
url: https://longhorn.rubenhensen.nl/oauth2/callback
# Envoy's test port until the switch from ingress-nginx
- matching_mode: strict
url: https://longhorn.rubenhensen.nl:10443/oauth2/callback
signing_key: !Find [authentik_crypto.certificatekeypair, [name, "authentik Self-signed Certificate"]]
property_mappings:
- !Find [authentik_providers_oauth2.scopemapping, [managed, goauthentik.io/providers/oauth2/scope-openid]]
- !Find [authentik_providers_oauth2.scopemapping, [managed, goauthentik.io/providers/oauth2/scope-email]]
- !Find [authentik_providers_oauth2.scopemapping, [managed, goauthentik.io/providers/oauth2/scope-profile]]
- model: authentik_core.application
id: longhorn-app
state: present
identifiers:
slug: longhorn
attrs:
name: Longhorn
provider: !KeyOf longhorn-provider
meta_launch_url: https://longhorn.rubenhensen.nl
# Longhorn can delete volumes, so only admins get in.
- model: authentik_policies.policybinding
state: present
identifiers:
order: 0
target: !KeyOf longhorn-app
attrs:
group: !Find [authentik_core.group, [name, "authentik Admins"]]
+18
View File
@@ -135,3 +135,21 @@ spec:
remoteRef:
key: kv/actualbudget-oidc
property: client_secret
---
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: longhorn-oidc-client-secret
spec:
secretStoreRef:
name: vault-backend
kind: ClusterSecretStore
refreshInterval: 15m
target:
name: longhorn-oidc-client-secret
creationPolicy: Owner
data:
- secretKey: client_secret
remoteRef:
key: kv/longhorn-oidc
property: client_secret
+14
View File
@@ -212,3 +212,17 @@ spec:
selector:
matchLabels:
kubernetes.io/metadata.name: argocd
- name: https-longhorn
protocol: HTTPS
port: 443
hostname: longhorn.rubenhensen.nl
tls:
certificateRefs:
- name: letsencrypt-prod
namespace: longhorn-system
allowedRoutes:
namespaces:
from: Selector
selector:
matchLabels:
kubernetes.io/metadata.name: longhorn-system
+76
View File
@@ -0,0 +1,76 @@
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: longhorn
spec:
parentRefs:
- name: homelab
namespace: envoy-gateway-system
sectionName: https-longhorn
hostnames:
- longhorn.rubenhensen.nl
rules:
- backendRefs:
- name: longhorn-frontend
port: 80
# No limit on the whole request, as with nginx. Envoy's default of 15s
# cuts off uploads and long-lived connections.
timeouts:
request: 0s
---
# Longhorn has no login of its own. Envoy sends visitors through authentik
# first; the authentik application only lets admins in.
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: SecurityPolicy
metadata:
name: longhorn-oidc
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: HTTPRoute
name: longhorn
oidc:
provider:
issuer: https://authentik.rubenhensen.nl/application/o/longhorn/
clientID: longhorn
clientSecret:
name: longhorn-oidc-client-secret
scopes:
- openid
- email
- profile
logoutPath: /logout
---
# Same client secret as authentik's, under the key Envoy Gateway expects.
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: longhorn-oidc-client-secret
spec:
secretStoreRef:
name: vault-backend
kind: ClusterSecretStore
refreshInterval: 15m
target:
name: longhorn-oidc-client-secret
creationPolicy: Owner
data:
- secretKey: client-secret
remoteRef:
key: kv/longhorn-oidc
property: client_secret
---
# Lets the Gateway serve the certificate cert-manager keeps in this namespace.
apiVersion: gateway.networking.k8s.io/v1
kind: ReferenceGrant
metadata:
name: gateway-tls
spec:
from:
- group: gateway.networking.k8s.io
kind: Gateway
namespace: envoy-gateway-system
to:
- group: ""
kind: Secret
name: letsencrypt-prod
+1
View File
@@ -5,5 +5,6 @@ namespace: longhorn-system
resources:
- ingress.yaml
- httproute.yaml
- volume-snapshot.yaml
- https://github.com/kubernetes-csi/external-snapshotter/client/config/crd