193 lines
5.5 KiB
Markdown
193 lines
5.5 KiB
Markdown
|
|
# Authelia OIDC Client Setup
|
||
|
|
|
||
|
|
One-time setup. Do this before running the app for the first time.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Step 1 — Generate the OIDC client secret
|
||
|
|
|
||
|
|
Run `secret.sh` on your **Authelia host** (needs `openssl` + `authelia` in PATH):
|
||
|
|
|
||
|
|
```bash
|
||
|
|
bash secret.sh
|
||
|
|
```
|
||
|
|
|
||
|
|
Output looks like:
|
||
|
|
|
||
|
|
```
|
||
|
|
=== Plaintext secret (app .env → OIDC_CLIENT_SECRET) ===
|
||
|
|
xK9mP2...64chars...
|
||
|
|
|
||
|
|
=== Authelia hash (configuration.yml → client_secret) ===
|
||
|
|
$argon2id$v=19$m=65536,t=3,p=4$...
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Step 2 — Save the plaintext secret
|
||
|
|
|
||
|
|
The plaintext secret is **only shown once**. Save it immediately to the app's env file on the LXC where the app will run:
|
||
|
|
|
||
|
|
```
|
||
|
|
# /etc/hsa/hsa.env (create this file, chmod 600, owned by the service user)
|
||
|
|
OIDC_CLIENT_SECRET=xK9mP2...64chars...
|
||
|
|
```
|
||
|
|
|
||
|
|
Full env file contents are documented in the app's README once we get there.
|
||
|
|
For now just save `OIDC_CLIENT_SECRET=<value>` somewhere safe.
|
||
|
|
|
||
|
|
**Never commit this file to git.** `.gitignore` already excludes `.env` files.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Step 3 — Generate the OIDC signing key (RSA / RS256)
|
||
|
|
|
||
|
|
Authelia needs a signing key for the JWTs it issues. **It must be RSA (RS256)** — OIDC
|
||
|
|
mandates RS256 as the baseline and Authelia rejects Ed25519/EdDSA for the OIDC JWKS.
|
||
|
|
|
||
|
|
Generate it and place it in the secrets dir, owned by the Authelia service user so the
|
||
|
|
process can read it (it runs non-root; a root-owned `chmod 600` key gives
|
||
|
|
`permission denied`):
|
||
|
|
|
||
|
|
```bash
|
||
|
|
sudo mkdir -p /tmp/oidc-rsa
|
||
|
|
sudo authelia crypto pair rsa generate --bits 2048 --directory /tmp/oidc-rsa
|
||
|
|
sudo install -o authelia -g authelia -m 600 /tmp/oidc-rsa/private.pem /etc/authelia/secrets/oidc_jwks.pem
|
||
|
|
sudo rm -rf /tmp/oidc-rsa
|
||
|
|
```
|
||
|
|
|
||
|
|
(Confirm the owner matches your other secrets: `ls -l /etc/authelia/secrets/`. Substitute
|
||
|
|
if it's not `authelia:authelia`.)
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Step 4 — Add the jwks + client block to configuration.yml
|
||
|
|
|
||
|
|
The key is referenced from the .pem file via Authelia's template filter, so it never gets
|
||
|
|
copied into the config. This requires enabling the template filter (see the note after the
|
||
|
|
block — it's a one-line systemd env var).
|
||
|
|
|
||
|
|
In `configuration.yml`, the full `identity_providers.oidc` section should look like this
|
||
|
|
(append the `hsa-tracker` entry if you already have other clients):
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
identity_providers:
|
||
|
|
oidc:
|
||
|
|
jwks:
|
||
|
|
- key_id: 'main'
|
||
|
|
algorithm: 'RS256'
|
||
|
|
use: 'sig'
|
||
|
|
key: {{ secret "/etc/authelia/secrets/oidc_jwks.pem" | mindent 10 "|" | msquote }}
|
||
|
|
clients:
|
||
|
|
- client_id: 'hsa-tracker'
|
||
|
|
client_name: 'HSA Receipt Tracker'
|
||
|
|
client_secret: '$argon2id$v=19$...' # the hash from secret.sh
|
||
|
|
public: false
|
||
|
|
authorization_policy: 'two_factor'
|
||
|
|
require_pkce: true
|
||
|
|
pkce_challenge_method: 'S256'
|
||
|
|
redirect_uris:
|
||
|
|
- 'https://hsa.maisym.com/callback'
|
||
|
|
- 'http://localhost:8080/callback' # for local dev testing
|
||
|
|
scopes:
|
||
|
|
- 'openid'
|
||
|
|
- 'profile'
|
||
|
|
- 'email'
|
||
|
|
- 'groups'
|
||
|
|
response_types:
|
||
|
|
- 'code'
|
||
|
|
grant_types:
|
||
|
|
- 'authorization_code'
|
||
|
|
token_endpoint_auth_method: 'client_secret_basic'
|
||
|
|
userinfo_signed_response_alg: 'none'
|
||
|
|
```
|
||
|
|
|
||
|
|
### Required: enable the template config filter
|
||
|
|
|
||
|
|
The `{{ secret ... }}` syntax above only works when Authelia's **template config filter**
|
||
|
|
is enabled — it's OFF by default. If you skip this, the `{{ ... }}` is passed to the YAML
|
||
|
|
parser raw and breaks the *entire* config file (symptom: `yaml: invalid map key` plus a
|
||
|
|
cascade of "X not configured" errors — those cascade errors are a red herring caused by
|
||
|
|
the file failing to parse).
|
||
|
|
|
||
|
|
Enable the filter on the service:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
sudo systemctl edit authelia
|
||
|
|
```
|
||
|
|
|
||
|
|
Add, save, exit:
|
||
|
|
|
||
|
|
```
|
||
|
|
[Service]
|
||
|
|
Environment=X_AUTHELIA_CONFIG_FILTERS=template
|
||
|
|
```
|
||
|
|
|
||
|
|
Confirm it registered before restarting:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
systemctl cat authelia | grep -i filter # should show your Environment line
|
||
|
|
```
|
||
|
|
|
||
|
|
Then restart (env changes need a full restart, not reload):
|
||
|
|
|
||
|
|
```bash
|
||
|
|
sudo systemctl restart authelia
|
||
|
|
```
|
||
|
|
|
||
|
|
### Gotchas worth knowing
|
||
|
|
|
||
|
|
- **The key must be RSA and readable by the Authelia service user.** Ed25519 is rejected
|
||
|
|
by the OIDC JWKS (RS256 is mandatory). A root-owned `chmod 600` key gives the process
|
||
|
|
`permission denied` — keep it in `/etc/authelia/secrets/` owned by `authelia`.
|
||
|
|
- **`authelia config validate` run manually shows false positives** for `jwt_secret` and
|
||
|
|
`storage encryption_key`, because the `*_FILE` secrets are injected by systemd and aren't
|
||
|
|
present in a manual shell. Under the running service they're fine — only trust the
|
||
|
|
`journalctl` output after a real restart for those two.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Step 5 — Create the hsa-users group and add both users
|
||
|
|
|
||
|
|
In your Authelia users file (typically `users_database.yml`), add `hsa-users` to the `groups` list for each user:
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
users:
|
||
|
|
jm:
|
||
|
|
disabled: false
|
||
|
|
displayname: 'JM'
|
||
|
|
password: '$argon2id$...'
|
||
|
|
email: 'jm@jmopines.com'
|
||
|
|
groups:
|
||
|
|
- 'admins'
|
||
|
|
- 'hsa-users'
|
||
|
|
```
|
||
|
|
|
||
|
|
Repeat for the second user.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Step 6 — Restart Authelia
|
||
|
|
|
||
|
|
Use `restart`, not `reload` — config-file and environment changes are only picked up on a
|
||
|
|
full restart. (The users/groups file in Step 5 is auto-reloaded by Authelia, but a restart
|
||
|
|
covers everything at once.)
|
||
|
|
|
||
|
|
```bash
|
||
|
|
sudo systemctl restart authelia
|
||
|
|
```
|
||
|
|
|
||
|
|
Verify it came up clean (no `level=error` or `level=fatal` lines):
|
||
|
|
|
||
|
|
```bash
|
||
|
|
journalctl -u authelia -n 20
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Verification
|
||
|
|
|
||
|
|
Once the app is running, opening `http://localhost:8080` (or `https://hsa.maisym.com`) should
|
||
|
|
redirect you to `auth.maisym.com`. After login + YubiKey 2FA it should land on a page showing
|
||
|
|
your identity and `[hsa-users]` group.
|