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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user