chore: sync homelab ops, identity, and monitoring docs
This commit is contained in:
10
identity/.env.example
Normal file
10
identity/.env.example
Normal file
@@ -0,0 +1,10 @@
|
||||
TZ=America/Chicago
|
||||
|
||||
AUTHELIA_HOST=auth.paccoco.com
|
||||
AUTHELIA_STORAGE_POSTGRES_DB=authelia
|
||||
AUTHELIA_STORAGE_POSTGRES_USER=authelia
|
||||
AUTHELIA_STORAGE_POSTGRES_PASSWORD=CHANGE_ME
|
||||
AUTHELIA_STORAGE_ENCRYPTION_KEY=CHANGE_ME
|
||||
AUTHELIA_SESSION_SECRET=CHANGE_ME
|
||||
AUTHELIA_SESSION_REDIS_PASSWORD=CHANGE_ME
|
||||
AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET=CHANGE_ME
|
||||
65
identity/README.md
Normal file
65
identity/README.md
Normal file
@@ -0,0 +1,65 @@
|
||||
# Identity / SSO
|
||||
|
||||
This stack introduces Authelia as the homelab identity plane.
|
||||
|
||||
Current design choices:
|
||||
|
||||
- Authelia only, no LDAP yet
|
||||
- shared Postgres for durable storage
|
||||
- shared Redis for session storage
|
||||
- file-backed users database for initial bootstrap
|
||||
- Pangolin/Newt exposure at auth.paccoco.com
|
||||
|
||||
Why this shape:
|
||||
|
||||
- it gets a real SSO control plane online without dragging in extra moving parts
|
||||
- it matches the homelab preference for shared DB infrastructure over SQLite
|
||||
- file users are fine at this size and can be migrated to LDAP later if needed
|
||||
|
||||
Files:
|
||||
|
||||
- docker-compose.yaml
|
||||
- .env.example
|
||||
- authelia/configuration.yml.example
|
||||
- authelia/users_database.example.yml
|
||||
|
||||
Bootstrap:
|
||||
|
||||
1. Copy this directory to PD at /mnt/docker-ssd/docker/compose/identity
|
||||
2. Copy .env.example to .env and replace every CHANGE_ME
|
||||
3. Copy authelia/configuration.yml.example to authelia/configuration.yml
|
||||
4. Render concrete secrets into `authelia/configuration.yml`; do not leave template placeholders or `${...}` references in the live file.
|
||||
5. Copy authelia/users_database.example.yml to authelia/users_database.yml
|
||||
6. Create an Authelia password hash:
|
||||
|
||||
docker run --rm authelia/authelia:latest authelia crypto hash generate argon2 --password 'CHANGE_ME'
|
||||
|
||||
7. Replace the sample hash in users_database.yml
|
||||
8. Create the authelia database/user in shared Postgres
|
||||
9. Set `AUTHELIA_SESSION_REDIS_PASSWORD` from the live shared Redis stack on PD.
|
||||
10. Create a Pangolin resource:
|
||||
Domain: auth.paccoco.com
|
||||
Scheme: http
|
||||
Host: authelia
|
||||
Port: 9091
|
||||
11. Validate and start:
|
||||
|
||||
cd /mnt/docker-ssd/docker/compose/identity
|
||||
docker compose --env-file .env config
|
||||
docker compose --env-file .env up -d
|
||||
docker exec authelia authelia config validate --config /config/configuration.yml
|
||||
|
||||
This repo stage gives you the identity control plane itself.
|
||||
|
||||
OIDC client rollout is intentionally a second pass because it needs:
|
||||
|
||||
- a real signing-key strategy
|
||||
- per-app client IDs and secrets
|
||||
- app-specific callback URLs verified against live domains
|
||||
|
||||
First client recommendation:
|
||||
|
||||
- Grafana via Generic OAuth against Authelia OIDC
|
||||
- Keep Grafana local-admin login enabled for the first cutover so recovery is easy if the public auth route or claims mapping is wrong
|
||||
|
||||
Do not try to wire every app at once. Get Authelia healthy first, then cut services over one at a time.
|
||||
103
identity/authelia/configuration.yml.example
Normal file
103
identity/authelia/configuration.yml.example
Normal file
@@ -0,0 +1,103 @@
|
||||
# Render concrete values into configuration.yml on PD.
|
||||
# Do not rely on runtime env interpolation for this file.
|
||||
theme: auto
|
||||
default_2fa_method: totp
|
||||
|
||||
server:
|
||||
address: tcp://0.0.0.0:9091
|
||||
|
||||
log:
|
||||
level: info
|
||||
|
||||
totp:
|
||||
issuer: paccoco.com
|
||||
|
||||
authentication_backend:
|
||||
file:
|
||||
path: /config/users_database.yml
|
||||
watch: false
|
||||
password:
|
||||
algorithm: argon2
|
||||
|
||||
access_control:
|
||||
default_policy: deny
|
||||
rules:
|
||||
- domain:
|
||||
- '*.paccoco.com'
|
||||
policy: one_factor
|
||||
|
||||
session:
|
||||
secret: 'CHANGE_ME_SESSION_SECRET'
|
||||
name: authelia_session
|
||||
same_site: lax
|
||||
expiration: 8h
|
||||
inactivity: 1h
|
||||
remember_me: 30d
|
||||
redis:
|
||||
host: shared-redis
|
||||
port: 6379
|
||||
password: 'CHANGE_ME_REDIS_PASSWORD'
|
||||
cookies:
|
||||
- domain: paccoco.com
|
||||
authelia_url: https://auth.paccoco.com
|
||||
default_redirection_url: https://grafana.paccoco.com
|
||||
|
||||
storage:
|
||||
encryption_key: 'CHANGE_ME_STORAGE_ENCRYPTION_KEY'
|
||||
postgres:
|
||||
address: tcp://shared-postgres:5432
|
||||
database: 'authelia'
|
||||
schema: public
|
||||
username: 'authelia'
|
||||
password: 'CHANGE_ME_POSTGRES_PASSWORD'
|
||||
|
||||
identity_validation:
|
||||
reset_password:
|
||||
jwt_secret: 'CHANGE_ME_RESET_PASSWORD_JWT_SECRET'
|
||||
|
||||
notifier:
|
||||
filesystem:
|
||||
filename: /config/data/notification.txt
|
||||
|
||||
identity_providers:
|
||||
oidc:
|
||||
hmac_secret: 'CHANGE_ME_OIDC_HMAC_SECRET'
|
||||
jwks:
|
||||
- key_id: 'grafana'
|
||||
algorithm: 'RS256'
|
||||
use: 'sig'
|
||||
key: |
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
CHANGE_ME_OIDC_PRIVATE_KEY
|
||||
-----END PRIVATE KEY-----
|
||||
claims_policies:
|
||||
grafana:
|
||||
id_token:
|
||||
- email
|
||||
- email_verified
|
||||
- groups
|
||||
- preferred_username
|
||||
- name
|
||||
clients:
|
||||
- client_id: 'grafana'
|
||||
client_name: 'Grafana'
|
||||
client_secret: 'CHANGE_ME_GRAFANA_CLIENT_SECRET'
|
||||
public: false
|
||||
authorization_policy: 'one_factor'
|
||||
require_pkce: true
|
||||
pkce_challenge_method: 'S256'
|
||||
redirect_uris:
|
||||
- 'https://grafana.paccoco.com/login/generic_oauth'
|
||||
scopes:
|
||||
- openid
|
||||
- profile
|
||||
- email
|
||||
- groups
|
||||
response_types:
|
||||
- code
|
||||
grant_types:
|
||||
- authorization_code
|
||||
access_token_signed_response_alg: 'none'
|
||||
userinfo_signed_response_alg: 'none'
|
||||
token_endpoint_auth_method: 'client_secret_basic'
|
||||
claims_policy: 'grafana'
|
||||
8
identity/authelia/users_database.example.yml
Normal file
8
identity/authelia/users_database.example.yml
Normal file
@@ -0,0 +1,8 @@
|
||||
users:
|
||||
john:
|
||||
disabled: false
|
||||
displayname: John
|
||||
email: john@paccoco.com
|
||||
password: "$argon2id$v=19$m=65536,t=3,p=4$REPLACE$ME"
|
||||
groups:
|
||||
- admins
|
||||
30
identity/docker-compose.yaml
Normal file
30
identity/docker-compose.yaml
Normal file
@@ -0,0 +1,30 @@
|
||||
name: identity
|
||||
|
||||
services:
|
||||
authelia:
|
||||
image: authelia/authelia:latest
|
||||
container_name: authelia
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "9091:9091"
|
||||
environment:
|
||||
TZ: ${TZ}
|
||||
volumes:
|
||||
- /mnt/docker-ssd/docker/compose/identity/authelia/configuration.yml:/config/configuration.yml:ro
|
||||
- /mnt/docker-ssd/docker/compose/identity/authelia/users_database.yml:/config/users_database.yml:ro
|
||||
- /mnt/tank/docker/appdata/authelia:/config/data
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:9091/api/health >/dev/null 2>&1 || exit 1"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 5
|
||||
start_period: 45s
|
||||
networks:
|
||||
- ix-databases_shared-databases
|
||||
- pangolin
|
||||
|
||||
networks:
|
||||
ix-databases_shared-databases:
|
||||
external: true
|
||||
pangolin:
|
||||
external: true
|
||||
Reference in New Issue
Block a user