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:
2025-12-15 00:25:24 +01:00
parent 4f8da38ca6
commit e8b76c6a72
3 changed files with 536 additions and 654 deletions

View File

@@ -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)