- Change reverse_proxy from https:// to http:// backend - Use authentik_http_port instead of authentik_https_port - Remove unnecessary TLS transport configuration - Remove health check for non-existent endpoint This aligns the Ansible template with the working configuration where authentik only serves HTTP internally and Caddy handles SSL.
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
postgresqlrole (provides Unix socket infrastructure)valkeyrole (provides Unix socket infrastructure)podmanrole (provides container runtime)caddyrole (provides reverse proxy infrastructure)
Configuration
Required Variables
# 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
# 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
# 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
- hosts: auth_servers
roles:
- postgresql
- valkey
- podman
- caddy
- authentik
With Tags
# 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 containerauthentik-server.service- Web server containerauthentik-worker.service- Background worker container
Networking
- External: HTTPS via Caddy on port 443
- Internal: Containers bind to
127.0.0.1:9000(HTTP) and127.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
authentiksystem user - Group-based socket access for PostgreSQL and Valkey
- TLS termination at Caddy proxy
- Security headers configured in Caddy
Troubleshooting
Check Service Status
systemctl status authentik-pod
systemctl status authentik-server
systemctl status authentik-worker
Check Logs
journalctl -u authentik-server -f
journalctl -u authentik-worker -f
Check Socket Connectivity
# 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
podman --user authentik pod ps
podman --user authentik ps
Post-Deployment
- Access Web Interface: Navigate to
https://auth.jnss.me - Login: Use admin credentials from vault variables
- Configure Providers: Set up OAuth2/SAML providers for services
- Create Applications: Configure applications for SSO integration
Maintenance
Update Containers
# 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
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:
-
User Namespace Preservation:
--userns=hostin pod configuration- Preserves host UID/GID mapping within containers
- Allows direct access to host socket files
-
Group Membership Preservation:
Annotation=run.oci.keep_original_groups=1in containers- Ensures supplementary group memberships are maintained in containers
- Enables access to postgres and valkey groups within containers
-
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
-
Host Service Integration: Authentik user added to service groups
- Added to
postgresgroup for PostgreSQL socket access - Added to
valkeygroup for Valkey socket access
- Added to
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