# Authentik Role Self-contained Authentik authentication server deployment using Podman and Unix sockets. ## Overview This role deploys Authentik as a containerized authentication service with: - **Unix socket IPC** for PostgreSQL and Valkey - **Rootless Podman** with systemd integration via Quadlet - **Self-contained permissions** management - **Caddy reverse proxy** configuration ## Architecture ``` ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ Caddy Proxy │ │ Authentik Pod │ │ Infrastructure │ │ │ │ │ │ │ │ auth.jnss.me │───▶│ ┌─────────────┐ │ │ PostgreSQL │ │ :443 │ │ │ Server │ │◄──▶│ (Unix Socket) │ │ │ │ │ :9443 │ │ │ │ │ │ │ └─────────────┘ │ │ Valkey │ │ │ │ ┌─────────────┐ │◄──▶│ (Unix Socket) │ │ │ │ │ Worker │ │ │ │ │ │ │ └─────────────┘ │ │ │ └─────────────────┘ └─────────────────┘ └─────────────────┘ ``` ## Dependencies - `postgresql` role (provides Unix socket infrastructure) - `valkey` role (provides Unix socket infrastructure) - `podman` role (provides container runtime) - `caddy` role (provides reverse proxy infrastructure) ## Configuration ### Required Variables ```yaml # Domain configuration authentik_domain: "auth.jnss.me" # Database credentials authentik_db_password: "{{ vault_authentik_db_password }}" authentik_secret_key: "{{ vault_authentik_secret_key }}" authentik_default_admin_password: "{{ vault_authentik_admin_password }}" # Infrastructure socket enablement postgresql_unix_socket_enabled: true valkey_unix_socket_enabled: true ``` ### Optional Variables ```yaml # Service configuration authentik_service_enabled: true authentik_service_state: "started" # Container version authentik_version: "latest" # Email configuration authentik_email_enabled: false authentik_email_host: "smtp.example.com" ``` ## Vault Variables Required ```yaml # Database password vault_authentik_db_password: "secure_db_password" # Authentik secret key (generate with: openssl rand -base64 32) vault_authentik_secret_key: "long_random_secret_key" # Admin user password vault_authentik_admin_password: "secure_admin_password" # Existing infrastructure passwords vault_valkey_password: "valkey_password" ``` ## Usage ### Basic Deployment ```yaml - hosts: auth_servers roles: - postgresql - valkey - podman - caddy - authentik ``` ### With Tags ```yaml # Deploy only database setup ansible-playbook site.yml -t database # Deploy only containers ansible-playbook site.yml -t containers # Deploy only Caddy config ansible-playbook site.yml -t caddy ``` ## File Structure ``` authentik/ ├── defaults/main.yml # Default variables ├── handlers/main.yml # Service handlers ├── meta/main.yml # Role dependencies ├── tasks/ │ ├── main.yml # Main orchestration │ ├── database.yml # Database setup │ └── cache.yml # Cache setup ├── templates/ │ ├── authentik.env.j2 # Environment variables │ ├── authentik.caddy.j2 # Caddy configuration │ ├── authentik-pod.container # Pod Quadlet file │ ├── authentik-server.container # Server Quadlet file │ └── authentik-worker.container # Worker Quadlet file └── README.md ``` ## Systemd Services The role creates the following systemd services: - `authentik-pod.service` - Main pod container - `authentik-server.service` - Web server container - `authentik-worker.service` - Background worker container ## Networking - **External**: HTTPS via Caddy on port 443 - **Internal**: Containers bind to `127.0.0.1:9000` (HTTP) and `127.0.0.1:9443` (HTTPS) - **Database**: Unix socket at `/var/run/postgresql/.s.PGSQL.5432` - **Cache**: Unix socket at `/var/run/valkey/valkey.sock` ## Security Features - **Rootless containers** via Podman - **Unix socket IPC** eliminates network exposure - **User isolation** with dedicated `authentik` system user - **Group-based socket access** for PostgreSQL and Valkey - **TLS termination** at Caddy proxy - **Security headers** configured in Caddy ## Troubleshooting ### Check Service Status ```bash systemctl status authentik-pod systemctl status authentik-server systemctl status authentik-worker ``` ### Check Logs ```bash journalctl -u authentik-server -f journalctl -u authentik-worker -f ``` ### Check Socket Connectivity ```bash # Test PostgreSQL socket sudo -u authentik psql -h /var/run/postgresql -U authentik authentik # Test Valkey socket sudo -u authentik redis-cli -s /var/run/valkey/valkey.sock -n 1 ping ``` ### Verify Container Status ```bash podman --user authentik pod ps podman --user authentik ps ``` ## Post-Deployment 1. **Access Web Interface**: Navigate to `https://auth.jnss.me` 2. **Login**: Use admin credentials from vault variables 3. **Configure Providers**: Set up OAuth2/SAML providers for services 4. **Create Applications**: Configure applications for SSO integration ## Maintenance ### Update Containers ```yaml # Update to specific version authentik_version: "2024.2.0" ``` ### Backup Data Important directories to backup: - `{{ authentik_data_dir }}` - Application data - `{{ authentik_media_dir }}` - Uploaded media - PostgreSQL database dump - Vault variables ## Integration Examples ### Protect Service with Authentik ```caddy service.example.com { forward_auth https://auth.jnss.me { uri /outpost.goauthentik.io/auth/caddy copy_headers Remote-User Remote-Name Remote-Email Remote-Groups } reverse_proxy localhost:8080 } ``` ## Technical Implementation Notes ### Unix Socket Access Solution This role implements a sophisticated solution for containerized Unix socket access: **Challenge**: Containers need to access Unix sockets owned by different system services (PostgreSQL, Valkey) while maintaining security isolation. **Solution Components**: 1. **User Namespace Preservation**: `--userns=host` in pod configuration - Preserves host UID/GID mapping within containers - Allows direct access to host socket files 2. **Group Membership Preservation**: `Annotation=run.oci.keep_original_groups=1` in containers - Ensures supplementary group memberships are maintained in containers - Enables access to postgres and valkey groups within containers 3. **Correct Redis URL Format**: `AUTHENTIK_CACHE__URL=unix://...?db=N&password=...` - Avoids Django Redis client URL parsing issues - Prevents incorrect port appending to Unix socket paths 4. **Host Service Integration**: Authentik user added to service groups - Added to `postgres` group for PostgreSQL socket access - Added to `valkey` group for Valkey socket access ### Container Architecture ``` ┌─────────────────────────────────────────────────────────────┐ │ Authentik Pod (--userns=host) │ │ │ │ ┌─────────────────┐ ┌─────────────────┐ │ │ │ Server Container│ │ Worker Container│ │ │ │ UID: 963 (host) │ │ UID: 963 (host) │ │ │ │ Groups: 963, │ │ Groups: 963, │ │ │ │ 968(postgres),│ │ 968(postgres),│ │ │ │ 965(valkey) │ │ 965(valkey) │ │ │ └─────────────────┘ └─────────────────┘ │ │ │ │ │ │ └────────────────────┴─────────────┐ │ └─────────────────────────────────────────────│─────────────┘ │ ┌───────────────▼──────────────┐ │ Host Unix Sockets │ │ │ │ /var/run/postgresql/ │ │ ├─ .s.PGSQL.5432 │ │ │ (postgres:postgres 0770) │ │ │ │ /var/run/valkey/ │ │ ├─ valkey.sock │ │ (valkey:valkey 0770) │ └──────────────────────────────┘ ``` ### Security Implications **Maintained Security**: - Container network isolation preserved (no `--network=host`) - Individual container user/group isolation - Standard Podman security features active - Principle of least privilege through group membership **Trade-offs**: - Containers share host user namespace (reduced UID isolation) - Group membership grants broader access to service files - Requires careful service group management ### Compatibility This solution is: - ✅ **Portable**: Works regardless of UID assignments - ✅ **Maintainable**: No custom subuid/subgid configuration - ✅ **Performant**: Unix sockets avoid TCP overhead - ✅ **Secure**: Maintains container isolation where it matters - ✅ **Standard**: Uses documented Podman/OCI features