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

@@ -7,7 +7,8 @@ This document describes the comprehensive authentication and authorization strat
Rick-infra implements a modern, security-focused authentication architecture that provides:
- **Centralized SSO**: Single sign-on across all services via Authentik
- **Forward Authentication**: Transparent protection without application changes
- **OAuth2/OIDC Integration**: Industry-standard authentication for services that support it (primary method)
- **Forward Authentication**: Transparent protection for legacy applications and services without OAuth support (fallback method)
- **Zero Network Exposure**: Database and cache communication via Unix sockets
- **Granular Authorization**: Fine-grained access control through groups and policies
- **Standards Compliance**: OAuth2, OIDC, SAML support for enterprise integration
@@ -98,15 +99,86 @@ sequenceDiagram
## Service Integration Patterns
### Pattern 1: Forward Authentication (Recommended)
### Choosing the Right Pattern
**Use Case**: Existing HTTP services that don't need to handle authentication
**Use OAuth2/OIDC (Primary Method)** when:
- ✅ Your service/application natively supports OAuth2/OIDC
- ✅ Examples: Nextcloud, Gitea, Grafana, modern web applications
- ✅ Provides better security, standard protocols, and proper token management
**Use Forward Authentication (Fallback Method)** when:
- ⚠️ Service doesn't support OAuth2/OIDC integration
- ⚠️ Legacy applications that cannot be modified
- ⚠️ Static sites requiring authentication
- ⚠️ Simple internal tools without authentication capabilities
---
### Pattern 1: OAuth2/OIDC Integration (Primary Method)
**Use Case**: Applications with native OAuth2/OIDC support (Nextcloud, Gitea, Grafana, etc.)
**Benefits**:
- No application code changes required
- Consistent authentication across all services
- Service receives authenticated user information via headers
- Centralized session management
- ✅ Industry-standard authentication protocol (RFC 6749, RFC 7636)
- ✅ Secure token-based authentication with JWT
- ✅ Proper session management with refresh tokens
- ✅ Native application integration
- ✅ Support for API access tokens
- ✅ Better logout handling and token refresh
**Implementation**:
```python
# Example OAuth2 configuration
OAUTH2_CONFIG = {
'client_id': 'your-client-id',
'client_secret': 'your-client-secret',
'server_metadata_url': 'https://auth.jnss.me/application/o/your-app/.well-known/openid_configuration',
'client_kwargs': {
'scope': 'openid email profile groups'
}
}
# OAuth2 flow implementation
from authlib.integrations.flask_client import OAuth
oauth = OAuth(app)
oauth.register('authentik', **OAUTH2_CONFIG)
@app.route('/login')
def login():
redirect_uri = url_for('callback', _external=True)
return oauth.authentik.authorize_redirect(redirect_uri)
@app.route('/callback')
def callback():
token = oauth.authentik.authorize_access_token()
user_info = oauth.authentik.parse_id_token(token)
# Store user info in session
session['user'] = user_info
return redirect('/dashboard')
```
**Real-World Example**: See Example 1 below for Gitea OAuth/OIDC configuration.
---
### Pattern 2: Forward Authentication (Fallback Method)
**Use Case**: Existing HTTP services that don't support OAuth2/OIDC
**Benefits**:
- ✅ No application code changes required
- ✅ Consistent authentication across all services
- ✅ Service receives authenticated user information via headers
- ✅ Centralized session management
- ✅ Works with any HTTP application
**Limitations**:
- ⚠️ Non-standard authentication approach
- ⚠️ All requests must flow through authenticating proxy
- ⚠️ Limited logout functionality
- ⚠️ Backend must trust proxy-provided headers
**Implementation**:
@@ -143,48 +215,9 @@ def dashboard():
return f"Welcome {user_name} ({username})"
```
### Pattern 2: OAuth2/OIDC Integration
**Real-World Example**: See Example 3 below for static site protection with forward auth.
**Use Case**: Applications that can implement OAuth2 client functionality
**Benefits**:
- More control over authentication flow
- Better integration with application user models
- Support for API access tokens
- Offline access via refresh tokens
**Implementation**:
```python
# Example OAuth2 configuration
OAUTH2_CONFIG = {
'client_id': 'your-client-id',
'client_secret': 'your-client-secret',
'server_metadata_url': 'https://auth.jnss.me/application/o/your-app/.well-known/openid_configuration',
'client_kwargs': {
'scope': 'openid email profile groups'
}
}
# OAuth2 flow implementation
from authlib.integrations.flask_client import OAuth
oauth = OAuth(app)
oauth.register('authentik', **OAUTH2_CONFIG)
@app.route('/login')
def login():
redirect_uri = url_for('callback', _external=True)
return oauth.authentik.authorize_redirect(redirect_uri)
@app.route('/callback')
def callback():
token = oauth.authentik.authorize_access_token()
user_info = oauth.authentik.parse_id_token(token)
# Store user info in session
session['user'] = user_info
return redirect('/dashboard')
```
---
### Pattern 3: API-Only Authentication
@@ -512,35 +545,69 @@ Remote-Session-ID: sess_abc123def456
## Integration Examples
### Example 1: Protecting Gitea with Groups
### Example 1: Gitea with OAuth2/OIDC Integration
**Objective**: Protect Git repository access with role-based permissions
**Objective**: Git repository access with native OAuth2/OIDC authentication
**Why OAuth for Gitea**: Gitea has native OAuth2/OIDC support, providing better security and user experience than forward auth.
#### Step 1: Configure Authentik OAuth2 Provider
```yaml
# Authentik Provider Configuration
name: "Gitea OAuth Provider"
type: "OAuth2/OpenID Provider"
authorization_flow: "default-provider-authorization-implicit-consent"
client_type: "confidential"
client_id: "gitea"
redirect_uris: "https://git.jnss.me/user/oauth2/Authentik/callback"
signing_key: "authentik-default-key"
scopes: ["openid", "profile", "email", "groups"]
property_mappings:
- "authentik default OAuth Mapping: OpenID 'openid'"
- "authentik default OAuth Mapping: OpenID 'email'"
- "authentik default OAuth Mapping: OpenID 'profile'"
```
#### Step 2: Caddy Configuration
```caddyfile
# Caddy configuration for Gitea
# Caddy configuration for Gitea - No forward auth needed
git.jnss.me {
forward_auth https://auth.jnss.me {
uri /outpost.goauthentik.io/auth/caddy
copy_headers Remote-User Remote-Groups
}
reverse_proxy localhost:3000
}
```
**Gitea Configuration**:
```ini
# app.ini - Gitea configuration
[auth]
REVERSE_PROXY_AUTHENTICATION = true
REVERSE_PROXY_AUTO_REGISTRATION = true
#### Step 3: Gitea Configuration
[auth.reverse_proxy]
USER_HEADER = Remote-User
EMAIL_HEADER = Remote-Email
FULL_NAME_HEADER = Remote-Name
```ini
# app.ini - Gitea OAuth2 configuration
[openid]
ENABLE_OPENID_SIGNIN = false
ENABLE_OPENID_SIGNUP = false
[oauth2_client]
REGISTER_EMAIL_CONFIRM = false
OPENID_CONNECT_SCOPES = openid email profile groups
ENABLE_AUTO_REGISTRATION = true
USERNAME = preferred_username
EMAIL = email
ACCOUNT_LINKING = auto
```
#### Step 4: Add OAuth Source in Gitea Web UI
1. Navigate to **Site Administration → Authentication Sources**
2. Click **Add Authentication Source**
3. **Authentication Type**: OAuth2
4. **Authentication Name**: Authentik
5. **OAuth2 Provider**: OpenID Connect
6. **Client ID**: `gitea` (from Authentik provider)
7. **Client Secret**: (from Authentik provider)
8. **OpenID Connect Auto Discovery URL**: `https://auth.jnss.me/application/o/gitea/.well-known/openid-configuration`
9. **Additional Scopes**: `profile email groups`
10. Enable: **Skip local 2FA**, **Automatically create users**
**Group Mapping**:
```yaml
# Authentik group configuration for Gitea
@@ -555,6 +622,8 @@ groups:
permissions: ["admin"]
```
**Result**: Users see "Sign in with Authentik" button on Gitea login page with full OAuth flow.
### Example 2: API Service with Scoped Access
**Objective**: REST API with OAuth2 authentication and scoped permissions