Retire Authentik now that every app logs in with Pocket ID

All of Authentik's applications (including Tailscale's tailnet login)
have moved to Pocket ID, and its only recent sign-ins were those
handovers. Drops its stack, the auth. route and DNS record, the auth
subdomain variables, Gotify's leftover hairpin entries, and the dockcheck
exclude; the docs now name Pocket ID as the SSO provider.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Phil
2026-10-31 10:07:39 -06:00
co-authored by Claude Opus 5.5
parent 2512f6cb86
commit 9b9be6a2f0
14 changed files with 23 additions and 165 deletions
+6 -6
View File
@@ -60,7 +60,7 @@ ansible-playbook dns.yml -i hosts.yml
```bash ```bash
# Deploy specific services using tags (now properly isolated) # Deploy specific services using tags (now properly isolated)
ansible-playbook site.yml -i hosts.yml --tags caddy --vault-password-file vault_pass ansible-playbook site.yml -i hosts.yml --tags caddy --vault-password-file vault_pass
ansible-playbook site.yml -i hosts.yml --tags authentik --vault-password-file vault_pass ansible-playbook site.yml -i hosts.yml --tags pocketid --vault-password-file vault_pass
ansible-playbook site.yml -i hosts.yml --tags gitea --vault-password-file vault_pass ansible-playbook site.yml -i hosts.yml --tags gitea --vault-password-file vault_pass
ansible-playbook site.yml -i hosts.yml --tags docker --vault-password-file vault_pass # entire docker role ansible-playbook site.yml -i hosts.yml --tags docker --vault-password-file vault_pass # entire docker role
ansible-playbook site.yml -i hosts.yml --tags services --vault-password-file vault_pass # all services only ansible-playbook site.yml -i hosts.yml --tags services --vault-password-file vault_pass # all services only
@@ -90,7 +90,7 @@ ansible-playbook site.yml -i hosts.yml --tags common,cron --vault-password-file
The docker role is now organized into logical service groups under `roles/docker/tasks/`: The docker role is now organized into logical service groups under `roles/docker/tasks/`:
- **infrastructure/**: Core platform components - **infrastructure/**: Core platform components
- Caddy (reverse proxy), Authentik (SSO), Dockge (container management) - Caddy (reverse proxy), Pocket ID (passkey SSO), Dockge (container management)
- **development/**: Development and collaboration tools - **development/**: Development and collaboration tools
- Gitea, ByteStash - Gitea, ByteStash
- **media/**: Content creation and consumption - **media/**: Content creation and consumption
@@ -137,7 +137,7 @@ The `dns.yml` playbook manages AWS Route53 records for both domains. All subdoma
- UFW firewall managed through Docker integration script - UFW firewall managed through Docker integration script
### Service Dependencies ### Service Dependencies
Many services depend on Authentik for SSO. When deploying new services, consider: Most services log in through Pocket ID (OIDC, passkeys) at `{{ subdomains.pocketid }}`. When deploying new services, consider:
- Whether SSO integration is needed - Whether SSO integration is needed
- Caddy routing configuration for subdomain access - Caddy routing configuration for subdomain access
- Network connectivity requirements within Docker stack - Network connectivity requirements within Docker stack
@@ -151,12 +151,12 @@ Services inside Docker containers cannot reach external domains that resolve to
```yaml ```yaml
extra_hosts: extra_hosts:
- "{{ subdomains.auth }}:{{ docker.hairpin_ip }}" - "{{ subdomains.pocketid }}:{{ docker.hairpin_ip }}"
- "{{ subdomains.cal }}:{{ docker.hairpin_ip }}" - "{{ subdomains.cal }}:{{ docker.hairpin_ip }}"
``` ```
Common domains requiring hairpinning fixes: Common domains requiring hairpinning fixes:
- `{{ subdomains.auth }}` (Authentik SSO) - `{{ subdomains.pocketid }}` (Pocket ID SSO)
- `{{ subdomains.cal }}` (Baikal CalDAV) - `{{ subdomains.cal }}` (Baikal CalDAV)
- Any service domain the container needs to communicate with - Any service domain the container needs to communicate with
@@ -192,5 +192,5 @@ networks:
external: true external: true
name: "{{ docker.network_name }}" name: "{{ docker.network_name }}"
extra_hosts: extra_hosts:
- "{{ subdomains.auth }}:{{ docker.hairpin_ip }}" - "{{ subdomains.pocketid }}:{{ docker.hairpin_ip }}"
``` ```
+3 -3
View File
@@ -14,7 +14,7 @@ The Docker role deploys and manages 21 self-hosted services organized into logic
### Infrastructure ### Infrastructure
- **Caddy** (Reverse proxy with automatic HTTPS) - **Caddy** (Reverse proxy with automatic HTTPS)
- **Authentik** (SSO/Identity Provider) - **Pocket ID** (passkey SSO/Identity Provider)
- **Dockge** (Container management) - **Dockge** (Container management)
### Development ### Development
@@ -84,7 +84,7 @@ Manages scheduled tasks and automation:
### [Docker Role](roles/docker/README.md) ### [Docker Role](roles/docker/README.md)
The most comprehensive role, deploying 21 containerized services organized into logical categories: The most comprehensive role, deploying 21 containerized services organized into logical categories:
- **Infrastructure**: Caddy reverse proxy, Authentik SSO, Dockge management - **Infrastructure**: Caddy reverse proxy, Pocket ID SSO, Dockge management
- **Development**: Gitea, ByteStash - **Development**: Gitea, ByteStash
- **Media**: Audiobookshelf, Kavita, Karakeep, Manyfold - **Media**: Audiobookshelf, Kavita, Karakeep, Manyfold
- **Productivity**: Paperless-NGX, Baikal, Syncthing, HeyForm, Dawarich, Obsidian LiveSync - **Productivity**: Paperless-NGX, Baikal, Syncthing, HeyForm, Dawarich, Obsidian LiveSync
@@ -132,7 +132,7 @@ ansible-playbook site.yml -i hosts.yml --tags services
# Deploy individual services # Deploy individual services
ansible-playbook site.yml -i hosts.yml --tags caddy ansible-playbook site.yml -i hosts.yml --tags caddy
ansible-playbook site.yml -i hosts.yml --tags authentik ansible-playbook site.yml -i hosts.yml --tags pocketid
``` ```
### Manage DNS Records ### Manage DNS Records
+2 -2
View File
@@ -25,8 +25,6 @@
ip: "{{ network.netcup_ip }}" ip: "{{ network.netcup_ip }}"
- name: "social" - name: "social"
ip: "{{ network.netcup_ip }}" ip: "{{ network.netcup_ip }}"
- name: "auth"
ip: "{{ network.netcup_ip }}"
- name: "audio" - name: "audio"
ip: "{{ network.netcup_ip }}" ip: "{{ network.netcup_ip }}"
- name: "books" - name: "books"
@@ -88,6 +86,8 @@
ip: "{{ network.netcup_ip }}" ip: "{{ network.netcup_ip }}"
- name: "sync" # kosync, replaced by Kavita - name: "sync" # kosync, replaced by Kavita
ip: "{{ network.netcup_ip }}" ip: "{{ network.netcup_ip }}"
- name: "auth" # Authentik, replaced by Pocket ID
ip: "{{ network.netcup_ip }}"
- name: "files" - name: "files"
ip: "{{ network.netcup_ip }}" ip: "{{ network.netcup_ip }}"
- name: "kanboard" - name: "kanboard"
-2
View File
@@ -4,7 +4,6 @@ secondary_domain: "nerder.land"
# Subdomain mappings # Subdomain mappings
subdomains: subdomains:
auth: "auth.{{ primary_domain }}"
git: "git.{{ primary_domain }}" git: "git.{{ primary_domain }}"
cal: "cal.{{ primary_domain }}" cal: "cal.{{ primary_domain }}"
docs: "docs.{{ primary_domain }}" docs: "docs.{{ primary_domain }}"
@@ -33,6 +32,5 @@ subdomains:
# Email domains for notifications # Email domains for notifications
email_domains: email_domains:
updates: "updates.{{ primary_domain }}" updates: "updates.{{ primary_domain }}"
auth_email: "auth@updates.{{ primary_domain }}"
git_email: "git@updates.{{ primary_domain }}" git_email: "git@updates.{{ primary_domain }}"
cal_email: "cal@updates.{{ primary_domain }}" cal_email: "cal@updates.{{ primary_domain }}"
+1 -1
View File
@@ -2,7 +2,7 @@
# Service categories for organization # Service categories for organization
service_categories: service_categories:
infrastructure: ["caddy", "authentik", "dockge", "gondulf"] infrastructure: ["caddy", "dockge", "gondulf"]
development: ["gitea", "bytestash"] development: ["gitea", "bytestash"]
media: ["audiobookshelf", "kavita", "hoarder", "manyfold"] media: ["audiobookshelf", "kavita", "hoarder", "manyfold"]
productivity: ["paperlessngx", "baikal", "syncthing", "heyform", "dawarich", "obsidian-livesync", "gokapi"] productivity: ["paperlessngx", "baikal", "syncthing", "heyform", "dawarich", "obsidian-livesync", "gokapi"]
+1 -1
View File
@@ -10,7 +10,7 @@ AutoMode=true
Notify=true Notify=true
# Exclude containers from checking # Exclude containers from checking
Exclude="authentik-postgresql-1,dawarich_redis,dawarich_db" Exclude="dawarich_redis,dawarich_db"
# Notification channels # Notification channels
NOTIFY_CHANNELS="gotify" NOTIFY_CHANNELS="gotify"
+7 -7
View File
@@ -12,7 +12,7 @@ Deploys and manages a comprehensive self-hosted infrastructure with 24 container
- **Firewall Integration**: UFW-Docker script properly configures firewall rules - **Firewall Integration**: UFW-Docker script properly configures firewall rules
### Security Features ### Security Features
- **Centralized SSO**: Authentik provides OIDC authentication for most services - **Centralized SSO**: Pocket ID provides passkey OIDC authentication for most services
- **Network Isolation**: Services restricted to appropriate network segments - **Network Isolation**: Services restricted to appropriate network segments
- **Container Hardening**: Non-root users, capability dropping, security options - **Container Hardening**: Non-root users, capability dropping, security options
- **Secret Management**: Ansible vault for sensitive configuration - **Secret Management**: Ansible vault for sensitive configuration
@@ -22,7 +22,7 @@ Deploys and manages a comprehensive self-hosted infrastructure with 24 container
### Infrastructure (`infrastructure/`) ### Infrastructure (`infrastructure/`)
- **Caddy** - Reverse proxy with automatic HTTPS (static IP: 172.20.0.5) - **Caddy** - Reverse proxy with automatic HTTPS (static IP: 172.20.0.5)
- **Authentik** - Enterprise authentication server (OIDC/SAML SSO) - **Pocket ID** - Passkey OIDC provider
- **Dockge** - Docker compose stack management UI - **Dockge** - Docker compose stack management UI
### Development (`development/`) ### Development (`development/`)
@@ -89,7 +89,7 @@ roles/docker/
│ ├── infrastructure/ │ ├── infrastructure/
│ │ ├── main.yml # Infrastructure category orchestrator │ │ ├── main.yml # Infrastructure category orchestrator
│ │ ├── caddy.yml # Reverse proxy │ │ ├── caddy.yml # Reverse proxy
│ │ └── authentik.yml # Authentication │ │ └── pocketid.yml # Authentication
│ ├── development/ │ ├── development/
│ │ ├── main.yml # Development category orchestrator │ │ ├── main.yml # Development category orchestrator
│ │ ├── gitea.yml # Git hosting │ │ ├── gitea.yml # Git hosting
@@ -135,7 +135,7 @@ ansible-playbook site.yml -i hosts.yml --tags infrastructure,monitoring
### Deploy Individual Services ### Deploy Individual Services
```bash ```bash
# Deploy specific services # Deploy specific services
ansible-playbook site.yml -i hosts.yml --tags authentik ansible-playbook site.yml -i hosts.yml --tags pocketid
ansible-playbook site.yml -i hosts.yml --tags gitea,bytestash ansible-playbook site.yml -i hosts.yml --tags gitea,bytestash
ansible-playbook site.yml -i hosts.yml --tags paperlessngx ansible-playbook site.yml -i hosts.yml --tags paperlessngx
``` ```
@@ -145,7 +145,7 @@ ansible-playbook site.yml -i hosts.yml --tags paperlessngx
### MMDL (Task Management) ### MMDL (Task Management)
- **URL**: https://tasks.thesatelliteoflove.com - **URL**: https://tasks.thesatelliteoflove.com
- **Initial Setup**: Visit `/install` endpoint first to run database migrations - **Initial Setup**: Visit `/install` endpoint first to run database migrations
- **Authentication**: Integrates with Authentik OIDC provider - **Authentication**: Integrates with the Pocket ID OIDC provider
- **Database**: Uses MySQL 8.0 with automatic schema migration - **Database**: Uses MySQL 8.0 with automatic schema migration
- **Features**: CalDAV integration, multiple account support, task management - **Features**: CalDAV integration, multiple account support, task management
@@ -181,7 +181,7 @@ The role uses a centralized variable hierarchy in `group_vars/all/`:
### Network Configuration ### Network Configuration
Services expect to be accessible via subdomains of configured domains: Services expect to be accessible via subdomains of configured domains:
- `auth.thesatelliteoflove.com` - Authentik - `id.thesatelliteoflove.com` - Pocket ID
- `git.thesatelliteoflove.com` - Gitea - `git.thesatelliteoflove.com` - Gitea
- `books.thesatelliteoflove.com` - Kavita - `books.thesatelliteoflove.com` - Kavita
- `tasks.thesatelliteoflove.com` - MMDL - `tasks.thesatelliteoflove.com` - MMDL
@@ -203,7 +203,7 @@ Services expect to be accessible via subdomains of configured domains:
- Restricted access for sensitive tools (Stirling PDF) - Restricted access for sensitive tools (Stirling PDF)
### Authentication ### Authentication
- Centralized SSO through Authentik for most services - Centralized SSO through Pocket ID for most services
- OAuth integration where supported - OAuth integration where supported
- Secure secret management through Ansible vault - Secure secret management through Ansible vault
@@ -1,27 +0,0 @@
- name: make authentik directories
ansible.builtin.file:
path: "{{ item}}"
state: directory
loop:
- /opt/stacks/authentik
- name: Template out the compose file
ansible.builtin.template:
src: authentik-compose.yml.j2
dest: /opt/stacks/authentik/compose.yml
owner: root
mode: '0644'
- name: Template out the .env file
ansible.builtin.template:
src: authentik-env.j2
dest: /opt/stacks/authentik/.env
owner: root
mode: '0640'
group: docker
- name: deploy authentik stack
community.docker.docker_compose_v2:
project_src: /opt/stacks/authentik
files:
- compose.yml
@@ -5,10 +5,6 @@
import_tasks: caddy.yml import_tasks: caddy.yml
tags: caddy tags: caddy
- name: Install authentik
import_tasks: authentik.yml
tags: authentik
- name: Install pocketid - name: Install pocketid
import_tasks: pocketid.yml import_tasks: pocketid.yml
tags: pocketid tags: pocketid
-4
View File
@@ -1,7 +1,3 @@
auth.thesatelliteoflove.com {
reverse_proxy authentik-server-1:9000
}
{{ subdomains.pocketid }} { {{ subdomains.pocketid }} {
reverse_proxy pocket-id:1411 reverse_proxy pocket-id:1411
} }
@@ -1,88 +0,0 @@
---
services:
postgresql:
image: docker.io/library/postgres:16-alpine
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"]
start_period: 20s
interval: 30s
retries: 5
timeout: 5s
volumes:
- database:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: ${PG_PASS:?database password required}
POSTGRES_USER: ${PG_USER:-authentik}
POSTGRES_DB: ${PG_DB:-authentik}
env_file:
- .env
trout:
image: docker.io/library/redis:alpine
command: --save 60 1 --loglevel warning
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "redis-cli ping | grep PONG"]
start_period: 20s
interval: 30s
retries: 5
timeout: 3s
volumes:
- trout:/data
server:
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2026.2.2}
restart: unless-stopped
command: server
environment:
AUTHENTIK_REDIS__HOST: trout
AUTHENTIK_POSTGRESQL__HOST: postgresql
AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik}
AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik}
AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
volumes:
- ./media:/media
- ./custom-templates:/templates
env_file:
- .env
depends_on:
- postgresql
- trout
worker:
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2026.2.2}
restart: unless-stopped
command: worker
environment:
AUTHENTIK_REDIS__HOST: trout
AUTHENTIK_POSTGRESQL__HOST: postgresql
AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik}
AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik}
AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
# `user: root` and the docker socket volume are optional.
# See more for the docker socket integration here:
# https://goauthentik.io/docs/outposts/integrations/docker
# Removing `user: root` also prevents the worker from fixing the permissions
# on the mounted folders, so when removing this make sure the folders have the correct UID/GID
# (1000:1000 by default)
user: root
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./media:/media
- ./certs:/certs
- ./custom-templates:/templates
env_file:
- .env
depends_on:
- postgresql
- trout
volumes:
database:
driver: local
trout:
driver: local
networks:
default:
external: true
name: {{ docker.network_name }}
-15
View File
@@ -1,15 +0,0 @@
PG_PASS={{ vault_authentik.postgres_password }}
AUTHENTIK_SECRET_KEY={{ vault_authentik.secret_key }}
# SMTP Host Emails are sent to
AUTHENTIK_EMAIL__HOST={{ smtp.host }}
AUTHENTIK_EMAIL__PORT=25
# Optionally authenticate (don't add quotation marks to your password)
AUTHENTIK_EMAIL__USERNAME={{ smtp.username }}
AUTHENTIK_EMAIL__PASSWORD={{ vault_smtp.password }}
# Use StartTLS
AUTHENTIK_EMAIL__USE_TLS=true
# Use SSL
AUTHENTIK_EMAIL__USE_SSL=false
AUTHENTIK_EMAIL__TIMEOUT=10
# Email address authentik will send from, should have a correct @domain
AUTHENTIK_EMAIL__FROM=auth@{{ email_domains.updates }}
@@ -11,7 +11,6 @@ services:
labels: labels:
mag37.dockcheck.update: true mag37.dockcheck.update: true
extra_hosts: extra_hosts:
- "{{ subdomains.auth }}:{{ docker.hairpin_ip }}"
- "{{ subdomains.gotify_assistant }}:{{ docker.hairpin_ip }}" - "{{ subdomains.gotify_assistant }}:{{ docker.hairpin_ip }}"
igotify-assistant: igotify-assistant:
@@ -27,7 +26,6 @@ services:
labels: labels:
mag37.dockcheck.update: true mag37.dockcheck.update: true
extra_hosts: extra_hosts:
- "{{ subdomains.auth }}:{{ docker.hairpin_ip }}"
- "{{ subdomains.gotify }}:{{ docker.hairpin_ip }}" - "{{ subdomains.gotify }}:{{ docker.hairpin_ip }}"
volumes: volumes:
+3 -3
View File
@@ -8,7 +8,7 @@
``` ```
roles/docker/tasks/ roles/docker/tasks/
├── main.yml (orchestrator) ├── main.yml (orchestrator)
├── infrastructure/ (caddy, authentik, dockge) ├── infrastructure/ (caddy, pocketid, dockge)
├── development/ (gitea, codeserver, bytestash) ├── development/ (gitea, codeserver, bytestash)
├── media/ (audiobookshelf, kavita, ghost, pinchflat, pinry, hoarder, manyfold) ├── media/ (audiobookshelf, kavita, ghost, pinchflat, pinry, hoarder, manyfold)
├── productivity/ (paperless, baikal, syncthing, mmdl, heyform, dawarich, palmr, obsidian-livesync) ├── productivity/ (paperless, baikal, syncthing, mmdl, heyform, dawarich, palmr, obsidian-livesync)
@@ -77,7 +77,7 @@
- Implement configuration validation with proper assertions - Implement configuration validation with proper assertions
### 10. Service dependency management ### 10. Service dependency management
- **Issue**: Some services depend on Authentik SSO but no startup ordering - **Issue**: Some services depend on Pocket ID SSO but no startup ordering
- **Solution**: Implement dependency checking and startup ordering - **Solution**: Implement dependency checking and startup ordering
### 11. Ansible best practices ### 11. Ansible best practices
@@ -137,5 +137,5 @@
## Notes ## Notes
- Current architecture is solid and much better organized for long-term maintainability - Current architecture is solid and much better organized for long-term maintainability
- Focus on high-impact, low-effort improvements first - Focus on high-impact, low-effort improvements first
- Leverage existing infrastructure (Gitea, Authentik) for automation - Leverage existing infrastructure (Gitea, Pocket ID) for automation
- Template-driven approach enables future dynamic configuration - Template-driven approach enables future dynamic configuration