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.
This commit is contained in:
@@ -1,139 +1,9 @@
|
|||||||
# Architecture Decision Records (ADR)
|
# 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.
|
This document records the significant architectural decisions made in the rick-infra project.
|
||||||
|
|
||||||
## 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)
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
## Unix Socket IPC Architecture
|
||||||
## 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.
|
|
||||||
|
|
||||||
### Context
|
### Context
|
||||||
|
|
||||||
@@ -141,11 +11,10 @@ Containerized applications need to communicate with database and cache services.
|
|||||||
|
|
||||||
1. **Network TCP/IP**: Standard network protocols
|
1. **Network TCP/IP**: Standard network protocols
|
||||||
2. **Unix Domain Sockets**: Filesystem-based IPC
|
2. **Unix Domain Sockets**: Filesystem-based IPC
|
||||||
3. **Shared Memory**: Direct memory sharing (complex)
|
|
||||||
|
|
||||||
### Decision
|
### 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
|
### Rationale
|
||||||
|
|
||||||
@@ -269,10 +138,6 @@ podman exec authentik-server id
|
|||||||
|
|
||||||
## ADR-003: Podman + systemd Container Orchestration
|
## 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.
|
**Technical Story**: Container orchestration solution for secure application deployment with systemd integration.
|
||||||
|
|
||||||
### Context
|
### 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
|
**Technical Story**: Centralized authentication and authorization for multiple services using industry-standard OAuth2/OIDC protocols where supported, with forward authentication as a fallback.
|
||||||
**Date**: December 2025
|
|
||||||
**Deciders**: Infrastructure Team
|
|
||||||
**Technical Story**: Centralized authentication and authorization for multiple services without modifying existing applications.
|
|
||||||
|
|
||||||
### Context
|
### Context
|
||||||
|
|
||||||
@@ -506,53 +368,122 @@ Authentication strategies for multiple services:
|
|||||||
|
|
||||||
1. **Per-Service Authentication**: Each service handles its own authentication
|
1. **Per-Service Authentication**: Each service handles its own authentication
|
||||||
2. **Shared Database**: Services share authentication database
|
2. **Shared Database**: Services share authentication database
|
||||||
3. **Forward Authentication**: Reverse proxy handles authentication
|
3. **OAuth2/OIDC Integration**: Services implement standard OAuth2/OIDC clients
|
||||||
4. **OAuth2/OIDC Integration**: Services implement OAuth2 clients
|
4. **Forward Authentication**: Reverse proxy handles authentication for services without OAuth support
|
||||||
|
|
||||||
### Decision
|
### 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
|
### 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
|
- **Zero Application Changes**: Protect existing services without modification
|
||||||
- **Consistent Security**: Same security model across all services
|
- **Header-Based Identity**: Simple identity propagation to backend
|
||||||
- **Session Management**: Centralized session handling and timeouts
|
- **Transparent Protection**: Services receive pre-authenticated requests
|
||||||
- **Multi-Factor Authentication**: MFA applied consistently across services
|
|
||||||
|
|
||||||
#### 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
|
- **Audit Trail**: Centralized authentication logging
|
||||||
- **Policy Management**: Single place to manage access policies
|
|
||||||
- **User Management**: One system for all user administration
|
- **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
|
### 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 │
|
│ User │ │ Caddy │ │ Authentik │ │ Service │
|
||||||
│ │ │ (Proxy) │ │ (Auth) │ │ (Backend) │
|
│ │ │ (Proxy) │ │ (Forward) │ │ (Backend) │
|
||||||
└──────┬──────┘ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘
|
└──────┬──────┘ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘
|
||||||
│ │ │ │
|
│ │ │ │
|
||||||
│ GET /dashboard │ │ │
|
│ GET / │ │ │
|
||||||
│─────────────────▶│ │ │
|
│─────────────────▶│ │ │
|
||||||
│ │ │ │
|
│ │ │ │
|
||||||
│ │ Forward Auth │ │
|
│ │ Forward Auth │ │
|
||||||
@@ -561,19 +492,19 @@ We will use **forward authentication** with Caddy reverse proxy and Authentik au
|
|||||||
│ │ 401 Unauthorized │ │
|
│ │ 401 Unauthorized │ │
|
||||||
│ │◀─────────────────│ │
|
│ │◀─────────────────│ │
|
||||||
│ │ │ │
|
│ │ │ │
|
||||||
│ 302 → /auth/login│ │ │
|
│ 302 → /auth │ │ │
|
||||||
│◀─────────────────│ │ │
|
│◀─────────────────│ │ │
|
||||||
│ │ │ │
|
│ │ │ │
|
||||||
│ Login form │ │ │
|
│ Login form │ │ │
|
||||||
│─────────────────▶│─────────────────▶│ │
|
│──────────────────────────────────────▶│ │
|
||||||
│ │ │ │
|
│ │ │ │
|
||||||
│ Credentials │ │ │
|
│ Credentials │ │ │
|
||||||
│─────────────────▶│─────────────────▶│ │
|
│──────────────────────────────────────▶│ │
|
||||||
│ │ │ │
|
│ │ │ │
|
||||||
│ Set-Cookie │ │ │
|
│ Set-Cookie │ │ │
|
||||||
│◀─────────────────│◀─────────────────│ │
|
│◀──────────────────────────────────────│ │
|
||||||
│ │ │ │
|
│ │ │ │
|
||||||
│ GET /dashboard │ │ │
|
│ GET / │ │ │
|
||||||
│─────────────────▶│ │ │
|
│─────────────────▶│ │ │
|
||||||
│ │ │ │
|
│ │ │ │
|
||||||
│ │ Forward Auth │ │
|
│ │ Forward Auth │ │
|
||||||
@@ -582,21 +513,93 @@ We will use **forward authentication** with Caddy reverse proxy and Authentik au
|
|||||||
│ │ 200 + Headers │ │
|
│ │ 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
|
```caddyfile
|
||||||
# Service protection template
|
# whoami service with forward authentication
|
||||||
dashboard.jnss.me {
|
whoami.jnss.me {
|
||||||
# Forward authentication to Authentik
|
# Forward authentication to Authentik
|
||||||
forward_auth https://auth.jnss.me {
|
forward_auth https://auth.jnss.me {
|
||||||
uri /outpost.goauthentik.io/auth/caddy
|
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:
|
Services receive authentication information via HTTP headers:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
# Example service code (Python Flask)
|
# Example service code (Python Flask)
|
||||||
@app.route('/dashboard')
|
@app.route('/')
|
||||||
def dashboard():
|
def index():
|
||||||
username = request.headers.get('Remote-User')
|
username = request.headers.get('Remote-User')
|
||||||
name = request.headers.get('Remote-Name')
|
name = request.headers.get('Remote-Name')
|
||||||
email = request.headers.get('Remote-Email')
|
email = request.headers.get('Remote-Email')
|
||||||
groups = request.headers.get('Remote-Groups', '').split(',')
|
groups = request.headers.get('Remote-Groups', '').split(',')
|
||||||
|
|
||||||
if 'admins' in groups:
|
return render_template('index.html',
|
||||||
# Admin functionality
|
|
||||||
pass
|
|
||||||
|
|
||||||
return render_template('dashboard.html',
|
|
||||||
username=username,
|
username=username,
|
||||||
name=name)
|
name=name,
|
||||||
```
|
email=email,
|
||||||
|
groups=groups)
|
||||||
### 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).*"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Authorization Policies
|
### Authorization Policies
|
||||||
|
|
||||||
|
Both OAuth and Forward Auth support Authentik authorization policies:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
# Example authorization policy in Authentik
|
# Example authorization policy in Authentik
|
||||||
policy_bindings:
|
policy_bindings:
|
||||||
- policy: "group_admins_only"
|
- policy: "group_admins_only"
|
||||||
target: "service_dashboard"
|
target: "nextcloud_oauth_provider"
|
||||||
order: 0
|
order: 0
|
||||||
|
|
||||||
- policy: "deny_external_ips"
|
- policy: "require_mfa"
|
||||||
target: "admin_endpoints"
|
target: "gitea_oauth_provider"
|
||||||
order: 1
|
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
|
### Consequences
|
||||||
|
|
||||||
#### Positive
|
#### Positive
|
||||||
|
|
||||||
- **Security**: Consistent, centralized authentication and authorization
|
- **Standards Compliance**: OAuth/OIDC uses industry-standard protocols
|
||||||
- **Simplicity**: No application changes required for protection
|
- **Security**: Multiple authentication options with appropriate security models
|
||||||
- **Flexibility**: Fine-grained access control through Authentik policies
|
- **Flexibility**: Right tool for each service (OAuth when possible, forward auth when needed)
|
||||||
- **Auditability**: Centralized authentication logging
|
- **Auditability**: Centralized authentication logging via Authentik
|
||||||
- **User Experience**: Single sign-on across all services
|
- **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
|
#### Negative
|
||||||
|
|
||||||
- **Single Point of Failure**: Authentication system failure affects all services
|
- **Complexity**: Need to understand two authentication methods
|
||||||
- **Performance**: Additional hop for authentication checks
|
- **Configuration Overhead**: OAuth requires per-service configuration
|
||||||
- **Complexity**: Additional component in the request path
|
- **Single Point of Failure**: Authentik failure affects all services
|
||||||
|
- **Learning Curve**: Team must understand OAuth flows and forward auth model
|
||||||
|
|
||||||
#### Mitigation Strategies
|
#### Mitigation Strategies
|
||||||
|
|
||||||
- **High Availability**: Robust deployment and monitoring of auth components
|
- **Documentation**: Clear decision guide for choosing OAuth vs forward auth
|
||||||
- **Caching**: Session caching to reduce authentication overhead
|
- **Templates**: Reusable OAuth configuration templates for common services
|
||||||
- **Fallback**: Emergency bypass procedures for critical services
|
- **High Availability**: Robust deployment and monitoring of Authentik
|
||||||
- **Monitoring**: Comprehensive monitoring of authentication flow
|
- **Monitoring**: Comprehensive monitoring of both authentication flows
|
||||||
|
- **Testing**: Automated tests for authentication flows
|
||||||
|
|
||||||
### Security Considerations
|
### Security Considerations
|
||||||
|
|
||||||
#### Session Security
|
#### OAuth/OIDC Security
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
# Authentik session settings
|
# Authentik OAuth2 Provider security settings
|
||||||
session_cookie_age: 3600 # 1 hour
|
authorization_code_validity: 60 # 1 minute
|
||||||
session_cookie_secure: true
|
access_code_validity: 3600 # 1 hour
|
||||||
session_cookie_samesite: "Strict"
|
refresh_code_validity: 2592000 # 30 days
|
||||||
session_remember_me: false
|
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
|
#### Access Control
|
||||||
|
|
||||||
- **Group-Based Authorization**: Users assigned to groups, groups to applications
|
- **Group-Based Authorization**: Users assigned to groups, groups to applications
|
||||||
- **Time-Based Access**: Temporary access grants
|
- **Policy Engine**: Authentik policies for fine-grained access control
|
||||||
- **IP-Based Restrictions**: Geographic or network-based access control
|
|
||||||
- **MFA Requirements**: Multi-factor authentication for sensitive services
|
- **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
|
#### Audit Logging
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"timestamp": "2025-12-11T17:52:31Z",
|
"timestamp": "2025-12-15T10:30:00Z",
|
||||||
"event": "authentication_success",
|
"event": "oauth_authorization",
|
||||||
"user": "john.doe",
|
"user": "john.doe",
|
||||||
"service": "dashboard.jnss.me",
|
"application": "nextcloud",
|
||||||
|
"scopes": ["openid", "email", "profile", "groups"],
|
||||||
"ip": "192.168.1.100",
|
"ip": "192.168.1.100",
|
||||||
"user_agent": "Mozilla/5.0..."
|
"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
|
**Nextcloud**:
|
||||||
2. **API Key Authentication**: For service-to-service communication
|
```caddyfile
|
||||||
3. **Service-Native Auth**: For legacy applications that cannot be easily protected
|
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
|
```caddyfile
|
||||||
docs.jnss.me {
|
docs.jnss.me {
|
||||||
forward_auth https://auth.jnss.me {
|
forward_auth https://auth.jnss.me {
|
||||||
@@ -734,33 +811,44 @@ docs.jnss.me {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Protecting an API
|
**Internal API (no OAuth support)**:
|
||||||
|
|
||||||
```caddyfile
|
```caddyfile
|
||||||
api.jnss.me {
|
api.jnss.me {
|
||||||
forward_auth https://auth.jnss.me {
|
forward_auth https://auth.jnss.me {
|
||||||
uri /outpost.goauthentik.io/auth/caddy
|
uri /outpost.goauthentik.io/auth/caddy
|
||||||
copy_headers Remote-User Remote-Email Remote-Groups
|
copy_headers Remote-User Remote-Email Remote-Groups
|
||||||
}
|
}
|
||||||
|
|
||||||
reverse_proxy localhost:3000
|
reverse_proxy localhost:3000
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Public Endpoints with Selective Protection
|
#### Selective Protection (Public + Protected Paths)
|
||||||
|
|
||||||
```caddyfile
|
```caddyfile
|
||||||
app.jnss.me {
|
app.jnss.me {
|
||||||
# Public endpoints (no auth)
|
# Public endpoints (no auth required)
|
||||||
handle /health {
|
handle /health {
|
||||||
reverse_proxy localhost:8080
|
reverse_proxy localhost:8080
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handle /metrics {
|
||||||
|
reverse_proxy localhost:8080
|
||||||
|
}
|
||||||
|
|
||||||
handle /public/* {
|
handle /public/* {
|
||||||
reverse_proxy localhost:8080
|
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 {
|
handle {
|
||||||
forward_auth https://auth.jnss.me {
|
forward_auth https://auth.jnss.me {
|
||||||
uri /outpost.goauthentik.io/auth/caddy
|
uri /outpost.goauthentik.io/auth/caddy
|
||||||
@@ -773,18 +861,17 @@ app.jnss.me {
|
|||||||
|
|
||||||
### Alternatives Considered
|
### Alternatives Considered
|
||||||
|
|
||||||
1. **OAuth2 Only**: Rejected due to application modification requirements
|
1. **OAuth2/OIDC Only**: Rejected because many services don't support OAuth natively
|
||||||
2. **Shared Database**: Rejected due to tight coupling between services
|
2. **Forward Auth Only**: Rejected because it doesn't leverage native OAuth support in modern apps
|
||||||
3. **VPN-Based Access**: Rejected due to operational complexity for web services
|
3. **Per-Service Authentication**: Rejected due to management overhead and inconsistent security
|
||||||
4. **Per-Service Authentication**: Rejected due to management overhead
|
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.
|
**Technical Story**: Enable containerized applications to access native infrastructure services (PostgreSQL, Valkey) via Unix sockets with group-based permissions.
|
||||||
|
|
||||||
### Context
|
### 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
|
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
|
2. **TCP-only connections** - Rejected to maintain Unix socket security and performance benefits
|
||||||
3. **Hardcoded GIDs** - Rejected for portability; facts provide dynamic resolution
|
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)
|
|
||||||
@@ -7,7 +7,8 @@ This document describes the comprehensive authentication and authorization strat
|
|||||||
Rick-infra implements a modern, security-focused authentication architecture that provides:
|
Rick-infra implements a modern, security-focused authentication architecture that provides:
|
||||||
|
|
||||||
- **Centralized SSO**: Single sign-on across all services via Authentik
|
- **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
|
- **Zero Network Exposure**: Database and cache communication via Unix sockets
|
||||||
- **Granular Authorization**: Fine-grained access control through groups and policies
|
- **Granular Authorization**: Fine-grained access control through groups and policies
|
||||||
- **Standards Compliance**: OAuth2, OIDC, SAML support for enterprise integration
|
- **Standards Compliance**: OAuth2, OIDC, SAML support for enterprise integration
|
||||||
@@ -98,15 +99,86 @@ sequenceDiagram
|
|||||||
|
|
||||||
## Service Integration Patterns
|
## 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**:
|
**Benefits**:
|
||||||
- No application code changes required
|
- ✅ Industry-standard authentication protocol (RFC 6749, RFC 7636)
|
||||||
- Consistent authentication across all services
|
- ✅ Secure token-based authentication with JWT
|
||||||
- Service receives authenticated user information via headers
|
- ✅ Proper session management with refresh tokens
|
||||||
- Centralized session management
|
- ✅ 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**:
|
**Implementation**:
|
||||||
|
|
||||||
@@ -143,48 +215,9 @@ def dashboard():
|
|||||||
return f"Welcome {user_name} ({username})"
|
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
|
### Pattern 3: API-Only Authentication
|
||||||
|
|
||||||
@@ -512,35 +545,69 @@ Remote-Session-ID: sess_abc123def456
|
|||||||
|
|
||||||
## Integration Examples
|
## 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
|
```caddyfile
|
||||||
# Caddy configuration for Gitea
|
# Caddy configuration for Gitea - No forward auth needed
|
||||||
git.jnss.me {
|
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
|
reverse_proxy localhost:3000
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
**Gitea Configuration**:
|
#### Step 3: Gitea Configuration
|
||||||
```ini
|
|
||||||
# app.ini - Gitea configuration
|
|
||||||
[auth]
|
|
||||||
REVERSE_PROXY_AUTHENTICATION = true
|
|
||||||
REVERSE_PROXY_AUTO_REGISTRATION = true
|
|
||||||
|
|
||||||
[auth.reverse_proxy]
|
```ini
|
||||||
USER_HEADER = Remote-User
|
# app.ini - Gitea OAuth2 configuration
|
||||||
EMAIL_HEADER = Remote-Email
|
[openid]
|
||||||
FULL_NAME_HEADER = Remote-Name
|
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**:
|
**Group Mapping**:
|
||||||
```yaml
|
```yaml
|
||||||
# Authentik group configuration for Gitea
|
# Authentik group configuration for Gitea
|
||||||
@@ -555,6 +622,8 @@ groups:
|
|||||||
permissions: ["admin"]
|
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
|
### Example 2: API Service with Scoped Access
|
||||||
|
|
||||||
**Objective**: REST API with OAuth2 authentication and scoped permissions
|
**Objective**: REST API with OAuth2 authentication and scoped permissions
|
||||||
|
|||||||
@@ -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 PostgreSQL** - High-performance database with Unix socket IPC
|
||||||
- **Native Valkey** - Redis-compatible cache with Unix socket IPC
|
- **Native Valkey** - Redis-compatible cache with Unix socket IPC
|
||||||
- **Podman Containers** - System-level container orchestration via systemd/Quadlet
|
- **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
|
## Architecture Summary
|
||||||
|
|
||||||
@@ -279,7 +279,9 @@ curl -s https://auth.jnss.me/api/v3/admin/version/
|
|||||||
# Launch URL: Your application URL
|
# 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
|
```bash
|
||||||
# Navigate to Applications → Providers → Create
|
# Navigate to Applications → Providers → Create
|
||||||
@@ -287,17 +289,72 @@ curl -s https://auth.jnss.me/api/v3/admin/version/
|
|||||||
# Name: "Forward Auth Provider"
|
# Name: "Forward Auth Provider"
|
||||||
# External Host: https://your-service.jnss.me
|
# External Host: https://your-service.jnss.me
|
||||||
# Internal Host: http://localhost:8080 (your service backend)
|
# Internal Host: http://localhost:8080 (your service backend)
|
||||||
|
# Use this only for: static sites, legacy apps, simple tools without OAuth support
|
||||||
```
|
```
|
||||||
|
|
||||||
## Service Integration Examples
|
## 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:
|
Add to your service's Caddy configuration:
|
||||||
|
|
||||||
```caddyfile
|
```caddyfile
|
||||||
# In /etc/caddy/sites-enabled/myservice.caddy
|
# In /etc/caddy/sites-enabled/whoami.caddy
|
||||||
myservice.jnss.me {
|
whoami.jnss.me {
|
||||||
# Forward authentication to authentik
|
# Forward authentication to authentik
|
||||||
forward_auth https://auth.jnss.me {
|
forward_auth https://auth.jnss.me {
|
||||||
uri /outpost.goauthentik.io/auth/caddy
|
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
|
### Log Analysis
|
||||||
|
|
||||||
#### Key Log Locations
|
#### 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\"'"
|
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.
|
|
||||||
Reference in New Issue
Block a user