Files
Thore Cimbal f6d2761025 feat: add the concierge bot for expiring guest invitations
Turns guest onboarding from an admin-only click in the Authentik UI into a traceable command a defined circle can run: !einladen creates a single-use invitation valid for three days, !verlaengern extends it twice at most, !freischalten makes it permanent, and expired accounts are deactivated automatically.

Authorisation is deliberately twofold - the Authentik group decides, the invite room makes it visible. A group alone leaves no trace of who invited whom; a room alone would authorise anyone who gets in.

Two deployment details matter: exactly one replica with Recreate, because a second instance would execute every command twice; and the script ConfigMap keeps its name hash so a change actually restarts the pod, avoiding the trap described in #50.

Endpoints and field names were taken from the running Authentik OpenAPI schema, not guessed. Refs axion1337.chat/axion1337.chat-gitops#48
2026-08-09 12:00:00 +00:00

86 lines
2.8 KiB
YAML

# @concierge - Gaeste-Einladungen (gitops#48). Skript: concierge-bot.py,
# als ConfigMap ueber den configMapGenerator in kustomization.yaml.
apiVersion: apps/v1
kind: Deployment
metadata:
name: concierge-bot
namespace: matrix
spec:
# ⚠️ Genau EINE Instanz. Der Bot haelt eine /sync-Schleife und verarbeitet
# Kommandos; zwei Instanzen wuerden jedes Kommando doppelt ausfuehren und
# jede Meldung doppelt posten. Deshalb replicas: 1 UND Recreate - bei
# RollingUpdate liefen waehrend eines Deploys kurzzeitig zwei.
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: concierge-bot
template:
metadata:
labels:
app: concierge-bot
spec:
securityContext:
runAsNonRoot: true
runAsUser: 10001
runAsGroup: 10001
seccompProfile:
type: RuntimeDefault
containers:
- name: bot
image: python:3.12-alpine
command: ["python3", "/app/concierge-bot.py"]
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
env:
- name: MATRIX_HOMESERVER
value: "https://matrix.axion1337.chat"
# Der Einladungsraum. ⚠️ Muss invite-only sein - der Bot prueft zwar
# zusaetzlich die Authentik-Gruppe, aber ein offener Raum macht
# sichtbar, wer eingeladen wurde, und das ist der halbe Zweck.
- name: MATRIX_ROOM_ID
valueFrom:
secretKeyRef:
name: concierge-credentials
key: matrix-room-id
# In-Cluster, nicht ueber die oeffentliche Adresse: spart den Umweg
# ueber Traefik und funktioniert auch, wenn extern etwas klemmt.
- name: AUTHENTIK_URL
value: "http://authentik-server.authentik.svc.cluster.local"
- name: MATRIX_TOKEN_FILE
value: /secrets/matrix-token
- name: AUTHENTIK_TOKEN_FILE
value: /secrets/authentik-token
- name: GUEST_DAYS
value: "3"
- name: MAX_RENEWALS
value: "2"
volumeMounts:
- name: script
mountPath: /app
readOnly: true
- name: creds
mountPath: /secrets
readOnly: true
- name: tmp
mountPath: /tmp
resources:
requests:
cpu: 10m
memory: 32Mi
limits:
memory: 128Mi
volumes:
- name: script
configMap:
name: concierge-bot-script
- name: creds
secret:
secretName: concierge-credentials
- name: tmp
emptyDir: {}