Files
net-kingdom/sso-mfa/k8s/network-policies/netpol-sso.yaml
Bernd Worsch 0754dc32e6 feat(sso-mfa): T05 SSO stack pivot — Keycloak → Authelia + LLDAP + KeyCape (NK-WP-0001-T05)
Replaces the Keycloak+privacyIDEA SSO tier with the lightweight stack built
during KEY-WP-0001: Authelia (password frontend), LLDAP (directory), and
KeyCape (OIDC orchestration). privacyIDEA is retained as the MFA engine.

Stack:
  kc.coulomb.social   — KeyCape OIDC server (stateless, custom Go)
  auth.coulomb.social — Authelia login portal (password auth → Authelia OIDC → KeyCape)
  lldap.coulomb.social — LLDAP admin UI (IP-restricted)
  pink.coulomb.social — privacyIDEA MFA engine (unchanged)

Changes:
- Remove sso-mfa/k8s/keycloak/ (7 files)
- Add sso-mfa/k8s/lldap/ (pvc, deployment, middleware, ingress, create-secrets, README)
- Add sso-mfa/k8s/authelia/ (pvc, configmap, deployment, ingress, create-secrets, README)
- Add sso-mfa/k8s/keycape/ (deployment, middleware, ingress, create-secrets, create-pi-token, README)
- Update network-policies/netpol-sso.yaml for new component topology
- Update verify-t05.sh: checks LLDAP + Authelia + KeyCape (23 checks)
- Update CONFIG.md: fix CP-NK-004 (KeyCape), add CP-NK-005 (Authelia), CP-NK-006 (LLDAP)
- Update bootstrap/gen-secrets.sh: add LLDAP/Authelia/KeyCape sections, remove Keycloak
- Update k8s/README.md: network policy table reflects new traffic paths
- Add sso-mfa/WORKPLAN.md: resumable task checklist

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 08:31:51 +00:00

267 lines
7.8 KiB
YAML

# NetworkPolicies for the sso namespace (KeyCape + Authelia + LLDAP)
#
# Components in this namespace:
# keycape — OIDC orchestration layer (port 8080)
# authelia — authentication frontend (port 9091)
# lldap — LDAP directory (port 3890 LDAP, port 17170 Web UI)
#
# Allowed ingress paths:
# Traefik → keycape :8080 (OIDC endpoints, user-facing)
# Traefik → authelia :9091 (login portal, user-facing)
# Traefik → lldap :17170 (admin web UI; IP-restricted at Traefik layer)
#
# Allowed egress paths:
# keycape → authelia :9091 (OIDC callback orchestration)
# keycape → lldap :3890 (LDAP user lookups)
# keycape → mfa :8080 (privacyIDEA MFA check and token validation)
# authelia → lldap :3890 (LDAP authentication backend)
# all pods → kube-dns :53 (DNS resolution)
#
# No egress to databases namespace — KeyCape is stateless;
# LLDAP uses SQLite on a PVC (no external DB needed in lightweight mode).
# ── Default deny all ingress and egress ──────────────────────────────────────
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: sso
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
---
# ── Traefik → KeyCape :8080 ───────────────────────────────────────────────────
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-traefik-to-keycape
namespace: sso
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: keycape
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
podSelector:
matchLabels:
app.kubernetes.io/name: traefik
ports:
- port: 8080
protocol: TCP
---
# ── Traefik → Authelia :9091 ──────────────────────────────────────────────────
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-traefik-to-authelia
namespace: sso
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: authelia
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
podSelector:
matchLabels:
app.kubernetes.io/name: traefik
ports:
- port: 9091
protocol: TCP
---
# ── Traefik → LLDAP :17170 (admin web UI) ────────────────────────────────────
# IP-based restriction is enforced at the Traefik layer (lldap-admin-allowlist
# middleware in lldap/middleware.yaml). This NetworkPolicy opens the port;
# Traefik enforces the IP allowlist before traffic reaches LLDAP.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-traefik-to-lldap-ui
namespace: sso
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: lldap
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
podSelector:
matchLabels:
app.kubernetes.io/name: traefik
ports:
- port: 17170
protocol: TCP
---
# ── KeyCape → Authelia :9091 ──────────────────────────────────────────────────
# KeyCape redirects the browser to Authelia and exchanges auth codes at /token.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-keycape-to-authelia
namespace: sso
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: authelia
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app.kubernetes.io/name: keycape
ports:
- port: 9091
protocol: TCP
---
# ── KeyCape → LLDAP :3890 ────────────────────────────────────────────────────
# KeyCape queries LLDAP for user attributes after authentication.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-keycape-to-lldap
namespace: sso
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: lldap
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app.kubernetes.io/name: keycape
ports:
- port: 3890
protocol: TCP
---
# ── Authelia → LLDAP :3890 ───────────────────────────────────────────────────
# Authelia binds to LLDAP to validate credentials and resolve group membership.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-authelia-to-lldap
namespace: sso
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: lldap
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app.kubernetes.io/name: authelia
ports:
- port: 3890
protocol: TCP
---
# ── KeyCape egress → Authelia + LLDAP (within sso namespace) ─────────────────
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-keycape-egress-internal
namespace: sso
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: keycape
policyTypes:
- Egress
egress:
- to:
- podSelector:
matchLabels:
app.kubernetes.io/name: authelia
ports:
- port: 9091
protocol: TCP
- to:
- podSelector:
matchLabels:
app.kubernetes.io/name: lldap
ports:
- port: 3890
protocol: TCP
---
# ── KeyCape egress → privacyIDEA (mfa namespace) :8080 ───────────────────────
# KeyCape calls privacyIDEA to check and validate MFA tokens.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-keycape-egress-to-privacyidea
namespace: sso
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: keycape
policyTypes:
- Egress
egress:
- to:
- namespaceSelector:
matchLabels:
net-kingdom/component: mfa
ports:
- port: 8080
protocol: TCP
---
# ── Authelia egress → LLDAP (within sso namespace) ───────────────────────────
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-authelia-egress-to-lldap
namespace: sso
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: authelia
policyTypes:
- Egress
egress:
- to:
- podSelector:
matchLabels:
app.kubernetes.io/name: lldap
ports:
- port: 3890
protocol: TCP
---
# ── Allow egress DNS (all pods) ──────────────────────────────────────────────
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-egress-dns
namespace: sso
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
ports:
- port: 53
protocol: UDP
- port: 53
protocol: TCP