Files
rick-infra/roles/authentik/README.md
Joakim b42ee2a22b Fix: Complete authentik Quadlet implementation with networking solution
Resolves authentik deployment issues by implementing proper Podman Quadlet
configuration and fixing networking for external access through Caddy.

Core Fixes:
• Add missing [Install] sections to container Quadlet files for systemd service generation
• Fix pod references from 'systemd-authentik' to 'authentik.pod' for proper Quadlet linking
• Remove problematic --userns=host to use proper rootless user namespaces
• Configure subuid/subgid ranges for authentik user (200000:65536)
• Update networking to bind 0.0.0.0:9000 only (remove unnecessary HTTPS port 9443)
• Add AUTHENTIK_LISTEN__HTTP=0.0.0.0:9000 environment configuration
• Fix Caddy reverse proxy to use HTTP backend instead of HTTPS

Infrastructure Updates:
• Enhance PostgreSQL role with Unix socket configuration and user management
• Improve Valkey role with proper systemd integration and socket permissions
• Add comprehensive service integration documentation
• Update deployment playbooks with backup and restore capabilities

Security Improvements:
• Secure network isolation with Caddy SSL termination
• Reduced attack surface by removing direct HTTPS container exposure
• Proper rootless container configuration with user namespace mapping

Result: authentik now fully operational with external HTTPS access via auth.jnss.me
All systemd services (authentik-pod, authentik-server, authentik-worker) running correctly.
2025-12-04 19:42:31 +01:00

306 lines
10 KiB
Markdown

# 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