net-kingdom/sso-mfa/k8s/authelia/README.md
tegwick a9aec541ec
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 4s
Implement NK-WP-0021 activity-core ops SSO least-privilege.
Seed LLDAP activity-core-operators, add membership runbook and helper,
restrict Authelia access on activity/temporal.coulomb.social to that
group (member one_factor + domain deny fallback), apply live, and verify
via Authelia check-policy plus unauthenticated edge redirects.
2026-07-22 15:47:26 +02:00

115 lines
4.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# T05b — Authelia (Authentication Frontend)
Authelia is the password-authentication frontend for the net-kingdom SSO stack.
It acts as an upstream OIDC provider for KeyCape: users are redirected here to
enter their password; Authelia validates credentials against LLDAP and returns
an authorization code to KeyCape, which then performs the MFA step via privacyIDEA.
**Important:** Authelia's access control policy is set to `one_factor` (password only).
MFA is handled exclusively by KeyCape + privacyIDEA. Do not change this to `two_factor`.
## Prerequisites
- T05a complete (LLDAP is Running and healthy, application groups created)
- `bootstrap/gen-secrets.sh` run and `secrets/authelia/secrets.env` populated in KeePassXC
- `kubectl` configured with cluster access
## Apply order
```bash
# 1. Create K8s Secret
cd sso-mfa/k8s/authelia
chmod +x create-secrets.sh
./create-secrets.sh
# 2. Apply manifests (order matters)
kubectl apply -f pvc.yaml
kubectl apply -f configmap.yaml
kubectl apply -f deployment.yaml
kubectl apply -f ingress.yaml
# 3. Wait for pod to be ready
# The startup probe allows 90 s for the initial LLDAP connection.
kubectl rollout status deployment/authelia -n sso --timeout=120s
```
## Configuration
All non-sensitive configuration is in `configmap.yaml` (mounted as `configuration.yml`).
Sensitive values are injected via `*_FILE` environment variables pointing to
Secret-mounted files (see `deployment.yaml` env section).
Key config points:
- `authentication_backend.ldap.url` — points to LLDAP cluster-internal service
- `identity_providers.oidc.clients[0].redirect_uris` — must match CP-NK-004 (`kc.coulomb.social`)
- `session.domain` — set to parent domain `coulomb.social` so cookies are valid across
both `auth.coulomb.social` and `kc.coulomb.social`
- `access_control.default_policy: one_factor` — fleet default; MFA is not Authelias job
- `access_control.rules` — domain allowlists by LLDAP group (see below)
### Domain rules (app operator groups)
Authelia evaluates `rules` top-down; **first match wins**. A rule that matches
`domain` but not `subject` is skipped, so non-members would fall through to
`default_policy` and stay allowed unless a later domain-only `deny` rule exists.
Pattern used for activity-core public hosts (NK-WP-0021):
```yaml
access_control:
default_policy: one_factor
rules:
- domain: app.example.com
subject: "group:app-operators"
policy: one_factor
- domain: app.example.com
policy: deny
```
| Host | Required LLDAP group |
|------|----------------------|
| `activity.coulomb.social` | `activity-core-operators` |
| `temporal.coulomb.social` | `activity-core-operators` |
Membership: `sso-mfa/k8s/lldap/OPERATOR-GROUPS.md`. Do **not** set `two_factor`
on these rules. Do **not** invent KeyCape OIDC clients for Traefik ForwardAuth
apps — the edge already calls Authelia `/api/verify`.
## Secrets managed
| Secret name | Keys | Purpose |
|-------------|------|---------|
| `authelia-secrets` | `jwt_secret` | Session JWT signing |
| | `session_secret` | Session cookie encryption |
| | `storage_encryption_key` | SQLite database encryption |
| | `ldap_password` | LDAP bind password (= `LLDAP_LDAP_USER_PASS`) |
| | `oidc_hmac_secret` | OIDC HMAC signing |
| | `oidc_issuer_private_key` | RSA-2048 private key for OIDC token signing |
| | `keycape_client_secret_hash` | Bcrypt hash of `AUTHELIA_KEYCAPE_CLIENT_SECRET` |
`create-secrets.sh` reads plaintext values from `secrets/authelia/secrets.env` and
`secrets/lldap/secrets.env`. It generates the bcrypt hash on the fly (requires
`python3+bcrypt` or `apache2-utils`). The RSA OIDC private key is generated
automatically if `AUTHELIA_OIDC_PRIVATE_KEY_FILE` is not set.
## Storage
`authelia-data` PVC (1 Gi, ReadWriteOnce) holds:
- `db.sqlite3` — SQLite database (user sessions, regulation data)
- `notification.txt` — notification log (filesystem notifier)
Back this PVC up alongside the LLDAP PVC.
## Verify
```bash
# Pod status
kubectl get pod -n sso -l app.kubernetes.io/name=authelia
# Health check
kubectl run -n sso --rm -it auth-test --image=busybox --restart=Never \
-- wget -qO- http://authelia.sso.svc.cluster.local:9091/api/health
# OIDC discovery (should return issuer + endpoints)
curl -s https://auth.coulomb.social/.well-known/openid-configuration | jq .
```