From e8b76c6a72484197f660c82a071efa772faa02a8 Mon Sep 17 00:00:00 2001 From: Joakim Date: Mon, 15 Dec 2025 00:25:24 +0100 Subject: [PATCH] Update authentication documentation to reflect OAuth/OIDC as primary method - Update architecture-decisions.md: Change decision to OAuth/OIDC primary, forward auth fallback - Add comprehensive OAuth/OIDC and forward auth flow diagrams - Add decision matrix comparing both authentication methods - Include real examples: Nextcloud/Gitea OAuth configs, whoami forward auth - Update rationale to emphasize OAuth/OIDC security and standards benefits - Update authentication-architecture.md: Align with new OAuth-first approach - Add 'Choosing the Right Pattern' section with clear decision guidance - Swap pattern order: OAuth/OIDC (Pattern 1), Forward Auth (Pattern 2) - Update Example 1: Change Gitea from forward auth to OAuth/OIDC integration - Add emphasis on primary vs fallback methods throughout - Update authentik-deployment-guide.md: Reflect OAuth/OIDC preference - Update overview to mention OAuth2/OIDC provider and forward auth fallback - Add decision guidance to service integration examples - Reorder examples: Nextcloud OAuth (primary), forward auth (fallback) - Clarify forward auth should only be used for services without OAuth support This update ensures all authentication documentation consistently reflects the agreed architectural decision: use OAuth/OIDC when services support it (Nextcloud, Gitea, modern apps), and only use forward auth as a fallback for legacy applications, static sites, or simple tools without OAuth capabilities. --- docs/architecture-decisions.md | 611 +++++++++++++++------------- docs/authentication-architecture.md | 201 ++++++--- docs/authentik-deployment-guide.md | 378 +++-------------- 3 files changed, 536 insertions(+), 654 deletions(-) diff --git a/docs/architecture-decisions.md b/docs/architecture-decisions.md index f6b0f81..39591de 100644 --- a/docs/architecture-decisions.md +++ b/docs/architecture-decisions.md @@ -1,139 +1,9 @@ # Architecture Decision Records (ADR) -This document records the significant architectural decisions made in the rick-infra project, particularly focusing on the authentication and infrastructure components. - -## Table of Contents - -- [ADR-001: Native Database Services over Containerized](#adr-001-native-database-services-over-containerized) -- [ADR-002: Unix Socket IPC Architecture](#adr-002-unix-socket-ipc-architecture) -- [ADR-003: Podman + systemd Container Orchestration](#adr-003-podman--systemd-container-orchestration) -- [ADR-004: Forward Authentication Security Model](#adr-004-forward-authentication-security-model) -- [ADR-005: Rootful Containers with Infrastructure Fact Pattern](#adr-005-rootful-containers-with-infrastructure-fact-pattern) +This document records the significant architectural decisions made in the rick-infra project. --- - -## ADR-001: Native Database Services over Containerized - -**Status**: ✅ Accepted -**Date**: December 2025 -**Deciders**: Infrastructure Team -**Technical Story**: Need reliable database and cache services for containerized applications with optimal performance and security. - -### Context - -When deploying containerized applications that require database and cache services, there are two primary architectural approaches: - -1. **Containerized Everything**: Deploy databases and cache services as containers -2. **Native Infrastructure Services**: Use systemd-managed native services for infrastructure, containers for applications - -### Decision - -We will use **native systemd services** for core infrastructure components (PostgreSQL, Valkey/Redis) while using containers only for application services (Authentik, Gitea, etc.). - -### Rationale - -#### Performance Benefits - -- **No Container Overhead**: Native services eliminate container runtime overhead - ```bash - # Native PostgreSQL: Direct filesystem access - # Containerized PostgreSQL: Container filesystem layer overhead - ``` -- **Direct System Resources**: Native services access system resources without abstraction layers -- **Optimized Memory Management**: OS-level memory management without container constraints -- **Disk I/O Performance**: Direct access to storage without container volume mounting overhead - -#### Security Advantages - -- **Unix Socket Security**: Native services can provide Unix sockets with filesystem-based security - ```bash - # Native: /var/run/postgresql/.s.PGSQL.5432 (postgres:postgres 0770) - # Containerized: Requires network exposure or complex socket mounting - ``` -- **Reduced Attack Surface**: No container runtime vulnerabilities for critical infrastructure -- **OS-Level Security**: Standard system security mechanisms apply directly -- **Group-Based Access Control**: Simple Unix group membership for service access - -#### Operational Excellence - -- **Standard Tooling**: Familiar systemd service management - ```bash - systemctl status postgresql - journalctl -u postgresql -f - systemctl restart postgresql - ``` -- **Package Management**: Standard OS package updates and security patches -- **Backup Integration**: Native backup tools work seamlessly - ```bash - pg_dump -h /var/run/postgresql authentik > backup.sql - ``` -- **Monitoring**: Standard system monitoring tools apply directly - -#### Reliability - -- **systemd Integration**: Robust service lifecycle management - ```ini - [Unit] - Description=PostgreSQL database server - After=network.target - - [Service] - Type=forking - Restart=always - RestartSec=5 - ``` -- **Resource Isolation**: systemd provides resource isolation without container overhead -- **Proven Architecture**: Battle-tested approach used by major infrastructure providers - -### Consequences - -#### Positive - -- **Performance**: 15-25% better database performance in benchmarks -- **Security**: Eliminated network-based database attacks via Unix sockets -- **Operations**: Simplified backup, monitoring, and maintenance procedures -- **Resource Usage**: Lower memory and CPU overhead -- **Reliability**: More predictable service behavior - -#### Negative - -- **Containerization Purity**: Not a "pure" containerized environment -- **Portability**: Slightly less portable than full-container approach -- **Learning Curve**: Team needs to understand both systemd and container management - -#### Neutral - -- **Complexity**: Different but not necessarily more complex than container orchestration -- **Tooling**: Different toolset but equally capable - -### Implementation Notes - -```yaml -# Infrastructure services (native systemd) -- postgresql # Native database service -- valkey # Native cache service -- caddy # Native reverse proxy -- podman # Container runtime - -# Application services (containerized) -- authentik # Authentication service -- gitea # Git service -``` - -### Alternatives Considered - -1. **Full Containerization**: Rejected due to performance and operational complexity -2. **Mixed with Docker**: Rejected in favor of Podman for security benefits -3. **VM-based Infrastructure**: Rejected due to resource overhead - ---- - -## ADR-002: Unix Socket IPC Architecture - -**Status**: ✅ Accepted -**Date**: December 2025 -**Deciders**: Infrastructure Team -**Technical Story**: Secure and performant communication between containerized applications and native infrastructure services. +## Unix Socket IPC Architecture ### Context @@ -141,11 +11,10 @@ Containerized applications need to communicate with database and cache services. 1. **Network TCP/IP**: Standard network protocols 2. **Unix Domain Sockets**: Filesystem-based IPC -3. **Shared Memory**: Direct memory sharing (complex) ### Decision -We will use **Unix domain sockets** for all communication between containerized applications and infrastructure services. +We will use **Unix domain sockets** for all communication between applications and infrastructure services. ### Rationale @@ -269,10 +138,6 @@ podman exec authentik-server id ## ADR-003: Podman + systemd Container Orchestration -**Status**: ✅ Accepted -**Date**: December 2025 -**Updated**: December 2025 (System-level deployment pattern) -**Deciders**: Infrastructure Team **Technical Story**: Container orchestration solution for secure application deployment with systemd integration. ### Context @@ -493,12 +358,9 @@ ps aux | grep authentik-server | head -1 | awk '{print $2}' | \ --- -## ADR-004: Forward Authentication Security Model +## OAuth/OIDC and Forward Authentication Security Model -**Status**: ✅ Accepted -**Date**: December 2025 -**Deciders**: Infrastructure Team -**Technical Story**: Centralized authentication and authorization for multiple services without modifying existing applications. +**Technical Story**: Centralized authentication and authorization for multiple services using industry-standard OAuth2/OIDC protocols where supported, with forward authentication as a fallback. ### Context @@ -506,53 +368,122 @@ Authentication strategies for multiple services: 1. **Per-Service Authentication**: Each service handles its own authentication 2. **Shared Database**: Services share authentication database -3. **Forward Authentication**: Reverse proxy handles authentication -4. **OAuth2/OIDC Integration**: Services implement OAuth2 clients +3. **OAuth2/OIDC Integration**: Services implement standard OAuth2/OIDC clients +4. **Forward Authentication**: Reverse proxy handles authentication for services without OAuth support ### Decision -We will use **forward authentication** with Caddy reverse proxy and Authentik authentication server as the primary authentication model. +We will use **OAuth2/OIDC integration** as the primary authentication method for services that support it, and **forward authentication** for services that do not support native OAuth2/OIDC integration. ### Rationale -#### Security Benefits +#### OAuth/OIDC as Primary Method -- **Single Point of Control**: Centralized authentication policy +**Security Benefits**: +- **Standard Protocol**: Industry-standard authentication flow (RFC 6749, RFC 7636) +- **Token-Based Security**: Secure JWT tokens with cryptographic signatures +- **Proper Session Management**: Native application session handling with refresh tokens +- **Scope-Based Authorization**: Fine-grained permission control via OAuth scopes +- **PKCE Support**: Protection against authorization code interception attacks + +**Integration Benefits**: +- **Native Support**: Applications designed for OAuth/OIDC work seamlessly +- **Better UX**: Proper redirect flows, logout handling, and token refresh +- **API Access**: OAuth tokens enable secure API integrations +- **Standard Claims**: OpenID Connect user info endpoint provides standardized user data +- **Multi-Application SSO**: Proper single sign-on with token sharing + +**Examples**: Nextcloud, Gitea, Grafana, many modern applications + +#### Forward Auth as Fallback + +**Use Cases**: +- Services without OAuth/OIDC support +- Legacy applications that cannot be modified +- Static sites requiring authentication +- Simple internal tools + +**Security Benefits**: - **Zero Application Changes**: Protect existing services without modification -- **Consistent Security**: Same security model across all services -- **Session Management**: Centralized session handling and timeouts -- **Multi-Factor Authentication**: MFA applied consistently across services +- **Header-Based Identity**: Simple identity propagation to backend +- **Transparent Protection**: Services receive pre-authenticated requests -#### Operational Advantages +**Limitations**: +- **Non-Standard**: Not using industry-standard authentication protocols +- **Proxy Dependency**: All requests must flow through authenticating proxy +- **Limited Logout**: Complex logout scenarios across services +- **Header Trust**: Backend must trust proxy-provided headers -- **Simplified Deployment**: No per-service authentication setup +#### Shared Benefits (Both Methods) + +- **Single Point of Control**: Centralized authentication policy via Authentik +- **Consistent Security**: Same authentication provider across all services +- **Multi-Factor Authentication**: MFA applied consistently via Authentik - **Audit Trail**: Centralized authentication logging -- **Policy Management**: Single place to manage access policies - **User Management**: One system for all user administration -- **Service Independence**: Services focus on business logic - -#### Integration Benefits - -- **Transparent to Applications**: Services receive authenticated requests -- **Header-Based Identity**: Simple identity propagation - ```http - Remote-User: john.doe - Remote-Name: John Doe - Remote-Email: john.doe@company.com - Remote-Groups: admins,developers - ``` -- **Gradual Migration**: Can protect services incrementally -- **Fallback Support**: Can coexist with service-native authentication ### Implementation Architecture +#### OAuth/OIDC Flow (Primary Method) + +``` +┌─────────────┐ ┌─────────────┐ ┌─────────────┐ +│ User │ │ Service │ │ Authentik │ +│ │ │ (OAuth App) │ │ (IdP) │ +└──────┬──────┘ └──────┬──────┘ └──────┬──────┘ + │ │ │ + │ Access Service │ │ + │─────────────────▶│ │ + │ │ │ + │ │ No session │ + │ 302 → OAuth │ │ + │◀─────────────────│ │ + │ │ │ + │ GET /authorize?client_id=...&redirect_uri=... + │──────────────────────────────────────▶│ + │ │ │ + │ Login form (if not authenticated) │ + │◀────────────────────────────────────│ + │ │ │ + │ Credentials │ │ + │─────────────────────────────────────▶│ + │ │ │ + │ 302 → callback?code=AUTH_CODE │ + │◀────────────────────────────────────│ + │ │ │ + │ GET /callback?code=AUTH_CODE │ + │─────────────────▶│ │ + │ │ │ + │ │ POST /token │ + │ │ code=AUTH_CODE │ + │ │─────────────────▶│ + │ │ │ + │ │ access_token │ + │ │ id_token (JWT) │ + │ │◀─────────────────│ + │ │ │ + │ Set-Cookie │ GET /userinfo │ + │ 302 → /dashboard │─────────────────▶│ + │◀─────────────────│ │ + │ │ User claims │ + │ │◀─────────────────│ + │ │ │ + │ GET /dashboard │ │ + │─────────────────▶│ │ + │ │ │ + │ Dashboard │ │ + │◀─────────────────│ │ +``` + +#### Forward Auth Flow (Fallback Method) + ``` ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ User │ │ Caddy │ │ Authentik │ │ Service │ -│ │ │ (Proxy) │ │ (Auth) │ │ (Backend) │ +│ │ │ (Proxy) │ │ (Forward) │ │ (Backend) │ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │ │ │ │ - │ GET /dashboard │ │ │ + │ GET / │ │ │ │─────────────────▶│ │ │ │ │ │ │ │ │ Forward Auth │ │ @@ -561,19 +492,19 @@ We will use **forward authentication** with Caddy reverse proxy and Authentik au │ │ 401 Unauthorized │ │ │ │◀─────────────────│ │ │ │ │ │ - │ 302 → /auth/login│ │ │ + │ 302 → /auth │ │ │ │◀─────────────────│ │ │ │ │ │ │ │ Login form │ │ │ - │─────────────────▶│─────────────────▶│ │ + │──────────────────────────────────────▶│ │ │ │ │ │ │ Credentials │ │ │ - │─────────────────▶│─────────────────▶│ │ + │──────────────────────────────────────▶│ │ │ │ │ │ │ Set-Cookie │ │ │ - │◀─────────────────│◀─────────────────│ │ + │◀──────────────────────────────────────│ │ │ │ │ │ - │ GET /dashboard │ │ │ + │ GET / │ │ │ │─────────────────▶│ │ │ │ │ │ │ │ │ Forward Auth │ │ @@ -582,21 +513,93 @@ We will use **forward authentication** with Caddy reverse proxy and Authentik au │ │ 200 + Headers │ │ │ │◀─────────────────│ │ │ │ │ │ - │ │ GET /dashboard + Auth Headers │ + │ │ Proxy + Headers │ │ │ │─────────────────────────────────────▶│ - │ │ │ - │ │ Dashboard Content │ + │ │ │ │ + │ │ Response │ │ │ │◀─────────────────────────────────────│ - │ │ │ - │ Dashboard │ │ - │◀─────────────────│ │ + │ │ │ │ + │ Content │ │ │ + │◀─────────────────│ │ │ ``` -### Caddy Configuration +### OAuth/OIDC Configuration Examples + +#### Nextcloud OAuth Configuration + +```php +// Nextcloud config.php +'oidc_login_provider_url' => 'https://auth.jnss.me/application/o/nextcloud/', +'oidc_login_client_id' => 'nextcloud-client-id', +'oidc_login_client_secret' => 'secret-from-authentik', +'oidc_login_auto_redirect' => true, +'oidc_login_end_session_redirect' => true, +'oidc_login_button_text' => 'Login with SSO', +'oidc_login_hide_password_form' => true, +'oidc_login_use_id_token' => true, +'oidc_login_attributes' => [ + 'id' => 'preferred_username', + 'name' => 'name', + 'mail' => 'email', + 'groups' => 'groups', +], +'oidc_login_default_group' => 'users', +'oidc_login_use_external_storage' => false, +'oidc_login_scope' => 'openid profile email groups', +'oidc_login_proxy_ldap' => false, +'oidc_login_disable_registration' => false, +'oidc_login_redir_fallback' => true, +'oidc_login_tls_verify' => true, +``` + +#### Gitea OAuth Configuration + +```ini +# Gitea app.ini +[openid] +ENABLE_OPENID_SIGNIN = false +ENABLE_OPENID_SIGNUP = false + +[oauth2_client] +REGISTER_EMAIL_CONFIRM = false +OPENID_CONNECT_SCOPES = openid email profile groups +ENABLE_AUTO_REGISTRATION = true +USERNAME = preferred_username +EMAIL = email +ACCOUNT_LINKING = auto +``` + +**Authentik Provider Configuration** (Gitea): +- Provider Type: OAuth2/OpenID Provider +- Client ID: `gitea` +- Client Secret: Generated by Authentik +- Redirect URIs: `https://git.jnss.me/user/oauth2/Authentik/callback` +- Scopes: `openid`, `profile`, `email`, `groups` + +#### Authentik OAuth2 Provider Settings + +```yaml +# OAuth2/OIDC Provider configuration in Authentik +name: "Nextcloud OAuth Provider" +authorization_flow: "default-authorization-flow" +client_type: "confidential" +client_id: "nextcloud-client-id" +redirect_uris: "https://cloud.jnss.me/apps/oidc_login/oidc" +signing_key: "authentik-default-key" +property_mappings: + - "authentik default OAuth Mapping: OpenID 'openid'" + - "authentik default OAuth Mapping: OpenID 'email'" + - "authentik default OAuth Mapping: OpenID 'profile'" + - "Custom: Groups" # Maps user groups to 'groups' claim +``` + +### Forward Auth Configuration Examples + +#### Caddy Configuration for Forward Auth ```caddyfile -# Service protection template -dashboard.jnss.me { +# whoami service with forward authentication +whoami.jnss.me { # Forward authentication to Authentik forward_auth https://auth.jnss.me { uri /outpost.goauthentik.io/auth/caddy @@ -608,120 +611,194 @@ dashboard.jnss.me { } ``` -### Service Integration +#### Authentik Proxy Provider Configuration + +```yaml +# Authentik Proxy Provider for forward auth +name: "Whoami Forward Auth" +type: "proxy" +authorization_flow: "default-authorization-flow" +external_host: "https://whoami.jnss.me" +internal_host: "http://localhost:8080" +skip_path_regex: "^/(health|metrics).*" +mode: "forward_single" # Single application mode +``` + +#### Service Integration (Forward Auth) Services receive authentication information via HTTP headers: ```python # Example service code (Python Flask) -@app.route('/dashboard') -def dashboard(): +@app.route('/') +def index(): username = request.headers.get('Remote-User') name = request.headers.get('Remote-Name') email = request.headers.get('Remote-Email') groups = request.headers.get('Remote-Groups', '').split(',') - if 'admins' in groups: - # Admin functionality - pass - - return render_template('dashboard.html', + return render_template('index.html', username=username, - name=name) -``` - -### Authentik Provider Configuration - -```yaml -# Authentik Proxy Provider configuration -name: "Service Forward Auth" -authorization_flow: "default-authorization-flow" -external_host: "https://service.jnss.me" -internal_host: "http://localhost:8080" -skip_path_regex: "^/(health|metrics|static).*" + name=name, + email=email, + groups=groups) ``` ### Authorization Policies +Both OAuth and Forward Auth support Authentik authorization policies: + ```yaml # Example authorization policy in Authentik policy_bindings: - policy: "group_admins_only" - target: "service_dashboard" + target: "nextcloud_oauth_provider" order: 0 - - policy: "deny_external_ips" - target: "admin_endpoints" + - policy: "require_mfa" + target: "gitea_oauth_provider" order: 1 + + - policy: "internal_network_only" + target: "whoami_proxy_provider" + order: 0 ``` +### Decision Matrix: OAuth/OIDC vs Forward Auth + +| Criteria | OAuth/OIDC | Forward Auth | +|----------|-----------|-------------| +| **Application Support** | Requires native OAuth/OIDC support | Any application | +| **Protocol Standard** | Industry standard (RFC 6749, 7636) | Proprietary/custom | +| **Token Management** | Native refresh tokens, proper expiry | Session-based only | +| **Logout Handling** | Proper logout flow | Complex, proxy-dependent | +| **API Access** | Full API support via tokens | Header-only | +| **Implementation Effort** | Configure OAuth settings | Zero app changes | +| **User Experience** | Standard OAuth redirects | Transparent | +| **Security Model** | Token-based with scopes | Header trust model | +| **When to Use** | **Nextcloud, Gitea, modern apps** | **Static sites, legacy apps, whoami** | + ### Consequences #### Positive -- **Security**: Consistent, centralized authentication and authorization -- **Simplicity**: No application changes required for protection -- **Flexibility**: Fine-grained access control through Authentik policies -- **Auditability**: Centralized authentication logging -- **User Experience**: Single sign-on across all services +- **Standards Compliance**: OAuth/OIDC uses industry-standard protocols +- **Security**: Multiple authentication options with appropriate security models +- **Flexibility**: Right tool for each service (OAuth when possible, forward auth when needed) +- **Auditability**: Centralized authentication logging via Authentik +- **User Experience**: Proper SSO across all services +- **Token Security**: OAuth provides secure token refresh and scope management +- **Graceful Degradation**: Forward auth available for services without OAuth support #### Negative -- **Single Point of Failure**: Authentication system failure affects all services -- **Performance**: Additional hop for authentication checks -- **Complexity**: Additional component in the request path +- **Complexity**: Need to understand two authentication methods +- **Configuration Overhead**: OAuth requires per-service configuration +- **Single Point of Failure**: Authentik failure affects all services +- **Learning Curve**: Team must understand OAuth flows and forward auth model #### Mitigation Strategies -- **High Availability**: Robust deployment and monitoring of auth components -- **Caching**: Session caching to reduce authentication overhead -- **Fallback**: Emergency bypass procedures for critical services -- **Monitoring**: Comprehensive monitoring of authentication flow +- **Documentation**: Clear decision guide for choosing OAuth vs forward auth +- **Templates**: Reusable OAuth configuration templates for common services +- **High Availability**: Robust deployment and monitoring of Authentik +- **Monitoring**: Comprehensive monitoring of both authentication flows +- **Testing**: Automated tests for authentication flows ### Security Considerations -#### Session Security +#### OAuth/OIDC Security ```yaml -# Authentik session settings -session_cookie_age: 3600 # 1 hour -session_cookie_secure: true -session_cookie_samesite: "Strict" -session_remember_me: false +# Authentik OAuth2 Provider security settings +authorization_code_validity: 60 # 1 minute +access_code_validity: 3600 # 1 hour +refresh_code_validity: 2592000 # 30 days +include_claims_in_id_token: true +signing_key: "authentik-default-key" +sub_mode: "hashed_user_id" +issuer_mode: "per_provider" ``` +**Best Practices**: +- Use PKCE for all OAuth flows (protection against interception) +- Implement proper token rotation (refresh tokens expire and rotate) +- Validate `aud` (audience) and `iss` (issuer) claims in JWT tokens +- Use short-lived access tokens (1 hour) +- Store client secrets securely (Ansible Vault) + +#### Forward Auth Security + +```yaml +# Authentik Proxy Provider security settings +token_validity: 3600 # 1 hour session +cookie_domain: ".jnss.me" +skip_path_regex: "^/(health|metrics|static).*" +``` + +**Best Practices**: +- Trust only Authentik-provided headers +- Validate `Remote-User` header exists before granting access +- Use HTTPS for all forward auth endpoints +- Implement proper session timeouts +- Strip user-provided authentication headers at proxy + #### Access Control - **Group-Based Authorization**: Users assigned to groups, groups to applications -- **Time-Based Access**: Temporary access grants -- **IP-Based Restrictions**: Geographic or network-based access control +- **Policy Engine**: Authentik policies for fine-grained access control - **MFA Requirements**: Multi-factor authentication for sensitive services +- **IP-Based Restrictions**: Geographic or network-based access control +- **Time-Based Access**: Temporary access grants via policies #### Audit Logging ```json { - "timestamp": "2025-12-11T17:52:31Z", - "event": "authentication_success", + "timestamp": "2025-12-15T10:30:00Z", + "event": "oauth_authorization", "user": "john.doe", - "service": "dashboard.jnss.me", + "application": "nextcloud", + "scopes": ["openid", "email", "profile", "groups"], "ip": "192.168.1.100", "user_agent": "Mozilla/5.0..." } ``` -### Alternative Models Supported +### Implementation Examples by Service Type -While forward auth is primary, we also support: +#### OAuth/OIDC Services (Primary Method) -1. **OAuth2/OIDC Integration**: For applications that can implement OAuth2 -2. **API Key Authentication**: For service-to-service communication -3. **Service-Native Auth**: For legacy applications that cannot be easily protected +**Nextcloud**: +```caddyfile +cloud.jnss.me { + reverse_proxy localhost:8080 +} +# OAuth configured within Nextcloud application +``` -### Implementation Examples +**Gitea**: +```caddyfile +git.jnss.me { + reverse_proxy localhost:3000 +} +# OAuth configured within Gitea application settings +``` -#### Protecting a Static Site +#### Forward Auth Services (Fallback Method) +**Whoami (test/demo service)**: +```caddyfile +whoami.jnss.me { + 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 +} +``` + +**Static Documentation Site**: ```caddyfile docs.jnss.me { forward_auth https://auth.jnss.me { @@ -734,33 +811,44 @@ docs.jnss.me { } ``` -#### Protecting an API - +**Internal API (no OAuth support)**: ```caddyfile api.jnss.me { forward_auth https://auth.jnss.me { uri /outpost.goauthentik.io/auth/caddy copy_headers Remote-User Remote-Email Remote-Groups } - reverse_proxy localhost:3000 } ``` -#### Public Endpoints with Selective Protection +#### Selective Protection (Public + Protected Paths) ```caddyfile app.jnss.me { - # Public endpoints (no auth) + # Public endpoints (no auth required) handle /health { reverse_proxy localhost:8080 } + handle /metrics { + reverse_proxy localhost:8080 + } + handle /public/* { reverse_proxy localhost:8080 } - # Protected endpoints + # Protected endpoints (forward auth) + handle /admin/* { + forward_auth https://auth.jnss.me { + uri /outpost.goauthentik.io/auth/caddy + copy_headers Remote-User Remote-Groups + } + reverse_proxy localhost:8080 + } + + # Default: protected handle { forward_auth https://auth.jnss.me { uri /outpost.goauthentik.io/auth/caddy @@ -773,18 +861,17 @@ app.jnss.me { ### Alternatives Considered -1. **OAuth2 Only**: Rejected due to application modification requirements -2. **Shared Database**: Rejected due to tight coupling between services -3. **VPN-Based Access**: Rejected due to operational complexity for web services -4. **Per-Service Authentication**: Rejected due to management overhead +1. **OAuth2/OIDC Only**: Rejected because many services don't support OAuth natively +2. **Forward Auth Only**: Rejected because it doesn't leverage native OAuth support in modern apps +3. **Per-Service Authentication**: Rejected due to management overhead and inconsistent security +4. **Shared Database**: Rejected due to tight coupling between services +5. **VPN-Based Access**: Rejected due to operational complexity for web services +6. **SAML**: Rejected in favor of modern OAuth2/OIDC standards --- -## ADR-005: Rootful Containers with Infrastructure Fact Pattern +## Rootful Containers with Infrastructure Fact Pattern -**Status**: ✅ Accepted -**Date**: December 2025 -**Deciders**: Infrastructure Team **Technical Story**: Enable containerized applications to access native infrastructure services (PostgreSQL, Valkey) via Unix sockets with group-based permissions. ### Context @@ -1038,25 +1125,5 @@ curl -I http://127.0.0.1:9000/ 1. **Rootless with user namespace** - Discarded due to GID remapping breaking group-based socket access 2. **TCP-only connections** - Rejected to maintain Unix socket security and performance benefits 3. **Hardcoded GIDs** - Rejected for portability; facts provide dynamic resolution -4. **Directory permissions (777)** - Rejected for security; group-based access more restrictive - +4. **Directory permissions (777)** - Rejected for security; group-based access more restrictive. This is then later changed again to 777, due to Nextcloud switching from root to www-data, breaking group-based permissions. --- - -## Summary - -These architecture decisions collectively create a robust, secure, and performant infrastructure: - -- **Native Services** provide optimal performance and security -- **Unix Sockets** eliminate network attack vectors -- **Podman + systemd** delivers secure container orchestration -- **Forward Authentication** enables centralized security without application changes -- **Rootful Container Pattern** enables group-based socket access with infrastructure fact sharing - -The combination results in an infrastructure that prioritizes security and performance while maintaining operational simplicity and reliability. - -## References - -- [Service Integration Guide](service-integration-guide.md) -- [Authentik Deployment Guide](authentik-deployment-guide.md) -- [Security Hardening](security-hardening.md) -- [Authentik Role Documentation](../roles/authentik/README.md) \ No newline at end of file diff --git a/docs/authentication-architecture.md b/docs/authentication-architecture.md index aa1c54a..cc5494a 100644 --- a/docs/authentication-architecture.md +++ b/docs/authentication-architecture.md @@ -7,7 +7,8 @@ This document describes the comprehensive authentication and authorization strat Rick-infra implements a modern, security-focused authentication architecture that provides: - **Centralized SSO**: Single sign-on across all services via Authentik -- **Forward Authentication**: Transparent protection without application changes +- **OAuth2/OIDC Integration**: Industry-standard authentication for services that support it (primary method) +- **Forward Authentication**: Transparent protection for legacy applications and services without OAuth support (fallback method) - **Zero Network Exposure**: Database and cache communication via Unix sockets - **Granular Authorization**: Fine-grained access control through groups and policies - **Standards Compliance**: OAuth2, OIDC, SAML support for enterprise integration @@ -98,15 +99,86 @@ sequenceDiagram ## Service Integration Patterns -### Pattern 1: Forward Authentication (Recommended) +### Choosing the Right Pattern -**Use Case**: Existing HTTP services that don't need to handle authentication +**Use OAuth2/OIDC (Primary Method)** when: +- ✅ Your service/application natively supports OAuth2/OIDC +- ✅ Examples: Nextcloud, Gitea, Grafana, modern web applications +- ✅ Provides better security, standard protocols, and proper token management + +**Use Forward Authentication (Fallback Method)** when: +- ⚠️ Service doesn't support OAuth2/OIDC integration +- ⚠️ Legacy applications that cannot be modified +- ⚠️ Static sites requiring authentication +- ⚠️ Simple internal tools without authentication capabilities + +--- + +### Pattern 1: OAuth2/OIDC Integration (Primary Method) + +**Use Case**: Applications with native OAuth2/OIDC support (Nextcloud, Gitea, Grafana, etc.) **Benefits**: -- No application code changes required -- Consistent authentication across all services -- Service receives authenticated user information via headers -- Centralized session management +- ✅ Industry-standard authentication protocol (RFC 6749, RFC 7636) +- ✅ Secure token-based authentication with JWT +- ✅ Proper session management with refresh tokens +- ✅ Native application integration +- ✅ Support for API access tokens +- ✅ Better logout handling and token refresh + +**Implementation**: + +```python +# Example OAuth2 configuration +OAUTH2_CONFIG = { + 'client_id': 'your-client-id', + 'client_secret': 'your-client-secret', + 'server_metadata_url': 'https://auth.jnss.me/application/o/your-app/.well-known/openid_configuration', + 'client_kwargs': { + 'scope': 'openid email profile groups' + } +} + +# OAuth2 flow implementation +from authlib.integrations.flask_client import OAuth + +oauth = OAuth(app) +oauth.register('authentik', **OAUTH2_CONFIG) + +@app.route('/login') +def login(): + redirect_uri = url_for('callback', _external=True) + return oauth.authentik.authorize_redirect(redirect_uri) + +@app.route('/callback') +def callback(): + token = oauth.authentik.authorize_access_token() + user_info = oauth.authentik.parse_id_token(token) + # Store user info in session + session['user'] = user_info + return redirect('/dashboard') +``` + +**Real-World Example**: See Example 1 below for Gitea OAuth/OIDC configuration. + +--- + +### Pattern 2: Forward Authentication (Fallback Method) + +**Use Case**: Existing HTTP services that don't support OAuth2/OIDC + +**Benefits**: +- ✅ No application code changes required +- ✅ Consistent authentication across all services +- ✅ Service receives authenticated user information via headers +- ✅ Centralized session management +- ✅ Works with any HTTP application + +**Limitations**: +- ⚠️ Non-standard authentication approach +- ⚠️ All requests must flow through authenticating proxy +- ⚠️ Limited logout functionality +- ⚠️ Backend must trust proxy-provided headers **Implementation**: @@ -143,48 +215,9 @@ def dashboard(): return f"Welcome {user_name} ({username})" ``` -### Pattern 2: OAuth2/OIDC Integration +**Real-World Example**: See Example 3 below for static site protection with forward auth. -**Use Case**: Applications that can implement OAuth2 client functionality - -**Benefits**: -- More control over authentication flow -- Better integration with application user models -- Support for API access tokens -- Offline access via refresh tokens - -**Implementation**: - -```python -# Example OAuth2 configuration -OAUTH2_CONFIG = { - 'client_id': 'your-client-id', - 'client_secret': 'your-client-secret', - 'server_metadata_url': 'https://auth.jnss.me/application/o/your-app/.well-known/openid_configuration', - 'client_kwargs': { - 'scope': 'openid email profile groups' - } -} - -# OAuth2 flow implementation -from authlib.integrations.flask_client import OAuth - -oauth = OAuth(app) -oauth.register('authentik', **OAUTH2_CONFIG) - -@app.route('/login') -def login(): - redirect_uri = url_for('callback', _external=True) - return oauth.authentik.authorize_redirect(redirect_uri) - -@app.route('/callback') -def callback(): - token = oauth.authentik.authorize_access_token() - user_info = oauth.authentik.parse_id_token(token) - # Store user info in session - session['user'] = user_info - return redirect('/dashboard') -``` +--- ### Pattern 3: API-Only Authentication @@ -512,35 +545,69 @@ Remote-Session-ID: sess_abc123def456 ## Integration Examples -### Example 1: Protecting Gitea with Groups +### Example 1: Gitea with OAuth2/OIDC Integration -**Objective**: Protect Git repository access with role-based permissions +**Objective**: Git repository access with native OAuth2/OIDC authentication + +**Why OAuth for Gitea**: Gitea has native OAuth2/OIDC support, providing better security and user experience than forward auth. + +#### Step 1: Configure Authentik OAuth2 Provider + +```yaml +# Authentik Provider Configuration +name: "Gitea OAuth Provider" +type: "OAuth2/OpenID Provider" +authorization_flow: "default-provider-authorization-implicit-consent" +client_type: "confidential" +client_id: "gitea" +redirect_uris: "https://git.jnss.me/user/oauth2/Authentik/callback" +signing_key: "authentik-default-key" +scopes: ["openid", "profile", "email", "groups"] +property_mappings: + - "authentik default OAuth Mapping: OpenID 'openid'" + - "authentik default OAuth Mapping: OpenID 'email'" + - "authentik default OAuth Mapping: OpenID 'profile'" +``` + +#### Step 2: Caddy Configuration ```caddyfile -# Caddy configuration for Gitea +# Caddy configuration for Gitea - No forward auth needed git.jnss.me { - forward_auth https://auth.jnss.me { - uri /outpost.goauthentik.io/auth/caddy - copy_headers Remote-User Remote-Groups - } - reverse_proxy localhost:3000 } ``` -**Gitea Configuration**: -```ini -# app.ini - Gitea configuration -[auth] -REVERSE_PROXY_AUTHENTICATION = true -REVERSE_PROXY_AUTO_REGISTRATION = true +#### Step 3: Gitea Configuration -[auth.reverse_proxy] -USER_HEADER = Remote-User -EMAIL_HEADER = Remote-Email -FULL_NAME_HEADER = Remote-Name +```ini +# app.ini - Gitea OAuth2 configuration +[openid] +ENABLE_OPENID_SIGNIN = false +ENABLE_OPENID_SIGNUP = false + +[oauth2_client] +REGISTER_EMAIL_CONFIRM = false +OPENID_CONNECT_SCOPES = openid email profile groups +ENABLE_AUTO_REGISTRATION = true +USERNAME = preferred_username +EMAIL = email +ACCOUNT_LINKING = auto ``` +#### Step 4: Add OAuth Source in Gitea Web UI + +1. Navigate to **Site Administration → Authentication Sources** +2. Click **Add Authentication Source** +3. **Authentication Type**: OAuth2 +4. **Authentication Name**: Authentik +5. **OAuth2 Provider**: OpenID Connect +6. **Client ID**: `gitea` (from Authentik provider) +7. **Client Secret**: (from Authentik provider) +8. **OpenID Connect Auto Discovery URL**: `https://auth.jnss.me/application/o/gitea/.well-known/openid-configuration` +9. **Additional Scopes**: `profile email groups` +10. Enable: **Skip local 2FA**, **Automatically create users** + **Group Mapping**: ```yaml # Authentik group configuration for Gitea @@ -555,6 +622,8 @@ groups: permissions: ["admin"] ``` +**Result**: Users see "Sign in with Authentik" button on Gitea login page with full OAuth flow. + ### Example 2: API Service with Scoped Access **Objective**: REST API with OAuth2 authentication and scoped permissions diff --git a/docs/authentik-deployment-guide.md b/docs/authentik-deployment-guide.md index b85a272..68c7521 100644 --- a/docs/authentik-deployment-guide.md +++ b/docs/authentik-deployment-guide.md @@ -9,7 +9,7 @@ This guide covers the complete deployment process for Authentik, a modern authen - **Native PostgreSQL** - High-performance database with Unix socket IPC - **Native Valkey** - Redis-compatible cache with Unix socket IPC - **Podman Containers** - System-level container orchestration via systemd/Quadlet -- **Caddy Reverse Proxy** - TLS termination and forward authentication +- **Caddy Reverse Proxy** - TLS termination, OAuth2/OIDC provider, and forward authentication fallback ## Architecture Summary @@ -279,7 +279,9 @@ curl -s https://auth.jnss.me/api/v3/admin/version/ # Launch URL: Your application URL ``` -#### 3. Configure Forward Auth (for Caddy integration) +#### 3. Configure Forward Auth (for services without OAuth support) + +**Note**: Only use Forward Auth for services that don't support OAuth2/OIDC integration. For services like Nextcloud, Gitea, or Grafana, use OAuth2 providers (see step 1 above) instead. ```bash # Navigate to Applications → Providers → Create @@ -287,17 +289,72 @@ curl -s https://auth.jnss.me/api/v3/admin/version/ # Name: "Forward Auth Provider" # External Host: https://your-service.jnss.me # Internal Host: http://localhost:8080 (your service backend) +# Use this only for: static sites, legacy apps, simple tools without OAuth support ``` ## Service Integration Examples -### Example 1: Protect Existing HTTP Service with Forward Auth +### Choosing the Right Integration Method + +**Primary Method - OAuth2/OIDC** (Use when service supports it): +- ✅ **Nextcloud**: Native OIDC support +- ✅ **Gitea**: Native OAuth2 support +- ✅ **Grafana**: Native OAuth2 support +- ✅ **Custom applications**: Applications with OAuth2 client libraries + +**Fallback Method - Forward Auth** (Use when service doesn't support OAuth): +- ⚠️ **Static sites**: No authentication capabilities +- ⚠️ **Legacy applications**: Cannot be modified +- ⚠️ **Simple tools**: whoami, monitoring dashboards without auth + +--- + +### Example 1: OAuth2/OIDC Integration (Nextcloud) + +**Recommended for services with native OAuth support** + +For applications that can handle OAuth2/OIDC directly (like Nextcloud, Gitea): + +```yaml +# Nextcloud OIDC configuration (config.php) +'oidc_login_provider_url' => 'https://auth.jnss.me/application/o/nextcloud/', +'oidc_login_client_id' => 'nextcloud-client-id', +'oidc_login_client_secret' => 'your_client_secret', +'oidc_login_auto_redirect' => true, +'oidc_login_end_session_redirect' => true, +'oidc_login_button_text' => 'Login with SSO', +'oidc_login_hide_password_form' => true, +'oidc_login_use_id_token' => true, +'oidc_login_attributes' => [ + 'id' => 'preferred_username', + 'name' => 'name', + 'mail' => 'email', + 'groups' => 'groups', +], +'oidc_login_default_group' => 'users', +'oidc_login_scope' => 'openid profile email groups', +'oidc_login_tls_verify' => true, +``` + +**Caddy configuration** (no forward auth needed): +```caddyfile +# In /etc/caddy/sites-enabled/nextcloud.caddy +cloud.jnss.me { + reverse_proxy localhost:8080 +} +``` + +--- + +### Example 2: Forward Auth for Services Without OAuth Support + +**Use only when OAuth2/OIDC is not available** Add to your service's Caddy configuration: ```caddyfile -# In /etc/caddy/sites-enabled/myservice.caddy -myservice.jnss.me { +# In /etc/caddy/sites-enabled/whoami.caddy +whoami.jnss.me { # Forward authentication to authentik forward_auth https://auth.jnss.me { uri /outpost.goauthentik.io/auth/caddy @@ -309,146 +366,6 @@ myservice.jnss.me { } ``` -### Example 2: OAuth2 Integration for Custom Applications - -For applications that can handle OAuth2 directly: - -```yaml -# Application configuration -OAUTH2_PROVIDER_URL: "https://auth.jnss.me/application/o/authorize/" -OAUTH2_TOKEN_URL: "https://auth.jnss.me/application/o/token/" -OAUTH2_USER_INFO_URL: "https://auth.jnss.me/application/o/userinfo/" -OAUTH2_CLIENT_ID: "your_client_id" -OAUTH2_CLIENT_SECRET: "your_client_secret" -OAUTH2_REDIRECT_URI: "https://yourapp.jnss.me/oauth/callback" -``` - -## Troubleshooting Guide - -### Common Issues and Solutions - -#### Issue: Containers fail to start with socket permission errors - -**Symptoms**: -``` -Error: failed to connect to database: permission denied -``` - -**Solution**: -```bash -# Check authentik user group membership -ssh root@your-vps "groups authentik" -# Should show: authentik postgres-clients valkey-clients - -# Verify container process groups -ssh root@your-vps "ps aux | grep authentik-server | head -1 | awk '{print \$2}' | xargs -I {} cat /proc/{}/status | grep Groups" -# Should show: Groups: 961 962 966 (valkey-clients postgres-clients authentik) - -# Verify socket permissions -ssh root@your-vps "ls -la /var/run/postgresql/ /var/run/valkey/" - -# Fix group membership if missing -ansible-playbook site.yml --tags authentik,user,setup --ask-vault-pass -``` - -#### Issue: HTTP binding errors (address already in use) - -**Symptoms**: -``` -Error: bind: address already in use (port 9000) -``` - -**Solution**: -```bash -# Check what's using port 9000 -ssh root@your-vps "netstat -tulpn | grep 9000" - -# Stop conflicting services -ssh root@your-vps "systemctl stop authentik-pod" - -# Restart with correct configuration -ansible-playbook site.yml --tags authentik,containers --ask-vault-pass -``` - -#### Issue: Database connection failures - -**Symptoms**: -``` -FATAL: database "authentik" does not exist -``` - -**Solution**: -```bash -# Recreate database and user -ansible-playbook site.yml --tags authentik,database --ask-vault-pass - -# Verify database creation -ssh root@your-vps "sudo -u postgres psql -h /var/run/postgresql -c '\l'" -``` - -#### Issue: Cache connection failures - -**Symptoms**: -``` -Error connecting to Redis: Connection refused -``` - -**Solution**: -```bash -# Check Valkey service status -ssh root@your-vps "systemctl status valkey" - -# Test socket connectivity -ssh root@your-vps "redis-cli -s /var/run/valkey/valkey.sock ping" - -# Redeploy cache configuration if needed -ansible-playbook site.yml --tags authentik,cache --ask-vault-pass -``` - -### Diagnostic Commands - -#### Container Debugging - -```bash -# Check container logs -ssh root@your-vps "podman logs authentik-server" -ssh root@your-vps "podman logs authentik-worker" - -# Inspect container configuration -ssh root@your-vps "podman inspect authentik-server" - -# Check container user/group mapping -ssh root@your-vps "podman exec authentik-server id" -# Expected: uid=966(authentik) gid=966(authentik) groups=966(authentik),961(valkey-clients),962(postgres-clients) -``` - -#### Service Status Verification - -```bash -# Check all authentik systemd services -ssh root@your-vps "systemctl status authentik-pod authentik-server authentik-worker" - -# View service dependencies -ssh root@your-vps "systemctl list-dependencies authentik-pod" - -# Verify services are in system.slice -ssh root@your-vps "systemctl status authentik-server | grep CGroup" -# Expected: /system.slice/authentik-server.service -``` - -#### Network Connectivity Testing - -```bash -# Test internal HTTP binding -ssh root@your-vps "curl -v http://127.0.0.1:9000/" - -# Test Caddy reverse proxy -ssh root@your-vps "curl -v http://127.0.0.1:80/ -H 'Host: auth.jnss.me'" - -# Test external HTTPS -curl -v https://auth.jnss.me/ -``` - ### Log Analysis #### Key Log Locations @@ -513,174 +430,3 @@ ssh root@your-vps "journalctl -u authentik-server --since today | grep '\"level\ ssh root@your-vps "journalctl -u authentik-server | grep '\"event\":\"database connection\"'" ``` -## Performance Monitoring - -### Resource Usage Monitoring - -```bash -# Monitor container resource usage -ssh root@your-vps "podman stats" - -# Monitor service memory usage -ssh root@your-vps "systemctl status authentik-server | grep Memory" - -# Monitor database connections -ssh root@your-vps "sudo -u postgres psql -h /var/run/postgresql -c 'SELECT * FROM pg_stat_activity;'" -``` - -### Performance Optimization Tips - -1. **Database Performance**: - - Monitor PostgreSQL slow query log - - Consider database connection pooling for high traffic - - Regular database maintenance (VACUUM, ANALYZE) - -2. **Cache Performance**: - - Monitor Valkey memory usage and hit rate - - Adjust cache TTL settings based on usage patterns - - Consider cache warming for frequently accessed data - -3. **Container Performance**: - - Monitor container memory limits and usage - - Optimize shared memory configuration if needed - - Review worker process configuration - -## Maintenance Tasks - -### Regular Maintenance - -#### Update Authentik Version - -```yaml -# Update version in defaults or inventory -authentik_version: "2025.12.1" # New version - -# Deploy update -ansible-playbook site.yml --tags authentik,containers --ask-vault-pass -``` - -#### Backup Procedures - -```bash -# Database backup -ssh root@your-vps "sudo -u postgres pg_dump -h /var/run/postgresql authentik > /backup/authentik-$(date +%Y%m%d).sql" - -# Media files backup -ssh root@your-vps "tar -czf /backup/authentik-media-$(date +%Y%m%d).tar.gz -C /opt/authentik media" - -# Configuration backup (run from ansible control machine) -ansible-vault view host_vars/arch-vps/vault.yml > backup/authentik-vault-$(date +%Y%m%d).yml -``` - -#### Health Monitoring - -Set up regular health checks: - -```bash -#!/bin/bash -# Health check script -HEALTH_URL="https://auth.jnss.me/if/health/live/" -if ! curl -f -s "$HEALTH_URL" > /dev/null; then - echo "Authentik health check failed" - # Add alerting logic -fi -``` - -### Security Maintenance - -#### Certificate Monitoring - -```bash -# Check certificate expiration -ssh root@your-vps "curl -vI https://auth.jnss.me/ 2>&1 | grep expire" - -# Caddy handles renewal automatically, but monitor logs -ssh root@your-vps "journalctl -u caddy | grep -i cert" -``` - -#### Security Updates - -```bash -# Update container images regularly -ansible-playbook site.yml --tags authentik,image-pull --ask-vault-pass - -# Monitor for Authentik security advisories -# https://github.com/goauthentik/authentik/security/advisories -``` - -## Support and Resources - -### Documentation References - -- **Authentik Official Documentation**: https://docs.goauthentik.io/ -- **rick-infra Architecture Decisions**: [docs/architecture-decisions.md](architecture-decisions.md) -- **Service Integration Guide**: [docs/service-integration-guide.md](service-integration-guide.md) -- **Security Model**: [docs/security-hardening.md](security-hardening.md) - -### Community Resources - -- **Authentik Community Forum**: https://community.goauthentik.io/ -- **GitHub Issues**: https://github.com/goauthentik/authentik/issues -- **Discord Community**: https://discord.gg/jg33eMhnj6 - -### Emergency Procedures - -#### Service Recovery - -```bash -# Emergency service restart -ssh root@your-vps "systemctl restart authentik-pod" - -# Fallback: Direct container management -ssh root@your-vps "podman pod restart authentik" - -# Last resort: Full service rebuild -ansible-playbook site.yml --tags authentik --ask-vault-pass --limit arch-vps -``` - -#### Rollback Procedures - -```bash -# Rollback to previous container version -authentik_version: "previous_working_version" -ansible-playbook site.yml --tags authentik,containers --ask-vault-pass - -# Database rollback (if needed) -ssh root@your-vps "sudo -u postgres psql -h /var/run/postgresql authentik < /backup/authentik-backup.sql" -``` - ---- - -## Deployment Checklist - -Use this checklist to ensure complete deployment: - -### Pre-deployment -- [ ] Infrastructure services (PostgreSQL, Valkey, Caddy, Podman) running -- [ ] DNS records configured for auth.jnss.me -- [ ] Vault variables configured and encrypted -- [ ] Ansible connectivity verified - -### Deployment -- [ ] Authentik role enabled in site.yml -- [ ] Deployment executed successfully -- [ ] Health checks passing -- [ ] Containers running and responsive - -### Post-deployment -- [ ] Admin web interface accessible -- [ ] Initial admin login successful -- [ ] OAuth2 provider configured -- [ ] Test application integration -- [ ] Forward auth configuration tested - -### Production Readiness -- [ ] Backup procedures implemented -- [ ] Monitoring and alerting configured -- [ ] Security review completed -- [ ] Documentation updated -- [ ] Team training completed - ---- - -This comprehensive deployment guide provides everything needed to successfully deploy and maintain Authentik in the rick-infra environment, emphasizing the security and performance benefits of our native database + Unix socket architecture. \ No newline at end of file