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.
115 lines
4.3 KiB
Markdown
115 lines
4.3 KiB
Markdown
# 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 Authelia’s 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 .
|
||
```
|