Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
09aaf1b2b5 | ||
|
|
337dbe85ac | ||
|
|
e462980dac | ||
|
|
79db6a8e49 | ||
|
|
25d1742d61 | ||
|
|
736c39a413 | ||
|
|
22a0823b7e | ||
|
|
3054037480 | ||
|
|
8f1d39b7a8 | ||
|
|
edf224e450 | ||
|
|
b32920c48f | ||
|
|
cb2ffa6a08 | ||
|
|
7d352fbf20 | ||
|
|
1bb1bc9610 | ||
|
|
37aea0254b | ||
|
|
fad91b6a05 | ||
|
|
af73cf770b | ||
|
|
09e4225de5 | ||
|
|
c0cb864ca2 | ||
|
|
235306a840 | ||
|
|
e9b24a6d1f | ||
|
|
0274f9316c | ||
|
|
027f567c8b | ||
|
|
d2bcd90291 | ||
|
|
80714fe901 | ||
|
|
5bbb03bc52 | ||
|
|
af13688993 | ||
|
|
f70e77127e | ||
|
|
f658ce2980 |
@@ -0,0 +1,228 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: authentik-blueprints
|
||||||
|
namespace: authentik
|
||||||
|
data:
|
||||||
|
matrix-invitation-flow.yaml: |
|
||||||
|
# yaml-language-server: $schema=https://goauthentik.io/blueprints/schema.json
|
||||||
|
version: 1
|
||||||
|
metadata:
|
||||||
|
name: matrix-invitation-flow
|
||||||
|
labels:
|
||||||
|
blueprints.goauthentik.io/instantiate: "true"
|
||||||
|
entries:
|
||||||
|
# Reaffirm the flow itself (already created manually; matched by slug)
|
||||||
|
- model: authentik_flows.flow
|
||||||
|
state: present
|
||||||
|
identifiers:
|
||||||
|
slug: matrix-invitation
|
||||||
|
id: matrix_invitation_flow
|
||||||
|
attrs:
|
||||||
|
name: matrix-invitation
|
||||||
|
title: matrix-invitation
|
||||||
|
designation: enrollment
|
||||||
|
|
||||||
|
# The prompt stage had accumulated 16 unrelated system validation_policies
|
||||||
|
# (e.g. default-user-settings-authorization, default-oobe-password-usable)
|
||||||
|
# from manual UI setup, likely a "select all" slip in the policy picker.
|
||||||
|
# These crash on an anonymous enrollment context ('AnonymousUser' object
|
||||||
|
# has no attribute 'group_attributes', etc). A prompt stage needs none here.
|
||||||
|
- model: authentik_stages_prompt.promptstage
|
||||||
|
state: present
|
||||||
|
identifiers:
|
||||||
|
name: matrix-invitation-prompt
|
||||||
|
attrs:
|
||||||
|
validation_policies: []
|
||||||
|
|
||||||
|
# Correct stage chain, mirroring the working matrix-enrollment flow:
|
||||||
|
# Invite -> Prompt (username/email/password) -> Write -> Password -> Login
|
||||||
|
# Root cause of the original bug: only Invite+Prompt were bound, both at
|
||||||
|
# order=0, so the flow never wrote the user to the DB or logged them in.
|
||||||
|
- model: authentik_flows.flowstagebinding
|
||||||
|
state: present
|
||||||
|
identifiers:
|
||||||
|
target: !KeyOf matrix_invitation_flow
|
||||||
|
order: 0
|
||||||
|
attrs:
|
||||||
|
stage: !Find [authentik_stages_invitation.invitationstage, [name, matrix-enrollment-invitation]]
|
||||||
|
|
||||||
|
- model: authentik_flows.flowstagebinding
|
||||||
|
state: present
|
||||||
|
identifiers:
|
||||||
|
target: !KeyOf matrix_invitation_flow
|
||||||
|
order: 1
|
||||||
|
attrs:
|
||||||
|
stage: !Find [authentik_stages_prompt.promptstage, [name, matrix-invitation-prompt]]
|
||||||
|
|
||||||
|
- model: authentik_flows.flowstagebinding
|
||||||
|
state: present
|
||||||
|
identifiers:
|
||||||
|
target: !KeyOf matrix_invitation_flow
|
||||||
|
order: 2
|
||||||
|
attrs:
|
||||||
|
stage: !Find [authentik_stages_user_write.userwritestage, [name, default-source-enrollment-write]]
|
||||||
|
|
||||||
|
- model: authentik_flows.flowstagebinding
|
||||||
|
state: present
|
||||||
|
identifiers:
|
||||||
|
target: !KeyOf matrix_invitation_flow
|
||||||
|
order: 3
|
||||||
|
attrs:
|
||||||
|
stage: !Find [authentik_stages_password.passwordstage, [name, default-authentication-password]]
|
||||||
|
|
||||||
|
- model: authentik_flows.flowstagebinding
|
||||||
|
state: present
|
||||||
|
identifiers:
|
||||||
|
target: !KeyOf matrix_invitation_flow
|
||||||
|
order: 4
|
||||||
|
attrs:
|
||||||
|
stage: !Find [authentik_stages_user_login.userloginstage, [name, default-source-enrollment-login]]
|
||||||
|
|
||||||
|
# Without an explicit destination, the flow falls back to Authentik's own
|
||||||
|
# /if/user/ dashboard, which refuses type=external users ("Die Oberflaeche
|
||||||
|
# kann nur von internen Nutzern geoeffnet werden") - exactly the user type
|
||||||
|
# these Matrix-only accounts correctly have. Send them to Element instead.
|
||||||
|
- model: authentik_stages_redirect.redirectstage
|
||||||
|
state: present
|
||||||
|
identifiers:
|
||||||
|
name: matrix-invitation-redirect
|
||||||
|
id: matrix_invitation_redirect_stage
|
||||||
|
attrs:
|
||||||
|
mode: static
|
||||||
|
target_static: https://axion1337.chat
|
||||||
|
|
||||||
|
- model: authentik_flows.flowstagebinding
|
||||||
|
state: present
|
||||||
|
identifiers:
|
||||||
|
target: !KeyOf matrix_invitation_flow
|
||||||
|
order: 5
|
||||||
|
attrs:
|
||||||
|
stage: !KeyOf matrix_invitation_redirect_stage
|
||||||
|
matrix-recovery-flow.yaml: |
|
||||||
|
# yaml-language-server: $schema=https://goauthentik.io/blueprints/schema.json
|
||||||
|
version: 1
|
||||||
|
metadata:
|
||||||
|
name: matrix-recovery-flow
|
||||||
|
labels:
|
||||||
|
blueprints.goauthentik.io/instantiate: "true"
|
||||||
|
entries:
|
||||||
|
# matrix-recovery existed but had zero stage bindings (dead flow), and the
|
||||||
|
# real login flow (default-authentication-flow, used by the MAS OAuth2
|
||||||
|
# provider's authentication_flow) didn't link to it at all - no "Forgot
|
||||||
|
# password?" link was ever shown. Reuses the same default-recovery-*
|
||||||
|
# stages the built-in default-recovery-flow already uses successfully,
|
||||||
|
# plus our own redirect stage instead of falling back to the authentik
|
||||||
|
# dashboard (blocked for type=external Matrix users).
|
||||||
|
- model: authentik_flows.flow
|
||||||
|
state: present
|
||||||
|
identifiers:
|
||||||
|
slug: matrix-recovery
|
||||||
|
id: matrix_recovery_flow
|
||||||
|
attrs:
|
||||||
|
designation: recovery
|
||||||
|
|
||||||
|
- model: authentik_flows.flowstagebinding
|
||||||
|
state: present
|
||||||
|
identifiers:
|
||||||
|
target: !KeyOf matrix_recovery_flow
|
||||||
|
order: 10
|
||||||
|
attrs:
|
||||||
|
stage: !Find [authentik_stages_identification.identificationstage, [name, default-recovery-identification]]
|
||||||
|
|
||||||
|
- model: authentik_flows.flowstagebinding
|
||||||
|
state: present
|
||||||
|
identifiers:
|
||||||
|
target: !KeyOf matrix_recovery_flow
|
||||||
|
order: 20
|
||||||
|
attrs:
|
||||||
|
stage: !Find [authentik_stages_email.emailstage, [name, default-recovery-email]]
|
||||||
|
|
||||||
|
- model: authentik_flows.flowstagebinding
|
||||||
|
state: present
|
||||||
|
identifiers:
|
||||||
|
target: !KeyOf matrix_recovery_flow
|
||||||
|
order: 30
|
||||||
|
attrs:
|
||||||
|
stage: !Find [authentik_stages_prompt.promptstage, [name, "Change your password"]]
|
||||||
|
|
||||||
|
- model: authentik_flows.flowstagebinding
|
||||||
|
state: present
|
||||||
|
identifiers:
|
||||||
|
target: !KeyOf matrix_recovery_flow
|
||||||
|
order: 40
|
||||||
|
attrs:
|
||||||
|
stage: !Find [authentik_stages_user_write.userwritestage, [name, default-recovery-user-write]]
|
||||||
|
|
||||||
|
- model: authentik_flows.flowstagebinding
|
||||||
|
state: present
|
||||||
|
identifiers:
|
||||||
|
target: !KeyOf matrix_recovery_flow
|
||||||
|
order: 100
|
||||||
|
attrs:
|
||||||
|
stage: !Find [authentik_stages_user_login.userloginstage, [name, default-recovery-user-login]]
|
||||||
|
|
||||||
|
- model: authentik_flows.flowstagebinding
|
||||||
|
state: present
|
||||||
|
identifiers:
|
||||||
|
target: !KeyOf matrix_recovery_flow
|
||||||
|
order: 110
|
||||||
|
attrs:
|
||||||
|
stage: !Find [authentik_stages_redirect.redirectstage, [name, matrix-invitation-redirect]]
|
||||||
|
|
||||||
|
# Wire the "Forgot password?" link on the real login flow used by MAS
|
||||||
|
- model: authentik_stages_identification.identificationstage
|
||||||
|
state: present
|
||||||
|
identifiers:
|
||||||
|
name: default-authentication-identification
|
||||||
|
attrs:
|
||||||
|
recovery_flow: !KeyOf matrix_recovery_flow
|
||||||
|
matrix-mfa-setup-redirect.yaml: |
|
||||||
|
# yaml-language-server: $schema=https://goauthentik.io/blueprints/schema.json
|
||||||
|
version: 1
|
||||||
|
metadata:
|
||||||
|
name: matrix-mfa-setup-redirect
|
||||||
|
labels:
|
||||||
|
blueprints.goauthentik.io/instantiate: "true"
|
||||||
|
entries:
|
||||||
|
# 2FA is optional (default-authentication-mfa-validation has
|
||||||
|
# not_configured_action=skip - login never blocks on missing MFA).
|
||||||
|
# Users who want to opt in use these built-in single-stage setup flows
|
||||||
|
# directly (unreachable via /if/user/, which is blocked for type=external
|
||||||
|
# Matrix accounts). Without a stage after the setup itself, completion
|
||||||
|
# fell back to the same blocked /if/user/ dashboard - append our redirect.
|
||||||
|
- model: authentik_flows.flowstagebinding
|
||||||
|
state: present
|
||||||
|
identifiers:
|
||||||
|
target: !Find [authentik_flows.flow, [slug, default-authenticator-totp-setup]]
|
||||||
|
order: 10
|
||||||
|
attrs:
|
||||||
|
stage: !Find [authentik_stages_redirect.redirectstage, [name, matrix-invitation-redirect]]
|
||||||
|
|
||||||
|
- model: authentik_flows.flowstagebinding
|
||||||
|
state: present
|
||||||
|
identifiers:
|
||||||
|
target: !Find [authentik_flows.flow, [slug, default-authenticator-webauthn-setup]]
|
||||||
|
order: 10
|
||||||
|
attrs:
|
||||||
|
stage: !Find [authentik_stages_redirect.redirectstage, [name, matrix-invitation-redirect]]
|
||||||
|
matrix-brand-default-app.yaml: |
|
||||||
|
# yaml-language-server: $schema=https://goauthentik.io/blueprints/schema.json
|
||||||
|
version: 1
|
||||||
|
metadata:
|
||||||
|
name: matrix-brand-default-app
|
||||||
|
labels:
|
||||||
|
blueprints.goauthentik.io/instantiate: "true"
|
||||||
|
entries:
|
||||||
|
# Root cause behind several dead ends: an authenticated user hitting "/"
|
||||||
|
# with no other destination (e.g. after logging in mid-way through the
|
||||||
|
# TOTP/WebAuthn setup flows) falls back to Brand.default_application: if
|
||||||
|
# unset, that's /if/user/, which type=external Matrix accounts can't
|
||||||
|
# open. Only affects the bare "/" fallback - explicit URLs like
|
||||||
|
# /if/admin/ are unaffected, so internal/staff access is unchanged.
|
||||||
|
- model: authentik_brands.brand
|
||||||
|
state: present
|
||||||
|
identifiers:
|
||||||
|
domain: authentik-default
|
||||||
|
attrs:
|
||||||
|
default_application: !Find [authentik_core.application, [slug, matrix]]
|
||||||
Regular → Executable
+4
@@ -52,6 +52,10 @@ spec:
|
|||||||
use_tls: true
|
use_tls: true
|
||||||
from: "Authentik <gamemaster@axion1337.chat>"
|
from: "Authentik <gamemaster@axion1337.chat>"
|
||||||
|
|
||||||
|
blueprints:
|
||||||
|
configMaps:
|
||||||
|
- authentik-blueprints
|
||||||
|
|
||||||
server:
|
server:
|
||||||
ingress:
|
ingress:
|
||||||
enabled: false
|
enabled: false
|
||||||
|
|||||||
Regular → Executable
+2
@@ -4,6 +4,8 @@ resources:
|
|||||||
- namespace.yaml
|
- namespace.yaml
|
||||||
- helm-repo.yaml
|
- helm-repo.yaml
|
||||||
- authentik-secret.yaml
|
- authentik-secret.yaml
|
||||||
|
- authentik-blueprints.yaml
|
||||||
- certificate.yaml
|
- certificate.yaml
|
||||||
- authentik.yaml
|
- authentik.yaml
|
||||||
- ingress.yaml
|
- ingress.yaml
|
||||||
|
- networkpolicy.yaml
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
# Default-deny ingress for the authentik namespace, with explicit allow rules for the
|
||||||
|
# traffic paths that actually need to reach in: Traefik (kube-system) for the public
|
||||||
|
# auth.axion1337.chat endpoint and ACME HTTP-01 challenges, and MAS (matrix namespace)
|
||||||
|
# for upstream OIDC calls. Egress is intentionally untouched (federation-equivalent
|
||||||
|
# outbound calls like SMTP aren't restricted here).
|
||||||
|
#
|
||||||
|
# Note: authentik-postgresql already has its own NetworkPolicy from the Bitnami
|
||||||
|
# postgresql subchart (port 5432, no source restriction) - left alone, not duplicated,
|
||||||
|
# since it would get reset on the next Helm upgrade anyway.
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: default-deny-ingress
|
||||||
|
namespace: authentik
|
||||||
|
spec:
|
||||||
|
podSelector: {}
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
---
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: allow-ingress-authentik-server
|
||||||
|
namespace: authentik
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: authentik
|
||||||
|
app.kubernetes.io/component: server
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: kube-system
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: matrix
|
||||||
|
ports:
|
||||||
|
# NetworkPolicy matches the pod's actual container port, not the Service's
|
||||||
|
# external port - the authentik-server Service maps 80->9000, 443->9443.
|
||||||
|
- protocol: TCP
|
||||||
|
port: 9000
|
||||||
|
- protocol: TCP
|
||||||
|
port: 9443
|
||||||
|
---
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: allow-ingress-acme-solver
|
||||||
|
namespace: authentik
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
acme.cert-manager.io/http01-solver: "true"
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: kube-system
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 8089
|
||||||
Regular → Executable
+2
-5
@@ -130,11 +130,8 @@ spec:
|
|||||||
cpu: 100m
|
cpu: 100m
|
||||||
memory: 128Mi
|
memory: 128Mi
|
||||||
livenessProbe:
|
livenessProbe:
|
||||||
exec:
|
tcpSocket:
|
||||||
command:
|
port: 3478
|
||||||
- /bin/sh
|
|
||||||
- -c
|
|
||||||
- "netstat -uln | grep 3478 || exit 1"
|
|
||||||
initialDelaySeconds: 30
|
initialDelaySeconds: 30
|
||||||
periodSeconds: 10
|
periodSeconds: 10
|
||||||
volumes:
|
volumes:
|
||||||
|
|||||||
Regular → Executable
+9
-1
@@ -59,6 +59,14 @@ spec:
|
|||||||
enabled: true
|
enabled: true
|
||||||
ingress:
|
ingress:
|
||||||
host: mrtc.axion1337.chat
|
host: mrtc.axion1337.chat
|
||||||
|
# Chart default (20Mi request+limit) OOM-killed the authorisation service after
|
||||||
|
# ~74 days of uptime (2026-07-28) - too tight for a long-running Go service.
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
memory: 64Mi
|
||||||
|
cpu: 50m
|
||||||
|
limits:
|
||||||
|
memory: 128Mi
|
||||||
|
|
||||||
# Element Web
|
# Element Web
|
||||||
elementWeb:
|
elementWeb:
|
||||||
@@ -66,7 +74,7 @@ spec:
|
|||||||
image:
|
image:
|
||||||
registry: rohana.axion1337.de
|
registry: rohana.axion1337.de
|
||||||
repository: sorb/threadnet-web
|
repository: sorb/threadnet-web
|
||||||
tag: v0.1.0
|
tag: v0.2.3-elementcall-h264
|
||||||
ingress:
|
ingress:
|
||||||
host: axion1337.chat
|
host: axion1337.chat
|
||||||
|
|
||||||
|
|||||||
Regular → Executable
+112
@@ -193,6 +193,7 @@ data:
|
|||||||
<div class="section">
|
<div class="section">
|
||||||
<h2>❓ Support</h2>
|
<h2>❓ Support</h2>
|
||||||
<p>Für weitere Hilfe besuche: <a href="https://element.io/help" target="_blank">element.io/help</a></p>
|
<p>Für weitere Hilfe besuche: <a href="https://element.io/help" target="_blank">element.io/help</a></p>
|
||||||
|
<p>🔐 <a href="security.html">Konto-Sicherheit (Passkey/2FA einrichten)</a></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="support">
|
<div class="support">
|
||||||
@@ -203,6 +204,117 @@ data:
|
|||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
# Security / 2FA setup page
|
||||||
|
"security.html": |
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Konto-Sicherheit - aXion1337.Chat</title>
|
||||||
|
<style>
|
||||||
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||||
|
body {
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
|
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
|
min-height: 100vh;
|
||||||
|
padding: 40px 20px;
|
||||||
|
}
|
||||||
|
.container {
|
||||||
|
max-width: 800px;
|
||||||
|
margin: 0 auto;
|
||||||
|
background: white;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 20px 60px rgba(0,0,0,0.3);
|
||||||
|
padding: 40px;
|
||||||
|
}
|
||||||
|
h1 { color: #333; margin-bottom: 10px; font-size: 2.5em; }
|
||||||
|
.subtitle { color: #666; margin-bottom: 40px; font-size: 1.1em; }
|
||||||
|
.section { margin-bottom: 40px; }
|
||||||
|
.section h2 {
|
||||||
|
color: #667eea;
|
||||||
|
font-size: 1.5em;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
border-bottom: 3px solid #667eea;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
}
|
||||||
|
.download-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||||
|
gap: 20px;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
.download-card {
|
||||||
|
background: #f8f9fa;
|
||||||
|
border: 2px solid #e9ecef;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 20px;
|
||||||
|
text-align: center;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
text-decoration: none;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
.download-card:hover {
|
||||||
|
border-color: #667eea;
|
||||||
|
background: #f0f3ff;
|
||||||
|
transform: translateY(-5px);
|
||||||
|
box-shadow: 0 10px 30px rgba(102, 126, 234, 0.2);
|
||||||
|
}
|
||||||
|
.download-card .icon { font-size: 2.5em; margin-bottom: 10px; }
|
||||||
|
.download-card .name { font-weight: 600; font-size: 1.1em; margin-bottom: 5px; }
|
||||||
|
.download-card .desc { font-size: 0.9em; color: #666; }
|
||||||
|
.instructions {
|
||||||
|
background: #e7f3ff;
|
||||||
|
border-left: 4px solid #0066cc;
|
||||||
|
padding: 15px;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin: 15px 0;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
.support {
|
||||||
|
text-align: center;
|
||||||
|
color: #666;
|
||||||
|
margin-top: 40px;
|
||||||
|
padding-top: 20px;
|
||||||
|
border-top: 1px solid #e9ecef;
|
||||||
|
}
|
||||||
|
.support a { color: #667eea; text-decoration: none; font-weight: 500; }
|
||||||
|
.support a:hover { text-decoration: underline; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h1>🔐 Konto-Sicherheit</h1>
|
||||||
|
<p class="subtitle">Zwei-Faktor-Authentifizierung ist optional - richte sie nur ein, wenn du sie nutzen möchtest.</p>
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
<h2>🔑 Einrichten</h2>
|
||||||
|
<div class="download-grid">
|
||||||
|
<a href="https://auth.axion1337.chat/if/flow/default-authenticator-webauthn-setup/" class="download-card" target="_blank">
|
||||||
|
<div class="icon">🔑</div>
|
||||||
|
<div class="name">Passkey</div>
|
||||||
|
<div class="desc">WebAuthn / Sicherheitsschlüssel</div>
|
||||||
|
</a>
|
||||||
|
<a href="https://auth.axion1337.chat/if/flow/default-authenticator-totp-setup/" class="download-card" target="_blank">
|
||||||
|
<div class="icon">📱</div>
|
||||||
|
<div class="name">TOTP</div>
|
||||||
|
<div class="desc">Authenticator-App</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="instructions">
|
||||||
|
<strong>Hinweis:</strong> Du musst bei <code>auth.axion1337.chat</code> eingeloggt sein, damit die
|
||||||
|
Einrichtung funktioniert. Ohne konfiguriertes Gerät wird beim Login einfach kein zweiter Faktor abgefragt -
|
||||||
|
2FA ist nie Voraussetzung zum Anmelden.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="support">
|
||||||
|
<p><a href="index.html">← Zurück zum Setup</a></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
# README
|
# README
|
||||||
"README-Element-Setup.md": |
|
"README-Element-Setup.md": |
|
||||||
# Element Desktop Setup Scripts
|
# Element Desktop Setup Scripts
|
||||||
|
|||||||
Regular → Executable
+1
@@ -21,6 +21,7 @@ spec:
|
|||||||
- |
|
- |
|
||||||
mkdir -p /html/docs/setup
|
mkdir -p /html/docs/setup
|
||||||
cp /config/index.html /html/docs/setup/
|
cp /config/index.html /html/docs/setup/
|
||||||
|
cp /config/security.html /html/docs/setup/
|
||||||
cp /config/README-Element-Setup.md /html/docs/setup/
|
cp /config/README-Element-Setup.md /html/docs/setup/
|
||||||
cp /config/element-setup-windows.cmd /html/docs/setup/
|
cp /config/element-setup-windows.cmd /html/docs/setup/
|
||||||
cp /config/element-setup-macos.command /html/docs/setup/
|
cp /config/element-setup-macos.command /html/docs/setup/
|
||||||
|
|||||||
Regular → Executable
+1
@@ -30,3 +30,4 @@ resources:
|
|||||||
- element-server-suite.yaml
|
- element-server-suite.yaml
|
||||||
# Custom Apex Ingress für Element Web + Well-Known auf axion1337.chat
|
# Custom Apex Ingress für Element Web + Well-Known auf axion1337.chat
|
||||||
- apex-ingress.yaml # Custom Apex Ingress für Element Web + Well-Known auf axion1337.chat
|
- apex-ingress.yaml # Custom Apex Ingress für Element Web + Well-Known auf axion1337.chat
|
||||||
|
- networkpolicy.yaml
|
||||||
@@ -0,0 +1,293 @@
|
|||||||
|
# Default-deny ingress for the matrix namespace, with explicit allow rules per component.
|
||||||
|
# Egress is intentionally untouched (federation to arbitrary Matrix servers, ACME, SMTP,
|
||||||
|
# DNS all stay unrestricted).
|
||||||
|
#
|
||||||
|
# Lesson learned deploying the authentik namespace's equivalent policy: NetworkPolicy
|
||||||
|
# filters on the pod's actual container port, not the Service's external port (e.g.
|
||||||
|
# authentik-server's Service maps 80->9000). Wherever a Service here uses a *named*
|
||||||
|
# targetPort, this file references that name directly instead of guessing a number -
|
||||||
|
# Kubernetes resolves it from the pod spec, which is safer than a hardcoded port.
|
||||||
|
#
|
||||||
|
# matrix-stack-postgres already effectively has no dedicated chart NetworkPolicy of its
|
||||||
|
# own (unlike authentik-postgresql's Bitnami one) - the rules below are the only gate.
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: default-deny-ingress
|
||||||
|
namespace: matrix
|
||||||
|
spec:
|
||||||
|
podSelector: {}
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
---
|
||||||
|
# axion1337.chat (root) -> Element Web
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: allow-ingress-element-web
|
||||||
|
namespace: matrix
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: element-web
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: kube-system
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: element
|
||||||
|
---
|
||||||
|
# admin.axion1337.chat -> Element Admin
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: allow-ingress-element-admin
|
||||||
|
namespace: matrix
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: element-admin
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: kube-system
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: http
|
||||||
|
---
|
||||||
|
# axion1337.chat/docs/setup -> Element desktop setup docs (our own nginx)
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: allow-ingress-element-web-docs
|
||||||
|
namespace: matrix
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app: element-web-docs
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: kube-system
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 8080
|
||||||
|
---
|
||||||
|
# matrix.axion1337.chat AND the well-known delegation both front through haproxy
|
||||||
|
# (matrix-stack-synapse and matrix-stack-well-known Services both target haproxy's
|
||||||
|
# named ports, not synapse-main directly).
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: allow-ingress-haproxy
|
||||||
|
namespace: matrix
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: haproxy
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: kube-system
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: haproxy-synapse
|
||||||
|
- protocol: TCP
|
||||||
|
port: haproxy-403
|
||||||
|
- protocol: TCP
|
||||||
|
port: haproxy-wkd
|
||||||
|
---
|
||||||
|
# account.axion1337.chat (Traefik) + matrix.axion1337.chat (also routes to MAS for some
|
||||||
|
# paths) + synapse-main calling MAS's internal port for session/token introspection.
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: allow-ingress-mas
|
||||||
|
namespace: matrix
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: matrix-authentication-service
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: kube-system
|
||||||
|
- podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: synapse-main
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 8080
|
||||||
|
- from:
|
||||||
|
- podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: synapse-main
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 8081
|
||||||
|
---
|
||||||
|
# Synapse itself: reached via haproxy (same namespace), calls from MAS (provisioning),
|
||||||
|
# metrics scraped by Alloy (monitoring namespace).
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: allow-ingress-synapse
|
||||||
|
namespace: matrix
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: synapse-main
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: haproxy
|
||||||
|
- podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: matrix-authentication-service
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: synapse-http
|
||||||
|
- protocol: TCP
|
||||||
|
port: synapse-health
|
||||||
|
- from:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: monitoring
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: synapse-metrics
|
||||||
|
---
|
||||||
|
# mrtc.axion1337.chat (Traefik) for the auth handshake, plus Alloy scraping metrics.
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: allow-ingress-rtc-authorisation-service
|
||||||
|
namespace: matrix
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: matrix-rtc-authorisation-service
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: kube-system
|
||||||
|
- podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: matrix-rtc-sfu
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: http
|
||||||
|
---
|
||||||
|
# The SFU: mrtc.axion1337.chat (Traefik) for signalling, Alloy for metrics, and the
|
||||||
|
# NodePort-exposed WebRTC media ports need to stay open to the internet by design -
|
||||||
|
# that's the actual point of a TURN/SFU media relay, not a mistake.
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: allow-ingress-rtc-sfu
|
||||||
|
namespace: matrix
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: matrix-rtc-sfu
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: kube-system
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: http
|
||||||
|
- from:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: monitoring
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: metrics
|
||||||
|
- from:
|
||||||
|
- ipBlock:
|
||||||
|
cidr: 0.0.0.0/0
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 30001
|
||||||
|
- protocol: UDP
|
||||||
|
port: 30002
|
||||||
|
---
|
||||||
|
# Postgres: only Synapse and MAS need data access; Alloy scrapes the exporter.
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: allow-ingress-postgres
|
||||||
|
namespace: matrix
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: postgres
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: synapse-main
|
||||||
|
- podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: matrix-authentication-service
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 5432
|
||||||
|
- from:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: monitoring
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 9187
|
||||||
|
---
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: allow-ingress-acme-solver
|
||||||
|
namespace: matrix
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
acme.cert-manager.io/http01-solver: "true"
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: kube-system
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 8089
|
||||||
|
|
||||||
|
# Note: coturn runs with hostNetwork: true, so NetworkPolicy does not apply to it at all -
|
||||||
|
# it's already gated by the Hetzner Cloud Firewall instead. Nothing to write here.
|
||||||
Regular → Executable
+139
-60
@@ -1,7 +1,7 @@
|
|||||||
# aXion1337.Chat – Task List & Meilensteine
|
# aXion1337.Chat – Task List & Meilensteine
|
||||||
|
|
||||||
**Last Updated**: 2026-05-15
|
**Last Updated**: 2026-07-28
|
||||||
**Statusübersicht**: [✅ 9 Abgeschlossen] [🔄 0 In Progress] [📋 11+ Pending] [🔒 10 Security]
|
**Statusübersicht**: [✅ 13 Abgeschlossen] [🔄 0 In Progress] [📋 8+ Pending] [🔒 10 Security]
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -9,9 +9,9 @@
|
|||||||
|
|
||||||
| Kategorie | Count | Status | Details |
|
| Kategorie | Count | Status | Details |
|
||||||
|-----------|-------|--------|---------|
|
|-----------|-------|--------|---------|
|
||||||
| **Completed** | 9 | ✅ Done | K3S, Flux, ESS, Themes, Desktop, Monitoring, TURN, Authentik, Firewall, SSH |
|
| **Completed** | 13 | ✅ Done | K3S, Flux, ESS, Themes, Desktop, Monitoring, TURN, Authentik (Deploy+Enrollment/Recovery/2FA), Firewall, SSH, coturn Fix, Element Call Fork, NetworkPolicies |
|
||||||
| **In Progress** | 0 | 🔄 — | — |
|
| **In Progress** | 0 | 🔄 — | — |
|
||||||
| **Backlog** | 11+ | 📋 Pending | DB Backups, E2E Test, Element Call Fork, PostgreSQL Migration, NetworkPolicies |
|
| **Backlog** | 8+ | 📋 Pending | DB Backups, PostgreSQL Migration, MAS-Template-Link, VP9-Retry |
|
||||||
| **Security Tasks** | 5 | 🔒 Pending | auditd, Kernel hardening, CrowdSec, Falco, WAF |
|
| **Security Tasks** | 5 | 🔒 Pending | auditd, Kernel hardening, CrowdSec, Falco, WAF |
|
||||||
|
|
||||||
### Priority Distribution
|
### Priority Distribution
|
||||||
@@ -25,6 +25,63 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 🗓️ Session-Zusammenfassung 2026-07-27/28 (fortlaufend aktualisiert)
|
||||||
|
|
||||||
|
Nach längerer Pause wiederaufgenommen — Mac war neu aufgesetzt, Zugriff (SSH, Kubeconfig,
|
||||||
|
age-Key, Homebrew/flux/helm/sops/age) komplett wiederhergestellt und dauerhaft in `~/.zshrc`
|
||||||
|
verankert. Was in dieser Session erledigt wurde:
|
||||||
|
|
||||||
|
1. **Authentik Enrollment/Recovery/2FA** (Issue #7 ✅ geschlossen) — siehe Phase 8 unten und
|
||||||
|
`docs/troubleshooting/README.md`. `matrix-invitation`- und `matrix-recovery`-Flows waren
|
||||||
|
kaputt bzw. leer, jetzt als Authentik Blueprint (`apps/authentik/authentik-blueprints.yaml`)
|
||||||
|
deklarativ repariert. E2E mit echten Test-Usern (`clark`, `lucky`) verifiziert.
|
||||||
|
2. **coturn-Crash behoben** — Liveness-Probe nutzte `netstat` (existiert nicht im Image),
|
||||||
|
Server killte einen gesunden Prozess seit 88 Tagen, 36.000+ Restarts. Auf `tcpSocket`-Probe
|
||||||
|
umgestellt, läuft seitdem stabil.
|
||||||
|
3. **Element Call Fork** (Issue #8 ✅ geschlossen, Release `m6-element-call-fork-complete`) —
|
||||||
|
1440p/60fps-Defaults, siehe Kapitel 4 in `docs/deployment-guides/04-element-customization.md`.
|
||||||
|
**Wichtig**: erzwungenes `video_codec: vp9` hat Calls kurzzeitig live komplett kaputt gemacht
|
||||||
|
(kein Bild/Ton) — sofort zurückgerollt, ohne Codec-Zwang läuft's. Root Cause dafür nicht
|
||||||
|
abschließend isoliert, nur umgangen.
|
||||||
|
4. **Identitäts-Aufräumarbeiten**: `sorB`'s Authentik-E-Mail korrigiert (`thorec@hotmail.de`),
|
||||||
|
MAS OIDC-Link (`upstream_oauth_links`) von `sorB` zeigte fest auf den alten MAS-User
|
||||||
|
`akadmin`/`@akadmin:axion1337.chat` (Sub-Hash ist stabil über Username-Renames, daher blieb
|
||||||
|
die Verknüpfung nach dem Rename "akadmin"→"sorB" bestehen) — umgehängt auf `sorb`/
|
||||||
|
`@sorb:axion1337.chat`. Neue Identität `elbojoloco` angelegt (E-Mail `cfx@riot.8shield.net`),
|
||||||
|
verknüpft mit dem alten `akadmin`-MAS-User. **Übrig**: ein leeres, unverknüpftes
|
||||||
|
`@bojeledoggo:axion1337.chat`-Konto (Tippfehler-Artefakt) — User räumt das selbst auf.
|
||||||
|
5. **NetworkPolicies** (Issue #10 ✅ geschlossen) — siehe "Network Security" Abschnitt unten.
|
||||||
|
Zwei Live-Incidents beim Rollout (Port-Verwechslungen), beide binnen Minuten live gepatcht
|
||||||
|
und danach committed. Nebenbei: `matrixRTC`-Authorisation-Service OOM-Fix (20Mi→128Mi).
|
||||||
|
6. **Element Call Qualität nachgeschärft** — 720p-Zwischen-Simulcast-Layer ergänzt (sonst
|
||||||
|
harter Sprung von 1440p auf blockiges 360p bei kleinsten Netzwerkschwankungen), und
|
||||||
|
`video_codec: h264` statt VP8 (klassisches Simulcast wie VP8, kein SVC-Risiko wie bei
|
||||||
|
VP9, oft hardwarebeschleunigt v.a. auf iOS). Live verifiziert: 7/8 Tracks nativ H.264,
|
||||||
|
1 sauberer VP8-Fallback. Deployed als `v0.2.3-elementcall-h264`.
|
||||||
|
7. **Backlog nach Gitea migriert** — restlicher offener Backlog (VP9-Retry, ThreadNet-Web-Bug,
|
||||||
|
MAS-Template-Link, WAF und 17 weitere Security-/Infra-Punkte) als Issues #11–#31 angelegt,
|
||||||
|
veraltete erledigte Punkte (Authentik Stage 2/E2E-Test/Invite-Links, Hetzner-Firewall,
|
||||||
|
SSH-Hardening) aus dieser Datei entfernt bzw. als done markiert.
|
||||||
|
|
||||||
|
### Offene Punkte
|
||||||
|
- **VP9-Retry**: vermutete Ursache jetzt bekannt (LiveKit nutzt SVC für vp9/av1, Fork-Code
|
||||||
|
setzt aber immer Simulcast-Layer) — braucht einen Code-Fix in `buildPublishOptions()`
|
||||||
|
(`src/livekit/options.ts`) bevor erneut versucht wird. Stattdessen H.264 probiert (siehe
|
||||||
|
unten) — läuft gut, kein SVC-Risiko, hardwarebeschleunigt auf mehr Geräten.
|
||||||
|
- **`ThreadNet-Web` Build-Bug**: `scripts/docker-link-repos.sh`/`docker-package.sh` nicht
|
||||||
|
ausführbar committet + veralteter `matrix-js-sdk#develop`-Pin im Lockfile blockiert
|
||||||
|
vollständigen Neu-Build des Web-Forks. Noch nicht gefixt, User hat noch nicht final
|
||||||
|
entschieden ob gewünscht.
|
||||||
|
- **Verwaistes `@bojeledoggo:axion1337.chat`**: leeres Matrix-Konto ohne OIDC-Link, User räumt
|
||||||
|
das selbst auf (braucht dafür seinen eigenen Access-Token für die Admin-API).
|
||||||
|
- **MAS-Template-Link**: 2FA/Passkey-Setup-Links direkt auf `account.axion1337.chat/account/`
|
||||||
|
statt nur über `docs/setup/security.html` — braucht MAS Custom-Template-Override
|
||||||
|
(`templates.path`), größerer separater Task.
|
||||||
|
- Nächste Kandidaten aus den offenen Issues: #6 (DB-Backup, CRITICAL), #9 (PostgreSQL-Migration),
|
||||||
|
#10 (NetworkPolicies).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 🎯 Next Steps (Priorisiert)
|
## 🎯 Next Steps (Priorisiert)
|
||||||
|
|
||||||
### 🔴 **THIS WEEK – CRITICAL**
|
### 🔴 **THIS WEEK – CRITICAL**
|
||||||
@@ -206,38 +263,65 @@
|
|||||||
|
|
||||||
**None** – Alle CRITICAL Tasks erledigt! Nächster Focus: Database Backups
|
**None** – Alle CRITICAL Tasks erledigt! Nächster Focus: Database Backups
|
||||||
|
|
||||||
|
### Phase 8: Authentik Enrollment/Recovery/MFA Fix (2026-07-27)
|
||||||
|
- [x] **matrix-invitation Flow repariert** – fehlende Write/Password/Login-Stages ergänzt, Reihenfolge korrigiert, als Authentik Blueprint (`apps/authentik/authentik-blueprints.yaml`) reproduzierbar gemacht
|
||||||
|
- [x] **matrix-invitation-prompt** – 16 fehlerhafte `validation_policies` entfernt (crashten mit `AnonymousUser`/`NoneType`-Fehlern)
|
||||||
|
- [x] **Redirect-Stage** – Flow endet jetzt auf `axion1337.chat` statt in der `/if/user/`-Sackgasse (blockiert für `type=external`)
|
||||||
|
- [x] **matrix-recovery Flow gebaut** – war komplett leer (0 Stages); Passwort-Reset funktioniert jetzt, verlinkt von der echten Login-Seite
|
||||||
|
- [x] **Brand.default_application gesetzt** – behebt mehrere Dead-Ends, wenn eingeloggte User `/` ohne Ziel aufrufen
|
||||||
|
- [x] **2FA/Passkey Selbst-Einrichtung** – Links zu `default-authenticator-totp-setup`/`-webauthn-setup` (2FA bleibt optional, `not_configured_action=skip`), dokumentiert unter `axion1337.chat/docs/setup/security.html`
|
||||||
|
- [ ] **Backlog**: → **Issue #13** (MAS Custom-Template-Override für 2FA/Passkey-Link auf `account.axion1337.chat/account/`)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📋 Backlog (Weitere Aufgaben)
|
## 📋 Backlog (Weitere Aufgaben)
|
||||||
|
|
||||||
### Authentik Completion
|
**Ab 2026-07-28 in Gitea-Issues gepflegt statt hier** (eine Quelle der Wahrheit) — offene Issues:
|
||||||
- [ ] **Finish Authentik Stage 2 – MAS Integration**
|
[#6](https://rohana.axion1337.de/sorb/axion1337.chat-gitops/issues/6) DB-Backup-Strategie,
|
||||||
- Prerequisites: Authentik OIDC Provider vollständig konfiguriert
|
[#9](https://rohana.axion1337.de/sorb/axion1337.chat-gitops/issues/9) Externe PostgreSQL-Migration,
|
||||||
- Task: Update `mas-secret.yaml`, enable password login disable
|
[#11](https://rohana.axion1337.de/sorb/axion1337.chat-gitops/issues/11)–[#31](https://rohana.axion1337.de/sorb/axion1337.chat-gitops/issues/31)
|
||||||
- Commit: `enable-authentik-oidc-integration-in-mas`
|
(VP9-Retry, ThreadNet-Web-Build-Bug, MAS-Template-Link, WAF, Media-PVC-Backups, Pod Security
|
||||||
- Est. Effort: 30 min (manual + scripted)
|
Admission, Federation-Allowlist, Mjolnir/Draupnir, Content-Scanner, External-Secrets,
|
||||||
|
Renovate/Trivy, Security-Advisory-Monitoring, automountServiceAccountToken,
|
||||||
- [ ] **Test End-to-End Login Flow**
|
unattended-upgrades, K3s-API-Security, auditd, Kernel-Hardening, Lynis, CrowdSec, Falco).
|
||||||
- Element Web login → MAS → Authentik → Matrix User Creation
|
Die detaillierten Beschreibungen unten sind das historische Original, aus dem die Issues
|
||||||
- Create test users via Authentik
|
entstanden sind — nicht mehr getrennt pflegen, stattdessen die Issues aktuell halten.
|
||||||
- Verify password reset flow
|
|
||||||
- Commit: (implicit in Stage 2)
|
|
||||||
- Est. Effort: 20 min
|
|
||||||
|
|
||||||
- [ ] **Create Invite Links für neue User**
|
|
||||||
- Authentik Admin UI → Invitations → Create
|
|
||||||
- Set expiry dates (7d) + use limits
|
|
||||||
- Document procedure
|
|
||||||
- Est. Effort: 15 min
|
|
||||||
|
|
||||||
### Element Call Enhancement
|
### Element Call Enhancement
|
||||||
- [ ] **Element Call Fork für Custom Constraints**
|
- [x] **Element Call Fork für Custom Constraints** (2026-07-28, Closes #8)
|
||||||
- Repository: Fork `element-hq/element-call`
|
- Fork: `rohana.axion1337.de/sorb/threadnet-call` (basiert auf `emmick4/element-call:livekit`,
|
||||||
- Feature: Video/Audio constraints parameter im config
|
das den noch nicht gemergten Upstream-PR element-hq/element-call#3736 enthält —
|
||||||
- Include: Bandwidth limiting, resolution limits, frame rate control
|
config-driven `media_quality`, keine Custom-Logik nötig)
|
||||||
- Integration mit Synapse well-known
|
- Defaults angehoben: Video bis 1440p/60fps (~8 Mbps), Screen-Share 1440p/30fps (~6 Mbps).
|
||||||
- Est. Effort: 2–3 days (fork + feature + test)
|
Das sind Startwerte, keine harten Limits — Nutzer können in den Settings weiter hochdrehen.
|
||||||
- Priority: **HIGH** (user feature)
|
- **Incident (2026-07-28)**: Erster Deploy (`v0.2.0`, mit `video_codec: vp9` erzwungen) hat
|
||||||
|
Calls komplett kaputt gemacht (kein Bild/Ton), obwohl LiveKit-Server-Logs den
|
||||||
|
Codec-Regression-Fallback auf VP8 als erfolgreich zeigten — Root Cause nicht abschließend
|
||||||
|
isoliert. Sofort auf `v0.1.0` zurückgerollt, dann `v0.2.1` ohne erzwungenen Codec (Standard
|
||||||
|
VP8) mit denselben 1440p/60fps-Werten deployed und vom Nutzer live bestätigt: funktioniert.
|
||||||
|
VP9-Präferenz vorerst fallengelassen, siehe Backlog.
|
||||||
|
- Rauschunterdrückung: nur clientseitige WebRTC-Standardtoggles (echoCancellation/
|
||||||
|
noiseSuppression/autoGainControl), kommt kostenlos mit derselben PR. **Bewusst kein**
|
||||||
|
server-seitiges ML-Noise-Cancellation (LiveKit Agents + DTLN/RNNoise) — laut LiveKits
|
||||||
|
eigener Doku ist das für Mensch-zu-Mensch-Calls der falsche Ansatz (nur für AI-Voice-Agents
|
||||||
|
gedacht, kein Standard-Pfad um bereinigtes Audio an andere Teilnehmer zurückzugeben).
|
||||||
|
- Well-Known/`org.matrix.msc4143.rtc_foci`-Delegation war schon vom ESS-Chart korrekt
|
||||||
|
automatisch konfiguriert — kein Handlungsbedarf trotz anderslautendem Issue-Text.
|
||||||
|
- **Deployment-Ansatz geändert**: `sorb/ThreadNet-Web` (der Element-Web-Fork) hat einen
|
||||||
|
vorbestehenden, unabhängigen Build-Bug (siehe unten) und ließ sich nicht komplett neu
|
||||||
|
bauen. Stattdessen: nur der `/app/widgets/element-call/`-Ordner im bereits laufenden
|
||||||
|
`threadnet-web:v0.1.0`-Image ausgetauscht → neues Image
|
||||||
|
`rohana.axion1337.de/sorb/threadnet-web:v0.2.0-elementcall-mediaquality`.
|
||||||
|
- Verifiziert: `media_quality` live auf `axion1337.chat/widgets/element-call/config.json`.
|
||||||
|
- **Gefunden, nicht gefixt**: `ThreadNet-Web` lässt sich aktuell nicht komplett neu bauen
|
||||||
|
— `scripts/docker-link-repos.sh`/`docker-package.sh` sind im Repo nicht ausführbar
|
||||||
|
committet (Mode 644 statt 755), UND der gepinnte `matrix-js-sdk#develop`-Commit im
|
||||||
|
Lockfile ist zu alt (fehlt `src/oidc/authorize.ts`, das `apps/web` importiert). Beides
|
||||||
|
unabhängig von diesem Fix, blockiert aber jeden zukünftigen vollständigen Rebuild.
|
||||||
|
- Backlog: MAL-basierte Noise-Cancellation (LiveKit Agents + self-hosted DTLN/RNNoise) als
|
||||||
|
experimentelle Idee, falls später gewünscht — kein etablierter Pfad für Conferencing.
|
||||||
|
- Backlog: VP9-Codec-Präferenz erneut versuchen, sobald PR #3736 upstream gemerged/gereift
|
||||||
|
ist oder Root Cause des Ausfalls isoliert wurde (Browser-Konsolen-Repro nötig).
|
||||||
|
|
||||||
### Database Hardening
|
### Database Hardening
|
||||||
- [ ] **External/Dedicated PostgreSQL Deployment**
|
- [ ] **External/Dedicated PostgreSQL Deployment**
|
||||||
@@ -264,18 +348,29 @@
|
|||||||
- Priority: **HIGH** (data preservation)
|
- Priority: **HIGH** (data preservation)
|
||||||
|
|
||||||
### Network Security
|
### Network Security
|
||||||
- [ ] **NetworkPolicies – K8s-Layer Segmentation**
|
- [x] **NetworkPolicies – K8s-Layer Segmentation** (2026-07-28, Closes #10)
|
||||||
- Default-Deny Ingress für `matrix` namespace
|
- Default-Deny Ingress (egress left untouched) für `matrix` UND `authentik` namespaces,
|
||||||
- Allow rules:
|
per-Komponente Allow-Regeln in `apps/authentik/networkpolicy.yaml` und
|
||||||
- Ingress → MAS:443
|
`apps/production/networkpolicy.yaml`. Rollout: authentik zuerst als Pilot, dann matrix.
|
||||||
- Ingress → ElementWeb:443
|
- Empirisch verifiziert, dass K3s' eingebauter NetworkPolicy-Controller tatsächlich
|
||||||
- MAS ↔ Synapse:8008
|
durchsetzt (Testnamespace, Timeout- statt Refused-Verhalten unter Deny-Policy).
|
||||||
- Synapse ↔ Postgres:5432
|
- **Zwei Live-Incidents beim Rollout, beide binnen Minuten behoben**:
|
||||||
- Authentik → Postgres:5432
|
1. `authentik-server`: Regel erlaubte Service-Port 80/443, aber NetworkPolicy filtert
|
||||||
- Authentik → Loki:3100 (monitoring)
|
auf dem tatsächlichen Container-Port (9000/9443 nach kube-proxy-DNAT) — 502 auf
|
||||||
- Egress: Matrix-specific (federation, etc.)
|
`auth.axion1337.chat`, sofort korrigiert.
|
||||||
- Est. Effort: 1 day
|
2. `matrix-authentication-service`: Regel erlaubte Synapse nur auf Port 8081, aber
|
||||||
- Priority: **MEDIUM** (compliance, least-privilege)
|
Synapse ruft `/oauth2/introspect` tatsächlich auf **Port 8080** — jede
|
||||||
|
authentifizierte Anfrage (inkl. `/sync`) scheiterte mit 503, alle Clients zeigten
|
||||||
|
"Verbindung unterbrochen". Live gepatcht, dann committed.
|
||||||
|
- Lehre für zukünftige NetworkPolicies in diesem Repo: wo immer ein Service benannte
|
||||||
|
Ports (`targetPort: <name>`) nutzt, diese direkt in der Policy referenzieren statt
|
||||||
|
Portnummern zu raten — schließt genau diese Fehlerklasse aus.
|
||||||
|
- Nebenbefund (unabhängig von NetworkPolicies): `matrixRTC`-Authorisation-Service hatte
|
||||||
|
ein 20Mi-Memory-Limit (Chart-Default), OOM-gekillt nach ~74 Tagen Uptime während der
|
||||||
|
Verifikations-Calls — auf 64Mi/128Mi angehoben.
|
||||||
|
- `coturn` (hostNetwork) bewusst ausgenommen — NetworkPolicy greift dort nicht.
|
||||||
|
- `authentik-postgresql`'s Bitnami-Chart-Policy (Port 5432, quelloffen) bewusst nicht
|
||||||
|
angefasst/dupliziert, da Helm-verwaltet.
|
||||||
|
|
||||||
- [ ] **Pod Security Admission (Restricted)**
|
- [ ] **Pod Security Admission (Restricted)**
|
||||||
- Apply to `matrix` & `authentik` namespaces
|
- Apply to `matrix` & `authentik` namespaces
|
||||||
@@ -355,24 +450,8 @@
|
|||||||
## 🔒 Security Hardening (Host & Cluster Level)
|
## 🔒 Security Hardening (Host & Cluster Level)
|
||||||
|
|
||||||
### Host OS Layer (Ubuntu/Debian)
|
### Host OS Layer (Ubuntu/Debian)
|
||||||
- [ ] **Hetzner Cloud Firewall**
|
- [x] **Hetzner Cloud Firewall** – Default-Deny inbound, siehe "Phase 7" oben. **Done.**
|
||||||
- Default-Deny inbound
|
- [x] **SSH Hardening** – Key-only, Root-Login disabled, Port 2248, siehe "Phase 7" oben. **Done.**
|
||||||
- Allow: 80/443 (HTTP/HTTPS)
|
|
||||||
- Allow: 22 (SSH) from your IP only (or via WireGuard/Tailscale)
|
|
||||||
- Status: ✅ Can be done in Hetzner UI
|
|
||||||
- Est. Effort: 30 min
|
|
||||||
- Priority: **CRITICAL** (immediate, zero config cost)
|
|
||||||
|
|
||||||
- [ ] **SSH Hardening**
|
|
||||||
- Disable password auth (key-only)
|
|
||||||
- Disable root login
|
|
||||||
- PermitRootLogin: no
|
|
||||||
- PasswordAuthentication: no
|
|
||||||
- MaxAuthTries: 3
|
|
||||||
- Optional: Change SSH port (cosmetic, reduces log noise)
|
|
||||||
- Optional: SSH hinter WireGuard/Tailscale (eliminates fail2ban für SSH)
|
|
||||||
- Est. Effort: 2 hours
|
|
||||||
- Priority: **HIGH** (immediate)
|
|
||||||
|
|
||||||
- [ ] **unattended-upgrades**
|
- [ ] **unattended-upgrades**
|
||||||
- Enable automatic security updates
|
- Enable automatic security updates
|
||||||
|
|||||||
Regular → Executable
+33
@@ -44,6 +44,39 @@
|
|||||||
|
|
||||||
**Konfiguration**: `apps/production/element-server-suite.yaml` (ESS Chart)
|
**Konfiguration**: `apps/production/element-server-suite.yaml` (ESS Chart)
|
||||||
|
|
||||||
|
## 4. Element Call Fork (Video/Audio-Qualität)
|
||||||
|
|
||||||
|
**Status**: ✅ Deployed (2026-07-28, Closes Issue #8)
|
||||||
|
|
||||||
|
- Fork: `rohana.axion1337.de/sorb/threadnet-call` (basiert auf `emmick4/element-call:livekit`,
|
||||||
|
enthält den noch nicht gemergten Upstream-PR element-hq/element-call#3736 mit
|
||||||
|
config-driven `media_quality` — kein Custom-Code nötig)
|
||||||
|
- Defaults angehoben: Kamera bis **1440p/60fps** (~8 Mbps), Screen-Share **1440p/30fps**
|
||||||
|
(~6 Mbps). Startwerte, keine harten Limits — Nutzer können in Settings weiter hochdrehen.
|
||||||
|
- Rauschunterdrückung: clientseitige WebRTC-Standardtoggles (Echo/Noise/Gain), passend zu
|
||||||
|
LiveKits eigener Empfehlung für Mensch-zu-Mensch-Calls. Bewusst **kein** server-seitiges
|
||||||
|
ML-Noise-Cancellation (siehe `docs/TASKS.md` Backlog).
|
||||||
|
- **Incident (2026-07-28)**: Erster Versuch mit erzwungenem `video_codec: vp9` hat Calls
|
||||||
|
komplett kaputt gemacht (kein Bild/Ton). Sofort zurückgerollt. Vermutete Ursache: LiveKit
|
||||||
|
nutzt für vp9/av1 SVC statt klassischem Simulcast, `buildPublishOptions()` im Fork setzt
|
||||||
|
aber immer Simulcast-Layer — Code-Fix nötig, bevor vp9 erneut versucht wird (Backlog).
|
||||||
|
- **720p-Zwischen-Layer ergänzt** (`simulcast_layers`) — ohne eigene Definition fiel die
|
||||||
|
Übertragung bei kleinsten Netzwerkschwankungen direkt von 1440p auf blockiges 360p, jetzt
|
||||||
|
sanftere Abstufung über 720p.
|
||||||
|
- **H.264 statt VP8** (2026-07-28) — nutzt wie VP8 klassisches Simulcast (kein SVC-Risiko wie
|
||||||
|
bei VP9), zusätzlich auf vielen Geräten (v.a. iOS/Safari) hardwarebeschleunigt. Live
|
||||||
|
verifiziert: 7 von 8 Video-Tracks liefen über H.264, 1 fiel sauber auf den VP8-Backup-Codec
|
||||||
|
zurück (kein Ausfall). Deployed als `v0.2.3-elementcall-h264`.
|
||||||
|
- Deployt als `rohana.axion1337.de/sorb/threadnet-web:v0.2.1-elementcall-noquotavp9` — nur
|
||||||
|
der `/app/widgets/element-call/`-Ordner im bestehenden `v0.1.0`-Image ausgetauscht, da
|
||||||
|
`ThreadNet-Web` einen vorbestehenden Build-Bug hat (siehe unten).
|
||||||
|
- Config live prüfbar: `https://axion1337.chat/widgets/element-call/config.json`
|
||||||
|
|
||||||
|
**Bekannter, nicht behobener Bug in `ThreadNet-Web`**: `scripts/docker-link-repos.sh` /
|
||||||
|
`docker-package.sh` sind nicht ausführbar committet (Mode 644), und der gepinnte
|
||||||
|
`matrix-js-sdk#develop`-Commit im Lockfile ist zu alt (fehlt `src/oidc/authorize.ts`) —
|
||||||
|
blockiert einen kompletten Neu-Build des Forks von Grund auf.
|
||||||
|
|
||||||
## Dateien
|
## Dateien
|
||||||
|
|
||||||
| Datei | Ort |
|
| Datei | Ort |
|
||||||
|
|||||||
Regular → Executable
+28
@@ -76,3 +76,31 @@ flux get helmreleases -n matrix --watch
|
|||||||
kubectl get pods -n matrix -w
|
kubectl get pods -n matrix -w
|
||||||
```
|
```
|
||||||
Sobald alle Pods auf `Running` stehen und die Zertifikate über Let's Encrypt validiert wurden (`kubectl get certificate -n matrix`), ist dein Matrix-Stack unter `https://axion1337.chat` erreichbar.
|
Sobald alle Pods auf `Running` stehen und die Zertifikate über Let's Encrypt validiert wurden (`kubectl get certificate -n matrix`), ist dein Matrix-Stack unter `https://axion1337.chat` erreichbar.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔁 Recovery: lokalen age-Key wiederherstellen (Server läuft bereits)
|
||||||
|
|
||||||
|
Anders als Schritt 2 oben (neuen Key **erzeugen**) — falls der Server bereits läuft und nur der
|
||||||
|
lokale Rechner den age-Key verloren hat (z.B. nach einer Neuinstallation), lässt sich der
|
||||||
|
**bestehende** Private Key direkt aus dem Cluster zurückholen, ohne einen neuen zu generieren
|
||||||
|
(das würde `.sops.yaml` und alle bereits verschlüsselten Secrets ungültig machen):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir -p ~/.age
|
||||||
|
kubectl get secret sops-age -n flux-system -o jsonpath='{.data.age\.agekey}' | base64 -d > ~/.age/keys.txt
|
||||||
|
chmod 600 ~/.age/keys.txt
|
||||||
|
|
||||||
|
# Public Key zur Kontrolle gegen .sops.yaml abgleichen:
|
||||||
|
grep 'public key:' ~/.age/keys.txt
|
||||||
|
grep 'age:' .sops.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
Voraussetzung: laufender Kubeconfig-Zugriff auf den Cluster (siehe Schritt 1 oben — auch das
|
||||||
|
ist reines Zurückkopieren, kein Neu-Erzeugen).
|
||||||
|
|
||||||
|
**Bekannte Schwachstelle**: Dieser Key existiert aktuell nur an zwei Orten — im
|
||||||
|
`sops-age`-Secret selbst (auf demselben Server) und lokal bei wem auch immer ihn zuletzt
|
||||||
|
zurückgeholt hat. Es gibt kein separates, offsite Backup. Fällt der Server komplett aus
|
||||||
|
(nicht nur der lokale Rechner), sind alle SOPS-verschlüsselten Secrets im Repo unlesbar.
|
||||||
|
Siehe Issue-Backlog für die Entscheidung, ob/wie das abgesichert wird.
|
||||||
@@ -0,0 +1,256 @@
|
|||||||
|
# 🆕 Authentik: Neuen Invitation Flow erstellen
|
||||||
|
|
||||||
|
**Problem**:
|
||||||
|
- Nur ein `matrix-enrollment` Flow existiert
|
||||||
|
- Wird für Standard-Signup + Invitations verwendet → Konflikt
|
||||||
|
- Fehler: "Found existing plan for other flow, deleting plan"
|
||||||
|
|
||||||
|
**Lösung**: Separaten `matrix-invitation` Flow für Einladungslinks erstellen.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Schritt 1: Authentik Admin UI öffnen
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl port-forward -n authentik svc/authentik 9000:9000
|
||||||
|
# Browser: http://localhost:9000/
|
||||||
|
# Admin: akadmin / (password)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Schritt 2: Neuen Flow erstellen
|
||||||
|
|
||||||
|
**Navigation**: Admin → Flows & Stages → Flows
|
||||||
|
|
||||||
|
1. Klick **"Create"** (oben rechts)
|
||||||
|
2. Fülle folgendes aus:
|
||||||
|
|
||||||
|
```
|
||||||
|
Name: matrix-invitation
|
||||||
|
Slug: matrix-invitation
|
||||||
|
Title: Matrix Enrollment via Invitation
|
||||||
|
Description: Enrollment flow for users created via invitation links
|
||||||
|
Designation: enrollment
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Speichern** (Save)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Schritt 3: Stages zur Invitation Flow hinzufügen
|
||||||
|
|
||||||
|
Nach dem Erstellen wirst du auf die Flow-Edit-Seite weitergeleitet.
|
||||||
|
|
||||||
|
**Navigation**: Admin → Flows & Stages → Flows → `matrix-invitation` → Edit
|
||||||
|
|
||||||
|
Klick auf "Add Stage" und folge dieser Reihenfolge:
|
||||||
|
|
||||||
|
### Stage 1: Invite Stage (Invitation verarbeiten)
|
||||||
|
|
||||||
|
1. Klick **"Add Stage"**
|
||||||
|
2. Wähle: **"Invite Stage"**
|
||||||
|
3. Konfiguriere:
|
||||||
|
```
|
||||||
|
Name: Invite
|
||||||
|
Order: 1
|
||||||
|
```
|
||||||
|
4. **Save**
|
||||||
|
|
||||||
|
Dann musst du das Binding setzen:
|
||||||
|
- Klick auf die Stage in der Flow
|
||||||
|
- Binding: **"Invite"** (oder "Invitation")
|
||||||
|
- Required: **Yes**
|
||||||
|
- **Save**
|
||||||
|
|
||||||
|
### Stage 2: Identification Stage (Username überprüfen)
|
||||||
|
|
||||||
|
1. Klick **"Add Stage"**
|
||||||
|
2. Wähle: **"Identification Stage"** (nicht "Authenticate Stage")
|
||||||
|
3. Konfiguriere:
|
||||||
|
```
|
||||||
|
Name: Identification
|
||||||
|
Order: 2
|
||||||
|
User Fields: username (oder email)
|
||||||
|
Create Users as Inactive: NO
|
||||||
|
```
|
||||||
|
4. **Save**
|
||||||
|
|
||||||
|
Binding setzen:
|
||||||
|
- Binding: **"Identify"**
|
||||||
|
- Required: **No**
|
||||||
|
- **Save**
|
||||||
|
|
||||||
|
### Stage 3: Prompt Stage (Daten abfragen: Username, Email, Name)
|
||||||
|
|
||||||
|
1. Klick **"Add Stage"**
|
||||||
|
2. Wähle: **"Prompt Stage"**
|
||||||
|
3. Konfiguriere:
|
||||||
|
```
|
||||||
|
Name: User Data
|
||||||
|
Order: 3
|
||||||
|
```
|
||||||
|
4. **Speichern (Save)**
|
||||||
|
|
||||||
|
Dann **Fields hinzufügen**:
|
||||||
|
- Klick auf die Stage
|
||||||
|
- Klick **"Add Field"** für jedes Feld:
|
||||||
|
|
||||||
|
#### Field 1: Username
|
||||||
|
```
|
||||||
|
Field Name: username
|
||||||
|
Label: Username
|
||||||
|
Type: text
|
||||||
|
Required: Yes
|
||||||
|
Placeholder: Choose a username
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Field 2: Email
|
||||||
|
```
|
||||||
|
Field Name: email
|
||||||
|
Label: Email Address
|
||||||
|
Type: email
|
||||||
|
Required: Yes
|
||||||
|
Placeholder: your@email.com
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Field 3: Name (Optional)
|
||||||
|
```
|
||||||
|
Field Name: name
|
||||||
|
Label: Full Name
|
||||||
|
Type: text
|
||||||
|
Required: No
|
||||||
|
Placeholder: Your Name
|
||||||
|
```
|
||||||
|
|
||||||
|
Alle Fields **Save**.
|
||||||
|
|
||||||
|
Dann **Stage-Binding setzen**:
|
||||||
|
- Binding: **"Prompt for data"** (oder "User Data")
|
||||||
|
- Required: **Yes**
|
||||||
|
- **Save**
|
||||||
|
|
||||||
|
### Stage 4: Write Stage (User in DB erstellen)
|
||||||
|
|
||||||
|
1. Klick **"Add Stage"**
|
||||||
|
2. Wähle: **"Write Stage"** (oder "User Write Stage")
|
||||||
|
3. Konfiguriere:
|
||||||
|
```
|
||||||
|
Name: Create User
|
||||||
|
Order: 4
|
||||||
|
```
|
||||||
|
4. **Speichern (Save)**
|
||||||
|
|
||||||
|
Dann **Field Bindings setzen**:
|
||||||
|
- Klick auf die Stage
|
||||||
|
- Unter "Field Bindings" oder "User Creation":
|
||||||
|
- `username` ← mapped von username Feld
|
||||||
|
- `email` ← mapped von email Feld
|
||||||
|
- `name` ← mapped von name Feld
|
||||||
|
- **Save**
|
||||||
|
|
||||||
|
Stage-Binding setzen:
|
||||||
|
- Binding: **"Create or update user"**
|
||||||
|
- Required: **Yes**
|
||||||
|
- **Save**
|
||||||
|
|
||||||
|
### Stage 5: Finish Stage (Abschluss)
|
||||||
|
|
||||||
|
1. Klick **"Add Stage"**
|
||||||
|
2. Wähle: **"Finish Stage"** (oder "User Login")
|
||||||
|
3. Konfiguriere:
|
||||||
|
```
|
||||||
|
Name: Finish
|
||||||
|
Order: 5
|
||||||
|
```
|
||||||
|
4. **Speichern (Save)**
|
||||||
|
|
||||||
|
Stage-Binding:
|
||||||
|
- Binding: **"Finish"** (oder "Complete enrollment")
|
||||||
|
- Required: **Yes**
|
||||||
|
- **Save**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Schritt 4: Flow als Standard-Invitation setzen
|
||||||
|
|
||||||
|
**Navigation**: Admin → System → Settings
|
||||||
|
|
||||||
|
Suche nach "Invitation Flow" oder "Default Flows":
|
||||||
|
1. Setze **"Invitation Flow"** auf `matrix-invitation`
|
||||||
|
2. **Save**
|
||||||
|
|
||||||
|
Alternativ:
|
||||||
|
- Admin → Flows & Stages → Flows
|
||||||
|
- Für jede Invitation/Group:
|
||||||
|
- Klick auf Group/Invitation
|
||||||
|
- Setze "Enrollment Flow" auf `matrix-invitation`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Schritt 5: Test mit neuem Einladungslink
|
||||||
|
|
||||||
|
1. **Neuen Einladungslink erstellen**:
|
||||||
|
- Admin → Users & Groups → Invitations
|
||||||
|
- Klick **"Create"**
|
||||||
|
- Expiry: 7 days
|
||||||
|
- **Create & Copy Link**
|
||||||
|
|
||||||
|
2. **Link öffnen** (neuer Browser/Inkognito):
|
||||||
|
- Link in Browser öffnen
|
||||||
|
- Sollte jetzt alle Felder zeigen:
|
||||||
|
- [ ] Username eingeben
|
||||||
|
- [ ] Email eingeben ← sollte jetzt da sein!
|
||||||
|
- [ ] Name eingeben (optional)
|
||||||
|
- [ ] "Weiter" oder "Sign in with Authentik"
|
||||||
|
|
||||||
|
3. **Authentik Login** (falls Binding korrekt):
|
||||||
|
- Mit Authentik anmelden
|
||||||
|
- Enrollment abgeschlossen
|
||||||
|
- User sollte in Synapse erstellt sein
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Fehler: "Stage not found"
|
||||||
|
- Stelle sicher, dass alle Stages ein **Binding** haben
|
||||||
|
- Alle Bindings müssen **eindeutig** sein (nicht doppelt)
|
||||||
|
- **Save** nach jeder Änderung
|
||||||
|
|
||||||
|
### Felder werden nicht angezeigt
|
||||||
|
- Prompt Stage überprüfen
|
||||||
|
- Alle Fields müssen **Save** sein
|
||||||
|
- Ggfs. Browser-Cache löschen
|
||||||
|
|
||||||
|
### Fehler nach Enrollment
|
||||||
|
- MAS Logs: `kubectl logs -f matrix-stack-matrix-authentication-service-6b994b9fcf-qqcxz -n matrix`
|
||||||
|
- Authentik Logs: `kubectl logs -f -n authentik -l app.kubernetes.io/name=authentik`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Erwartetes Ergebnis
|
||||||
|
|
||||||
|
Nach dem Fix:
|
||||||
|
1. Einladungslink öffnen → `matrix-invitation` Flow
|
||||||
|
2. Username, Email, Name eingeben
|
||||||
|
3. "Mit Authentik anmelden"
|
||||||
|
4. Nach Login: User in Synapse erstellt
|
||||||
|
5. Login zu ElementWeb möglich
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Checkliste
|
||||||
|
|
||||||
|
- [ ] `matrix-invitation` Flow erstellt
|
||||||
|
- [ ] 5 Stages in korrekter Reihenfolge (Invite → Identify → Prompt → Write → Finish)
|
||||||
|
- [ ] Prompt Stage hat username, email, name Felder
|
||||||
|
- [ ] Alle Stages haben korrektes Binding
|
||||||
|
- [ ] `matrix-invitation` als Standard-Invitation-Flow gesetzt
|
||||||
|
- [ ] Neuen Einladungslink erstellt und getestet
|
||||||
|
- [ ] Test-User kann Email eingeben
|
||||||
|
- [ ] Test-User in Synapse DB nach Login
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Sollte ca. 10-15 Minuten dauern!** 🚀
|
||||||
@@ -0,0 +1,314 @@
|
|||||||
|
# ✅ Authentik Enrollment Flow – Reparatur-Template
|
||||||
|
|
||||||
|
Basierend auf häufigen Problemen: Hier sind die wahrscheinlichsten Fixes.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Problem 1: MAS kennt Authentik-OIDC nicht
|
||||||
|
|
||||||
|
### Symptom
|
||||||
|
- MAS zeigt "Sign in with Authentik" Button nicht
|
||||||
|
- Logs: "upstream provider not configured"
|
||||||
|
|
||||||
|
### Lösung
|
||||||
|
|
||||||
|
**MAS Secret muss diesen Block enthalten:**
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# apps/production/custom-configs/mas-secret.yaml (decrypted)
|
||||||
|
---
|
||||||
|
matrixAuthenticationService:
|
||||||
|
upstream_oauth2_config:
|
||||||
|
issuer: "https://auth.axion1337.chat/application/o/matrix/"
|
||||||
|
client_id: "{{ CLIENT_ID_FROM_AUTHENTIK }}"
|
||||||
|
client_secret: "{{ CLIENT_SECRET_FROM_AUTHENTIK }}"
|
||||||
|
authorization_endpoint: "https://auth.axion1337.chat/application/o/authorize/"
|
||||||
|
token_endpoint: "https://auth.axion1337.chat/application/o/token/"
|
||||||
|
userinfo_endpoint: "https://auth.axion1337.chat/application/o/userinfo/"
|
||||||
|
scopes:
|
||||||
|
- "openid"
|
||||||
|
- "profile"
|
||||||
|
- "email"
|
||||||
|
user_mapping_provider:
|
||||||
|
type: "oidc"
|
||||||
|
config:
|
||||||
|
localpart_template: "{{ user.preferred_username }}"
|
||||||
|
display_name_template: "{{ user.name }}"
|
||||||
|
email_template: "{{ user.email }}"
|
||||||
|
|
||||||
|
# Wichtig: Password-Login deaktivieren (da wir nur OIDC verwenden)
|
||||||
|
passwords:
|
||||||
|
enabled: false
|
||||||
|
```
|
||||||
|
|
||||||
|
**Wie ausfüllen:**
|
||||||
|
|
||||||
|
1. Authentik Admin UI öffnen: `https://auth.axion1337.chat`
|
||||||
|
2. Admin → Applications → Providers → "matrix-provider" (oder ähnlich)
|
||||||
|
3. Folgende Werte kopieren:
|
||||||
|
- **Client ID**: Im Provider-Details zu sehen
|
||||||
|
- **Client Secret**: Im Provider-Details zu sehen (unter "Credentials")
|
||||||
|
|
||||||
|
4. Local entschlüsseln (mit age-key):
|
||||||
|
```bash
|
||||||
|
cd gitops/
|
||||||
|
sops -d -i apps/production/custom-configs/mas-secret.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
5. Datei öffnen und die Werte einfügen
|
||||||
|
|
||||||
|
6. Wieder verschlüsseln:
|
||||||
|
```bash
|
||||||
|
sops -e -i apps/production/custom-configs/mas-secret.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
7. Commiten:
|
||||||
|
```bash
|
||||||
|
git add apps/production/custom-configs/mas-secret.yaml
|
||||||
|
git commit -m "Fix: Configure MAS upstream OIDC for Authentik"
|
||||||
|
git push
|
||||||
|
```
|
||||||
|
|
||||||
|
8. Flux triggern:
|
||||||
|
```bash
|
||||||
|
flux reconcile kustomization production-apps --with-source
|
||||||
|
```
|
||||||
|
|
||||||
|
9. Warten, dass MAS Pod neu startet:
|
||||||
|
```bash
|
||||||
|
kubectl get pods -n matrix -l app=matrix-authentication-service -w
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Problem 2: Authentik Enrollment Flow ist kaputt
|
||||||
|
|
||||||
|
### Symptom
|
||||||
|
- User kommt zu Authentik-Login
|
||||||
|
- Nach Login: "Error: Enrollment stage not found" oder ähnlich
|
||||||
|
- Oder: Flow bricht ohne Fehlermeldung ab
|
||||||
|
|
||||||
|
### Lösung
|
||||||
|
|
||||||
|
**Authentik UI → Flows & Stages → Enrollment Flow überprüfen:**
|
||||||
|
|
||||||
|
```
|
||||||
|
Flows → Enrollment
|
||||||
|
├── Stage 1: "Identify" (if not exists)
|
||||||
|
│ └── Binding: "Identification (if not exists)"
|
||||||
|
├── Stage 2: "Write" (wichtig!)
|
||||||
|
│ └── Binding: "Create or update user"
|
||||||
|
│ └── User Creation Policies: ???
|
||||||
|
├── Stage 3: (optional) Weitere Datenerfassung
|
||||||
|
└── Stage 4: "Finish"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Häufiger Fehler**: "Write" Stage ist nicht korrekt mit den benötigten Feldern konfiguriert.
|
||||||
|
|
||||||
|
**Fix:**
|
||||||
|
|
||||||
|
1. Authentik Admin UI: `https://auth.axion1337.chat`
|
||||||
|
2. **Flows & Stages** → **Stages**
|
||||||
|
3. Nach "Write" Stage suchen (Filter: "write")
|
||||||
|
4. Klick auf "Write Stage"
|
||||||
|
5. **Field Bindings** überprüfen:
|
||||||
|
- [ ] `username` ← MUSS mit Authentik Username bindbar sein
|
||||||
|
- [ ] `email` ← MUSS vorhanden sein
|
||||||
|
- [ ] `name` ← Optional, aber empfohlen
|
||||||
|
6. Alle sollten "required" sein (nicht optional)
|
||||||
|
7. **Save**
|
||||||
|
|
||||||
|
Dann zurück zu **Flows** → **Enrollment**:
|
||||||
|
1. Stages überprüfen (oben)
|
||||||
|
2. Bindings überprüfen:
|
||||||
|
- Each Stage hat "Binding" Feld
|
||||||
|
- "Write" Stage sollte mit "Create or update user" gebunden sein
|
||||||
|
3. **Save**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Problem 3: OIDC Token werden nicht korrekt zu Synapse weitergeleitet
|
||||||
|
|
||||||
|
### Symptom
|
||||||
|
- User kommt bis zu ElementWeb
|
||||||
|
- Nach Login zu Authentik: "User not found in Synapse" oder Loop
|
||||||
|
- Oder: User wird in Authentik angelegt, aber nicht in Synapse
|
||||||
|
|
||||||
|
### Lösung
|
||||||
|
|
||||||
|
Das ist komplexer und erfordert MAS-Konfiguration + Synapse-Konfiguration.
|
||||||
|
|
||||||
|
**MAS Config (upstream_oauth2_config)** muss korrekt sein (siehe Problem 1).
|
||||||
|
|
||||||
|
**Zusätzlich in MAS Secret:**
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# apps/production/custom-configs/mas-secret.yaml
|
||||||
|
matrixAuthenticationService:
|
||||||
|
# ... upstream_oauth2_config ...
|
||||||
|
|
||||||
|
# User-Provisioning Konfiguration
|
||||||
|
access:
|
||||||
|
# Benutzer aus OIDC Provider automatisch erzeugen
|
||||||
|
auto_provision: true
|
||||||
|
# Synapse URL
|
||||||
|
home_server: "https://matrix.axion1337.chat"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Problem 4: ElementWeb zeigt nicht automatisch OIDC-Button
|
||||||
|
|
||||||
|
### Symptom
|
||||||
|
- MAS läuft und hat OIDC konfiguriert
|
||||||
|
- ElementWeb zeigt nur "Sign in with username" oder "SAML login"
|
||||||
|
- Kein "Sign in with Authentik" Button
|
||||||
|
|
||||||
|
### Lösung
|
||||||
|
|
||||||
|
ElementWeb muss die MAS-Konfiguration kennen. Das geschieht über `.well-known/matrix/client`:
|
||||||
|
|
||||||
|
**Test:**
|
||||||
|
```bash
|
||||||
|
curl https://axion1337.chat/.well-known/matrix/client | jq '.authentication'
|
||||||
|
```
|
||||||
|
|
||||||
|
Sollte zurückgeben:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"flows": [
|
||||||
|
{
|
||||||
|
"stages": ["m.login.sso"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"identity_providers": [
|
||||||
|
{
|
||||||
|
"id": "authentik",
|
||||||
|
"name": "Authentik",
|
||||||
|
"icon": "...",
|
||||||
|
"brand": "custom"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Falls nicht: **ElementWeb Config in Element-Stack aktualisieren:**
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# apps/production/custom-configs/element-values.yaml
|
||||||
|
elementWeb:
|
||||||
|
config:
|
||||||
|
auth:
|
||||||
|
sso_redirect_options:
|
||||||
|
immediate: false
|
||||||
|
on_welcome_page: true
|
||||||
|
```
|
||||||
|
|
||||||
|
**Dann:**
|
||||||
|
```bash
|
||||||
|
git add apps/production/custom-configs/element-values.yaml
|
||||||
|
git commit -m "Fix: Enable SSO redirect in ElementWeb"
|
||||||
|
git push
|
||||||
|
flux reconcile kustomization production-apps --with-source
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Problem 5: User kann sich anmelden, aber Boje ist nicht in Matrix
|
||||||
|
|
||||||
|
### Symptom
|
||||||
|
- Authentik-Login funktioniert
|
||||||
|
- MAS zeigt User erfolgreich
|
||||||
|
- ElementWeb Login funktioniert
|
||||||
|
- **ABER**: User ist nicht in Synapse (check mit `kubectl exec -n matrix synapse ...`)
|
||||||
|
|
||||||
|
### Lösung
|
||||||
|
|
||||||
|
Das bedeutet: User wird nicht automatisch in Synapse provisioniert.
|
||||||
|
|
||||||
|
**MAS muss User zu Synapse erstellen:**
|
||||||
|
|
||||||
|
In MAS Secret, `access` Sektion:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
matrixAuthenticationService:
|
||||||
|
access:
|
||||||
|
# Synapse erlaubt neue User-Erstellung
|
||||||
|
homeserver: "https://matrix.axion1337.chat"
|
||||||
|
|
||||||
|
# Optional: User automatisch erstellen
|
||||||
|
registration_enabled: true
|
||||||
|
```
|
||||||
|
|
||||||
|
**Synapse-seitig** muss auch User-Erstellung erlaubt sein:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# apps/production/custom-configs/synapse-values.yaml
|
||||||
|
synapse:
|
||||||
|
additional:
|
||||||
|
registration:
|
||||||
|
config: |
|
||||||
|
enable_registration: true
|
||||||
|
enable_registration_without_token: false
|
||||||
|
# Token wird von MAS bereitgestellt
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Komplettes Test-Szenario
|
||||||
|
|
||||||
|
Nach allen Fixes:
|
||||||
|
|
||||||
|
1. **Browser 1**: `https://axion1337.chat` öffnen
|
||||||
|
2. Auf ElementWeb "Sign in" klicken
|
||||||
|
3. "Sign in with Authentik" klicken (sollte sichtbar sein)
|
||||||
|
4. Authentik-Login durchführen (akadmin)
|
||||||
|
5. Nach Login: Enrollment-Flow (nur falls neuer User)
|
||||||
|
6. Zurück zu ElementWeb
|
||||||
|
7. **Synapse prüfen**:
|
||||||
|
```bash
|
||||||
|
kubectl exec -it -n matrix deployment/synapse -- \
|
||||||
|
/usr/local/bin/psql -U synapse -d synapse -c "SELECT name, admin FROM users LIMIT 10;"
|
||||||
|
```
|
||||||
|
8. Neuer User sollte auftauchen
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Debugging-Commands (während Test)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Live MAS logs (folgen)
|
||||||
|
kubectl logs -n matrix -l app=matrix-authentication-service -f
|
||||||
|
|
||||||
|
# Authentik logs
|
||||||
|
kubectl logs -n authentik -l app.kubernetes.io/name=authentik -f
|
||||||
|
|
||||||
|
# Port-Forward für manuelles Testen
|
||||||
|
kubectl port-forward -n matrix svc/matrix-authentication-service 8765:8080
|
||||||
|
|
||||||
|
# MAS Secret auslesen (im Cluster)
|
||||||
|
kubectl get secret ess-mas-values-secret -n matrix -o jsonpath='{.data.values\.yaml}' | base64 -d
|
||||||
|
|
||||||
|
# Synapse User-Liste
|
||||||
|
kubectl exec -it -n matrix deployment/synapse -- \
|
||||||
|
/usr/local/bin/psql -U synapse -d synapse -c "SELECT name, admin, is_guest FROM users;"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Checkliste für erfolgreichen Fix
|
||||||
|
|
||||||
|
- [ ] MAS Secret decrypted, upstream_oauth2_config eingetragen
|
||||||
|
- [ ] Client ID + Secret von Authentik kopiert
|
||||||
|
- [ ] MAS Secret re-encrypted und commited
|
||||||
|
- [ ] Authentik Enrollment Flow überprüft
|
||||||
|
- [ ] OIDC Provider in Authentik aktiv
|
||||||
|
- [ ] OIDC Application "matrix" in Authentik existiert
|
||||||
|
- [ ] MAS Pod neu gestartet (nach Secret-Change)
|
||||||
|
- [ ] ElementWeb zeigt OIDC-Button
|
||||||
|
- [ ] Test-Login durchgeführt
|
||||||
|
- [ ] Neuer User in Synapse DB vorhanden
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Fragen?** → Siehe `DIAGNOSTIK-AUTHENTIK-FLOW.md` für tiefergehende Diagnose.
|
||||||
@@ -0,0 +1,244 @@
|
|||||||
|
# 🔧 Authentik Invitation Flow Fix – Für Einladungslinks
|
||||||
|
|
||||||
|
**Problem**:
|
||||||
|
- Standard Enrollment (akadmin): ✅ funktioniert
|
||||||
|
- Invitation Flow (Boje über Einladungslink): ❌ Nur Username gefragt, keine Email
|
||||||
|
- Nach Enrollment: "Fehler fehlende Rechte"
|
||||||
|
|
||||||
|
**Root Cause**: Invitation Flow erfasst nicht alle erforderlichen Felder (Email) für OIDC-Token-Generation.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 1: Diagnose im Authentik Admin UI
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Authentik Admin UI öffnen
|
||||||
|
kubectl port-forward -n authentik svc/authentik 9000:9000
|
||||||
|
# Browser: http://localhost:9000/
|
||||||
|
# Admin credentials: akadmin / (password)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.1 Überprüfe: Welche Flows existieren?
|
||||||
|
|
||||||
|
**Navigation**: Admin → Flows & Stages → Flows
|
||||||
|
|
||||||
|
Suche nach diesen Flows:
|
||||||
|
- [ ] `enrollment` – Standard Enrollment (für akadmin)
|
||||||
|
- [ ] `invitation` – Invitation Flow (für Einladungslinks)
|
||||||
|
- [ ] `default-authentication-flow` – Standard Login
|
||||||
|
|
||||||
|
### 1.2 Überprüfe: Standard Enrollment Flow (funktioniert)
|
||||||
|
|
||||||
|
**Navigation**: Flows → `enrollment` öffnen
|
||||||
|
|
||||||
|
**Stages sollten sein:**
|
||||||
|
```
|
||||||
|
1. Identify (if not exists)
|
||||||
|
└─ Binding: "Identification (if not exists)"
|
||||||
|
|
||||||
|
2. Write
|
||||||
|
└─ Binding: "Create or update user"
|
||||||
|
└─ Field bindings MUST include:
|
||||||
|
├─ username
|
||||||
|
├─ email ← WICHTIG
|
||||||
|
└─ name (optional)
|
||||||
|
|
||||||
|
3. (optional) Weitere Stages
|
||||||
|
|
||||||
|
4. Finish
|
||||||
|
```
|
||||||
|
|
||||||
|
**Wichtig**: Alle Felder müssen "required" sein (nicht optional).
|
||||||
|
|
||||||
|
### 1.3 Überprüfe: Invitation Flow (wahrscheinlich kaputt)
|
||||||
|
|
||||||
|
**Navigation**: Flows → `invitation` öffnen
|
||||||
|
|
||||||
|
**Problem**: Wahrscheinlich fehlt die "Email" Stage hier!
|
||||||
|
|
||||||
|
**Sollte sein:**
|
||||||
|
```
|
||||||
|
1. Invite Stage
|
||||||
|
└─ Binding: "Invite user"
|
||||||
|
|
||||||
|
2. Identification (if not exists)
|
||||||
|
└─ Binding: "Identify"
|
||||||
|
|
||||||
|
3. Prompt Stage (für zusätzliche Daten!)
|
||||||
|
└─ Binding: "Prompt for data"
|
||||||
|
└─ Fields: username, email, name, password
|
||||||
|
|
||||||
|
4. Write
|
||||||
|
└─ Binding: "Create or update user"
|
||||||
|
|
||||||
|
5. Finish
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 2: Reparatur der Invitation Flow
|
||||||
|
|
||||||
|
### Schritt 1: Neue "Prompt Stage" erstellen (falls nicht existiert)
|
||||||
|
|
||||||
|
**Navigation**: Admin → Flows & Stages → Stages
|
||||||
|
|
||||||
|
1. Klick "Create"
|
||||||
|
2. Name: `invitation-prompt` oder ähnlich
|
||||||
|
3. Type: **"Prompt Stage"**
|
||||||
|
4. Configure:
|
||||||
|
- [ ] **Fields to Prompt**:
|
||||||
|
- Username (required)
|
||||||
|
- Email (required) ← WICHTIG
|
||||||
|
- Name (optional)
|
||||||
|
- Password (optional, da OIDC)
|
||||||
|
|
||||||
|
5. Save
|
||||||
|
|
||||||
|
### Schritt 2: Invitation Flow reparieren
|
||||||
|
|
||||||
|
**Navigation**: Admin → Flows & Stages → Flows → `invitation`
|
||||||
|
|
||||||
|
**Stages in dieser Reihenfolge:**
|
||||||
|
|
||||||
|
```
|
||||||
|
Stage 1: Invite Stage
|
||||||
|
├─ Binding: "Invite"
|
||||||
|
├─ Required: Yes
|
||||||
|
|
||||||
|
Stage 2: Identification Stage
|
||||||
|
├─ Binding: "Identify" (oder "Identification (if not exists)")
|
||||||
|
├─ Required: No
|
||||||
|
|
||||||
|
Stage 3: [NEUE STAGE] Prompt für Email/Username
|
||||||
|
├─ Type: "Prompt Stage"
|
||||||
|
├─ Binding: "Prompt for data"
|
||||||
|
├─ Fields:
|
||||||
|
│ ├─ username (required)
|
||||||
|
│ ├─ email (required) ← ENTSCHEIDEND
|
||||||
|
│ └─ name (optional)
|
||||||
|
├─ Required: Yes
|
||||||
|
|
||||||
|
Stage 4: Write
|
||||||
|
├─ Binding: "Create or update user"
|
||||||
|
├─ User Creation Policies: (standard)
|
||||||
|
├─ Required: Yes
|
||||||
|
|
||||||
|
Stage 5: Finish
|
||||||
|
├─ Binding: "Finish"
|
||||||
|
├─ Required: Yes
|
||||||
|
```
|
||||||
|
|
||||||
|
**Speichern** und Testen!
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 3: Teste Invitation Flow
|
||||||
|
|
||||||
|
### Test 1: Neuen Einladungslink erstellen
|
||||||
|
|
||||||
|
**Navigation**: Admin → Users & Groups → Invitations
|
||||||
|
|
||||||
|
1. Klick "Create"
|
||||||
|
2. Expiry: 7 days
|
||||||
|
3. Create & Copy Link
|
||||||
|
|
||||||
|
### Test 2: Einladungslink öffnen (in neuem Browser/Inkognito)
|
||||||
|
|
||||||
|
1. Link öffnen
|
||||||
|
2. Enrollment Flow sollte jetzt:
|
||||||
|
- [ ] Username eingeben
|
||||||
|
- [ ] **Email eingeben** ← Das sollte jetzt da sein!
|
||||||
|
- [ ] Name eingeben (optional)
|
||||||
|
- [ ] "Sign in with Authentik" klicken (falls Authentik-Binding korrekt)
|
||||||
|
|
||||||
|
3. Nach Authentik-Login: User in Synapse erstellt?
|
||||||
|
```bash
|
||||||
|
kubectl exec -it -n matrix matrix-stack-postgres-0 -- \
|
||||||
|
psql -U synapse -d synapse -c "SELECT name FROM users WHERE created_ts > now() - interval '5 minutes';"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Test 3: Prüfe MAS Logs auf Fehler
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl logs -f matrix-stack-matrix-authentication-service-6b994b9fcf-qqcxz -n matrix | grep -i "error\|fail\|boje"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 4: Häufige Fehler & Lösungen
|
||||||
|
|
||||||
|
### Fehler 1: "Fehlende Rechte" nach Enrollment
|
||||||
|
|
||||||
|
**Symptom**: Enrollment abgeschlossen, aber Fehler auf Berechtigungsseite
|
||||||
|
|
||||||
|
**Ursachen**:
|
||||||
|
- [ ] Email-Feld wurde nicht erfasst
|
||||||
|
- [ ] OIDC-Token hat unvollständige Daten
|
||||||
|
- [ ] Synapse User konnte nicht erstellt werden (Duplikat?)
|
||||||
|
|
||||||
|
**Lösung**:
|
||||||
|
1. Authentik Logs prüfen: `kubectl logs -n authentik -l app.kubernetes.io/name=authentik -f | grep -i "error\|invitation"`
|
||||||
|
2. MAS Logs prüfen: `kubectl logs -f matrix-stack-matrix-authentication-service-6b994b9fcf-qqcxz -n matrix | grep -i "boje\|error"`
|
||||||
|
3. Synapse Logs prüfen: `kubectl logs -f -n matrix matrix-stack-synapse-0 | grep -i "boje\|register"`
|
||||||
|
|
||||||
|
### Fehler 2: "Stage not found" oder "Flow invalid"
|
||||||
|
|
||||||
|
**Ursache**: Invitation Flow hat Binding-Fehler
|
||||||
|
|
||||||
|
**Lösung**:
|
||||||
|
1. Admin UI → Flows → Invitation Flow öffnen
|
||||||
|
2. Alle Stages überprüfen, dass sie korrekt gebunden sind
|
||||||
|
3. Keine leeren/ungültigen Bindings
|
||||||
|
4. Save & Retry
|
||||||
|
|
||||||
|
### Fehler 3: Email-Feld wird nicht angezeigt
|
||||||
|
|
||||||
|
**Ursache**: Prompt Stage hat email nicht in Fields
|
||||||
|
|
||||||
|
**Lösung**:
|
||||||
|
1. Admin UI → Flows → Stages → Prompt Stage öffnen
|
||||||
|
2. Edit → Fields überprüfen
|
||||||
|
3. Email hinzufügen if missing:
|
||||||
|
- Field name: `email`
|
||||||
|
- Type: `email`
|
||||||
|
- Required: Yes
|
||||||
|
4. Save
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Erwarteter Ablauf nach Fix
|
||||||
|
|
||||||
|
1. Browser öffnet Einladungslink → Enrollment Flow
|
||||||
|
2. "Username eingeben" → z.B. "boje"
|
||||||
|
3. **"Email eingeben"** ← Sollte jetzt da sein
|
||||||
|
4. "Name eingeben" (optional)
|
||||||
|
5. "Weiter" oder "Mit Authentik anmelden"
|
||||||
|
6. Authentik Login
|
||||||
|
7. Enrollment abgeschlossen
|
||||||
|
8. User "boje" in Synapse DB angelegt
|
||||||
|
9. Login zu ElementWeb möglich
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Checkliste
|
||||||
|
|
||||||
|
- [ ] Authentik Admin UI geöffnet (port-forward 9000)
|
||||||
|
- [ ] Standard Enrollment Flow überprüft (funktioniert mit akadmin)
|
||||||
|
- [ ] Invitation Flow überprüft
|
||||||
|
- [ ] Prompt Stage existiert mit email field
|
||||||
|
- [ ] Invitation Flow hat alle 5 Stages in korrekter Reihenfolge
|
||||||
|
- [ ] Neuen Einladungslink erstellt und getestet
|
||||||
|
- [ ] Test-User hat Email eingeben können
|
||||||
|
- [ ] Test-User in Synapse DB nach Login
|
||||||
|
- [ ] MAS Logs zeigen keine Fehler
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Frage**: Stimmt das mit deiner Beobachtung überein - dass bei der Einladung **nur Username** gefragt wurde, aber **nicht die Email**?
|
||||||
|
|
||||||
|
Wenn ja, dann ist der Fix:
|
||||||
|
1. Prompt Stage erstellen/reparieren (mit email field)
|
||||||
|
2. Zur Invitation Flow hinzufügen
|
||||||
|
3. Testen
|
||||||
|
|
||||||
|
Soll ich dir noch mehr Detailschritte geben?
|
||||||
@@ -0,0 +1,261 @@
|
|||||||
|
# 🔍 Authentik Enrollment Flow – Diagnostik & Reparaturplan
|
||||||
|
|
||||||
|
**Symptom**:
|
||||||
|
- `akadmin` wurde manuell in Matrix-DB angelegt (funktioniert)
|
||||||
|
- `Boje` wurde nur in Authentik erstellt, nicht in Matrix-DB (kaputt)
|
||||||
|
- Beide sollen denselben Enrollment Flow verwenden
|
||||||
|
|
||||||
|
**Vermutung**: Die Authentik → MAS → Synapse Kette ist unterbrochen
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 1: Diagnose (Bestandsaufnahme)
|
||||||
|
|
||||||
|
### 1.1 Authentik Logs prüfen
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Authentik Server logs
|
||||||
|
kubectl logs -n authentik -l app.kubernetes.io/name=authentik -f | grep -i "oauth\|oidc\|enroll\|flow"
|
||||||
|
|
||||||
|
# Worker logs
|
||||||
|
kubectl logs -n authentik -l app.kubernetes.io/component=worker -f | grep -i "enroll"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Worauf achten**:
|
||||||
|
- Fehler bei "Enrollment create"?
|
||||||
|
- OIDC Token-Probleme?
|
||||||
|
- Flow-Validierungsfehler?
|
||||||
|
|
||||||
|
### 1.2 MAS (Matrix Authentication Service) Logs prüfen
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# MAS logs
|
||||||
|
kubectl logs -n matrix -l app=matrix-authentication-service -f | grep -i "oauth\|upstream\|user\|oidc"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Worauf achten**:
|
||||||
|
- Verbindung zu Authentik erfolgreich?
|
||||||
|
- Token-Validierung fehlgeschlagen?
|
||||||
|
- User-Provisioning-Fehler?
|
||||||
|
|
||||||
|
### 1.3 Synapse Logs prüfen
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Synapse logs (für User-Erstellung)
|
||||||
|
kubectl logs -n matrix -l app=synapse -f | grep -i "user\|provision\|register\|auth"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Worauf achten**:
|
||||||
|
- User-Registrierungs-Fehler?
|
||||||
|
- Provisioning-Fehler?
|
||||||
|
- Authentifizierungsprobleme?
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 2: Authentik UI Überprüfung
|
||||||
|
|
||||||
|
### 2.1 Enrollment Flow inspizieren
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Authentik UI öffnen
|
||||||
|
kubectl port-forward -n authentik svc/authentik 9000:9000
|
||||||
|
# → Browser: http://localhost:9000
|
||||||
|
# → Admin UI → Flows & Stages → "Enrollment" Flow suchen
|
||||||
|
```
|
||||||
|
|
||||||
|
**Checklist**:
|
||||||
|
- [ ] Flow existiert und heißt "Enrollment"
|
||||||
|
- [ ] Reihenfolge der Stages:
|
||||||
|
1. Identify (optional)
|
||||||
|
2. Write (User-Erstellung)
|
||||||
|
3. Enrollment (if-condition für neuen User)
|
||||||
|
4. Verification (optional)
|
||||||
|
- [ ] "Write Stage" bindet sich an:
|
||||||
|
- [ ] Username
|
||||||
|
- [ ] Email
|
||||||
|
- [ ] Name
|
||||||
|
- [ ] Alle Bindings sind "required" (nicht optional)
|
||||||
|
|
||||||
|
### 2.2 OIDC Provider in Authentik prüfen
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Über Authentik UI:
|
||||||
|
# Admin → Applications → Providers → "matrix-provider" (oder ähnlich)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Checklist**:
|
||||||
|
- [ ] Provider existiert
|
||||||
|
- [ ] Name: z.B. "matrix-provider"
|
||||||
|
- [ ] Client Type: "Confidential"
|
||||||
|
- [ ] Redirect URIs enthalten:
|
||||||
|
- [ ] `https://account.axion1337.chat/upstream/callback/*`
|
||||||
|
- [ ] `https://account.axion1337.chat/upstream/callback/01KQDJTR1ZVTG8JQ220F5BNBFZ` (exact)
|
||||||
|
- [ ] Scopes: `openid profile email`
|
||||||
|
- [ ] Client ID + Secret kopiert?
|
||||||
|
|
||||||
|
### 2.3 OIDC Application in Authentik
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Admin → Applications → Applications → "matrix"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Checklist**:
|
||||||
|
- [ ] Application existiert mit Slug "matrix"
|
||||||
|
- [ ] Provider ist zugewiesen
|
||||||
|
- [ ] Enrollment Flow ist zugewiesen (nicht "deny")
|
||||||
|
- [ ] Enrollment Flow ist die richtige (die von oben)
|
||||||
|
|
||||||
|
### 2.4 Test-User "Boje" inspizieren
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Admin → Directory → Users → "Boje"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Checklist**:
|
||||||
|
- [ ] Username: `boje`
|
||||||
|
- [ ] Email: `boje@...` (vorhanden?)
|
||||||
|
- [ ] Groups: Falls erforderlich, die richtigen Groups zugewiesen?
|
||||||
|
- [ ] Status: Active oder Disabled?
|
||||||
|
- [ ] Sessions: Aktive Logins?
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 3: MAS Konfiguration überprüfen
|
||||||
|
|
||||||
|
### 3.1 Current MAS Secret auslesen
|
||||||
|
|
||||||
|
Da der age-key nicht lokal verfügbar ist, müssen wir die Konfiguration im Cluster prüfen:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# MAS Config im Cluster auslesen (nicht verschlüsselt)
|
||||||
|
kubectl get secret ess-mas-values-secret -n matrix -o jsonpath='{.data.values\.yaml}' | base64 -d | yq . | head -100
|
||||||
|
```
|
||||||
|
|
||||||
|
**Worauf achten**:
|
||||||
|
- [ ] `upstream_oauth2_config` Block existiert
|
||||||
|
- [ ] `upstream_oauth2_config.issuer`: `https://auth.axion1337.chat/application/o/matrix/`
|
||||||
|
- [ ] `upstream_oauth2_config.client_id`: Authentik Client ID
|
||||||
|
- [ ] `upstream_oauth2_config.client_secret`: Authentik Client Secret (*)
|
||||||
|
- [ ] `upstream_oauth2_config.scopes`: `["openid", "profile", "email"]`
|
||||||
|
- [ ] `upstream_oauth2_config.user_mapping_provider`:
|
||||||
|
- `type`: "oidc"
|
||||||
|
- `config.localpart_template`: `{{ user.preferred_username }}`
|
||||||
|
- `config.display_name_template`: `{{ user.name }}`
|
||||||
|
- `config.email_template`: `{{ user.email }}`
|
||||||
|
|
||||||
|
### 3.2 MAS Pod exec – Config live prüfen
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# MAS Config im laufenden Pod inspizieren
|
||||||
|
kubectl exec -it -n matrix deployment/matrix-authentication-service -- cat /etc/mas/config.yaml | grep -A50 upstream_oauth2_config
|
||||||
|
```
|
||||||
|
|
||||||
|
**Worauf achten**:
|
||||||
|
- Config ist syntaktisch korrekt (YAML)?
|
||||||
|
- Indentierung ist richtig?
|
||||||
|
- Werte sind vorhanden?
|
||||||
|
|
||||||
|
### 3.3 MAS OIDC Discovery prüfen
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Authentik OIDC Discovery Endpoint
|
||||||
|
curl -s https://auth.axion1337.chat/application/o/matrix/.well-known/openid-configuration | jq .
|
||||||
|
|
||||||
|
# Sollte zurückgeben:
|
||||||
|
# {
|
||||||
|
# "issuer": "https://auth.axion1337.chat/application/o/matrix/",
|
||||||
|
# "token_endpoint": "https://auth.axion1337.chat/application/o/token/",
|
||||||
|
# "authorization_endpoint": "...",
|
||||||
|
# ...
|
||||||
|
# }
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 4: Login-Flow Testen
|
||||||
|
|
||||||
|
### 4.1 MAS Login UI öffnen
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Port-Forward zu MAS
|
||||||
|
kubectl port-forward -n matrix svc/matrix-authentication-service 8765:8080
|
||||||
|
# → Browser: http://localhost:8765
|
||||||
|
```
|
||||||
|
|
||||||
|
**Test**:
|
||||||
|
1. Auf MAS-Seite: "Sign in with Authentik" klicken
|
||||||
|
2. Authentik-Login durchführen
|
||||||
|
3. Auf Enrollment Flow warten
|
||||||
|
4. Neuen User erstellen (Test-Username, Email, Password)
|
||||||
|
5. Nach erfolgreicher Registrierung: Matrix home_server erhalten?
|
||||||
|
|
||||||
|
### 4.2 Fehlerberichte
|
||||||
|
|
||||||
|
Falls Fehler auftritt:
|
||||||
|
- [ ] Screenshot des Fehlers
|
||||||
|
- [ ] MAS logs auslesen: `kubectl logs -n matrix -l app=matrix-authentication-service --tail=50`
|
||||||
|
- [ ] Authentik logs auslesen: `kubectl logs -n authentik -l app.kubernetes.io/name=authentik --tail=50`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 5: Reparaturschritte (nachdem Diagnose klar ist)
|
||||||
|
|
||||||
|
### Falls MAS-Config fehlerhaft:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Secrets entschlüsseln (lokale Umgebung mit age-key erforderlich)
|
||||||
|
sops -d apps/production/custom-configs/mas-secret.yaml > /tmp/mas-secret-decrypted.yaml
|
||||||
|
|
||||||
|
# 2. Editor öffnen und Konfiguration reparieren
|
||||||
|
vim /tmp/mas-secret-decrypted.yaml
|
||||||
|
# → upstream_oauth2_config überprüfen und korrigieren
|
||||||
|
|
||||||
|
# 3. Wieder verschlüsseln
|
||||||
|
sops -e /tmp/mas-secret-decrypted.yaml > apps/production/custom-configs/mas-secret.yaml
|
||||||
|
|
||||||
|
# 4. Commiten
|
||||||
|
git add apps/production/custom-configs/mas-secret.yaml
|
||||||
|
git commit -m "Fix: Correct MAS upstream_oauth2_config for Authentik integration"
|
||||||
|
|
||||||
|
# 5. Flux triggern
|
||||||
|
flux reconcile kustomization production-apps --with-source
|
||||||
|
```
|
||||||
|
|
||||||
|
### Falls Authentik Enrollment Flow fehlerhaft:
|
||||||
|
|
||||||
|
1. Admin UI öffnen: `kubectl port-forward -n authentik svc/authentik 9000:9000`
|
||||||
|
2. Flows → Enrollment Flow öffnen
|
||||||
|
3. Stages überprüfen und in richtige Reihenfolge bringen:
|
||||||
|
- **Identify**: Benutzer identifizieren
|
||||||
|
- **Write**: Benutzer in DB speichern
|
||||||
|
- **Enrollment**: Weitere Felder (optional)
|
||||||
|
- **Finish**: Abschluss
|
||||||
|
4. Speichern
|
||||||
|
5. Neuen Test-User erstellen und Enrollment durchlaufen
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Erwartete Endergebnisse
|
||||||
|
|
||||||
|
Nach erfolgreichem Fix:
|
||||||
|
1. Benutzer klickt "Sign in with Authentik" auf MAS
|
||||||
|
2. Authentik-Login-Seite wird angezeigt
|
||||||
|
3. Nach Login: Enrollment Flow wird angezeigt
|
||||||
|
4. User füllt Formular aus
|
||||||
|
5. Nach "Finish": Authentik erstellt User UND verbindet zu Matrix
|
||||||
|
6. User wird in Matrix-DB angelegt (`_matrix_auth` prefix)
|
||||||
|
7. User kan sich bei ElementWeb anmelden
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 Nächster Schritt
|
||||||
|
|
||||||
|
Bitte folgende Diagnostik durchlaufen und mir die Output berichte:
|
||||||
|
|
||||||
|
1. **MAS Logs** (letzten 30 Zeilen)
|
||||||
|
2. **Authentik Logs** (letzten 30 Zeilen)
|
||||||
|
3. **MAS Secret (entschlüsselt)** – upstream_oauth2_config Block
|
||||||
|
4. **Authentik OIDC Discovery** Output
|
||||||
|
5. **Screenshots** der Authentik UI (Enrollment Flow, OIDC Provider, Application)
|
||||||
|
|
||||||
|
Damit kann ich dann genau sehen, wo der Bruch in der Kette ist! 🔗
|
||||||
Executable
+112
@@ -0,0 +1,112 @@
|
|||||||
|
# 🔧 Troubleshooting Guides
|
||||||
|
|
||||||
|
Dieser Ordner enthält detaillierte Troubleshooting- und Reparaturanleitungen für häufige Probleme bei der Authentik/MAS/Matrix Integration.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📖 Guides
|
||||||
|
|
||||||
|
### 1. **DIAGNOSTIK-AUTHENTIK-FLOW.md**
|
||||||
|
**Für**: Vollständige Diagnose des Authentik Enrollment Flows
|
||||||
|
**Wann**: Wenn Sie systematisch überprüfen möchten, ob die gesamte OIDC-Kette (Authentik → MAS → Synapse) funktioniert
|
||||||
|
**Umfasst**:
|
||||||
|
- Authentik Logs analysieren
|
||||||
|
- MAS Konfiguration überprüfen
|
||||||
|
- OIDC Discovery testen
|
||||||
|
- Enrollment Flow inspizieren
|
||||||
|
- Fehlersuche mit Debugging-Commands
|
||||||
|
|
||||||
|
**Status**: Nutzer Boje - Nur in Authentik erstellt, nicht in Synapse
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2. **AUTHENTIK-FIX-TEMPLATE.md**
|
||||||
|
**Für**: Konkrete Reparaturen bei MAS/Authentik Integration
|
||||||
|
**Wann**: Wenn Sie wissen, welches Problem Sie haben und schnelle Lösungen suchen
|
||||||
|
**Behandelt**:
|
||||||
|
- Problem 1: MAS kennt Authentik-OIDC nicht
|
||||||
|
- Problem 2: Authentik Enrollment Flow kaputt
|
||||||
|
- Problem 3: OIDC Token werden nicht weitergeleitet
|
||||||
|
- Problem 4: ElementWeb zeigt keinen OIDC-Button
|
||||||
|
- Problem 5: User in Authentik aber nicht in Synapse
|
||||||
|
|
||||||
|
**Status**: Best Practices für häufige Probleme
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 3. **AUTHENTIK-INVITATION-FLOW-FIX.md**
|
||||||
|
**Für**: Reparatur des Invitation Flows bei Einladungslinks
|
||||||
|
**Wann**: Wenn Nutzer via Einladungslink nicht korrekt erstellt werden
|
||||||
|
**Problem**: Invitation Flow erfasst nur Username, nicht Email/Name
|
||||||
|
**Lösung**:
|
||||||
|
- Prompt Stage mit Email-Feld erstellen/reparieren
|
||||||
|
- Zur Invitation Flow hinzufügen
|
||||||
|
- Testen mit neuem Einladungslink
|
||||||
|
|
||||||
|
**Status**: Nutzer Klaus - Fehler "kein ausstehender benutzer Anfrage wurde verweigert"
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 4. **AUTHENTIK-CREATE-INVITATION-FLOW.md** ⭐ **WICHTIGSTE ANLEITUNG**
|
||||||
|
**Für**: Neuen separaten Invitation Flow erstellen
|
||||||
|
**Wann**: Wenn nur ein `matrix-enrollment` Flow existiert (Standard + Invitations gemeinsam)
|
||||||
|
**Root Cause**: Flow-Konflikt durch gemeinsamen Flow
|
||||||
|
**Lösung** (Schritt-für-Schritt):
|
||||||
|
1. Neuen Flow `matrix-invitation` erstellen
|
||||||
|
2. 5 Stages konfigurieren (Invite → Identify → Prompt → Write → Finish)
|
||||||
|
3. Email-Feld in Prompt Stage hinzufügen
|
||||||
|
4. Invitations auf neuen Flow setzen
|
||||||
|
5. Testen
|
||||||
|
|
||||||
|
**Zeitaufwand**: ~20 Minuten
|
||||||
|
**Status**: Aktuell für Klaus/Boje notwendig
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 Schneller Einstieg
|
||||||
|
|
||||||
|
### Szenario 1: "Enrollment funktioniert nicht, ich weiß nicht warum"
|
||||||
|
→ **Start**: `DIAGNOSTIK-AUTHENTIK-FLOW.md`
|
||||||
|
|
||||||
|
### Szenario 2: "Einladungslink funktioniert nicht"
|
||||||
|
→ **Start**: `AUTHENTIK-CREATE-INVITATION-FLOW.md` (wenn nur ein Flow existiert)
|
||||||
|
→ oder `AUTHENTIK-INVITATION-FLOW-FIX.md` (wenn zwei Flows existieren)
|
||||||
|
|
||||||
|
### Szenario 3: "Ich kenne das Problem und brauche Lösungen"
|
||||||
|
→ **Start**: `AUTHENTIK-FIX-TEMPLATE.md`
|
||||||
|
|
||||||
|
### Szenario 4: "Alles ist kaputt, ich brauche alles Schritt-für-Schritt"
|
||||||
|
→ **Start**: `AUTHENTIK-CREATE-INVITATION-FLOW.md` → `AUTHENTIK-FIX-TEMPLATE.md` → `DIAGNOSTIK-AUTHENTIK-FLOW.md`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📋 Bekannte Probleme
|
||||||
|
|
||||||
|
| Problem | Nutzer | Guide | Status |
|
||||||
|
|---------|--------|-------|--------|
|
||||||
|
| Nur Standard Enrollment funktioniert | akadmin ✅ | - | Resolved |
|
||||||
|
| User nur in Authentik, nicht in Synapse | Boje | `DIAGNOSTIK-AUTHENTIK-FLOW.md` | In Progress |
|
||||||
|
| Einladungslink-Fehler: "kein ausstehender benutzer" | Klaus | `AUTHENTIK-CREATE-INVITATION-FLOW.md` | **Fixed (2026-07-27)** — `matrix-invitation` Flow hatte nur Invite+Prompt Stage-Bindings, beide auf `order=0`. Write/Password/Login-Stages fehlten komplett. Live gefixt + als Blueprint (`apps/authentik/authentik-blueprints.yaml`) reproduzierbar gemacht. |
|
||||||
|
| OIDC-Integration unklar | General | `AUTHENTIK-FIX-TEMPLATE.md` | Reference |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔗 Verwandte Dokumentation
|
||||||
|
|
||||||
|
- `../README.md` – Hauptdokumentation & Architektur
|
||||||
|
- `../TASKS.md` – Aufgabenliste & Meilensteine
|
||||||
|
- `../deployment-guides/` – Deployment-Anleitungen für andere Components
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 💡 Tipps
|
||||||
|
|
||||||
|
- **Immer Logs überprüfen** bevor man herumrät: `kubectl logs -f -n <namespace> <pod>`
|
||||||
|
- **Browser-Cache löschen** nach Authentik-Änderungen
|
||||||
|
- **Port-Forward nutzen** für lokales Testen: `kubectl port-forward -n authentik svc/authentik 9000:9000`
|
||||||
|
- **Kleine Tests machen** (einen User mit Invitation testen, nicht 10 auf einmal)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Zuletzt aktualisiert**: 2026-05-18
|
||||||
|
**Verfasser**: Claude Code + Thore
|
||||||
Reference in New Issue
Block a user