Post-Tyranny-Tech-Infrastru.../docs/OIDC_AUTOMATION.md
Pieter 8866411ef3 Implement fully automated OIDC/SSO provisioning (#4)
This commit eliminates all manual configuration steps for OIDC/SSO setup,
making the infrastructure fully scalable to dozens or hundreds of servers.

## Automation Overview

The deployment now automatically:
1. Authenticates with Zitadel using admin credentials
2. Creates OIDC application via Zitadel Management API
3. Retrieves client ID and secret
4. Configures Nextcloud OIDC provider

**Zero manual steps required!**

## New Components

### Zitadel OIDC Automation
- `files/get_admin_token.sh`: OAuth2 authentication script
- `files/create_oidc_app.py`: Python script for OIDC app creation via API
- `tasks/oidc-apps.yml`: Ansible orchestration for full automation

### API Integration
- Uses Zitadel Management API v1
- Resource Owner Password Credentials flow for admin auth
- Creates OIDC apps with proper security settings:
  - Authorization Code + Refresh Token grants
  - JWT access tokens
  - Role and UserInfo assertions enabled
  - Proper redirect URI configuration

### Nextcloud Integration
- Updated `tasks/oidc.yml` to auto-configure provider
- Receives credentials from Zitadel automation
- Configures discovery URI automatically
- Handles idempotency (skips if already configured)

## Scalability Benefits

### Before (Manual)
```
1. Deploy infrastructure
2. Login to Zitadel console
3. Create OIDC app manually
4. Copy client ID/secret
5. SSH to server
6. Run occ command with credentials
```

**Time per server: ~10-15 minutes**

### After (Automated)
```
1. Deploy infrastructure
```

**Time per server: ~0 minutes (fully automated)**

### Impact
- 10 servers: Save ~2 hours of manual work
- 50 servers: Save ~10 hours of manual work
- 100 servers: Save ~20 hours of manual work

## Security

- Admin credentials encrypted with SOPS
- Access tokens are ephemeral (generated per deployment)
- Client secrets never logged (`no_log: true`)
- All API calls over HTTPS only
- Credentials passed via Ansible facts (memory only)

## Documentation

Added comprehensive documentation:
- `docs/OIDC_AUTOMATION.md`: Full automation guide
- How it works
- Technical implementation details
- Troubleshooting guide
- Security considerations

## Testing

The automation is idempotent and handles:
-  First-time setup (creates app)
-  Subsequent runs (skips if exists)
-  Error handling (fails gracefully)
-  Credential validation

## Next Steps

Users can immediately login via SSO after deployment:
1. Visit https://nextcloud.{client}.vrije.cloud
2. Click "Login with Zitadel"
3. Enter Zitadel credentials
4. Automatically logged into Nextcloud

Closes #4

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-06 09:49:16 +01:00

175 lines
4.5 KiB
Markdown

# OIDC/SSO Automation
This document explains the fully automated OIDC/SSO setup between Zitadel and Nextcloud.
## Overview
The infrastructure now supports **fully automated** OIDC application provisioning, eliminating manual configuration steps. This makes the system scalable to dozens or hundreds of servers.
## How It Works
### 1. Automated OIDC App Creation
When deploying a new client, the Ansible playbook automatically:
1. **Authenticates with Zitadel** using admin credentials
2. **Creates OIDC application** via Zitadel Management API
3. **Retrieves client credentials** (client ID and secret)
4. **Configures Nextcloud** with the OIDC provider
### 2. Zero Manual Steps
The entire SSO setup happens automatically during deployment:
```bash
ansible-playbook -i hcloud.yml playbooks/deploy.yml
```
No need to:
- Login to Zitadel console
- Manually create OIDC apps
- Copy/paste client credentials
- Configure Nextcloud manually
### 3. Scalability
This automation makes it trivial to deploy **dozens of servers**:
```yaml
# terraform.tfvars
clients = {
client1 = { ... }
client2 = { ... }
client3 = { ... }
# Add as many as needed!
}
```
Each client gets:
- Its own Zitadel instance
- Its own Nextcloud instance
- Automatic OIDC configuration
- Unique credentials
## Technical Implementation
### Components
1. **`get_admin_token.sh`**: Authenticates with Zitadel using admin credentials
2. **`create_oidc_app.py`**: Creates OIDC app via Zitadel Management API
3. **`oidc-apps.yml`**: Ansible task orchestrating the automation
4. **`nextcloud/oidc.yml`**: Configures Nextcloud with OIDC provider
### Authentication Flow
```
1. Ansible → get_admin_token.sh → Zitadel OAuth2
2. Receives → JWT access token
3. Ansible → create_oidc_app.py → Zitadel Management API
4. Creates → OIDC application
5. Returns → Client ID + Client Secret
6. Ansible → Nextcloud occ command
7. Configures → OIDC provider
```
### API Endpoints Used
- **Token**: `POST https://{domain}/oauth/v2/token`
- **Projects**: `POST https://{domain}/management/v1/projects/_search`
- **Create App**: `POST https://{domain}/management/v1/projects/{id}/apps/oidc`
### Security Considerations
- Admin credentials are stored in **encrypted SOPS secrets**
- Access tokens are **ephemeral** (generated per-deployment)
- Client secrets are **never logged** (no_log: true)
- API calls use **HTTPS only**
## Configuration Options
### Zitadel OIDC App Settings
The automation creates apps with these settings:
```yaml
- Response Type: Authorization Code
- Grant Types: Authorization Code, Refresh Token
- App Type: Web Application
- Auth Method: Client Secret Basic
- Token Type: JWT
- Role Assertions: Enabled
- UserInfo Assertions: Enabled
```
### Nextcloud OIDC Provider
Configured with:
```yaml
- Provider Name: Zitadel
- Client ID: <auto-generated>
- Client Secret: <auto-generated>
- Discovery URI: https://{domain}/.well-known/openid-configuration
```
## Testing
After deployment, verify SSO works:
1. Visit: `https://nextcloud.{client}.vrije.cloud`
2. Click "Login with SSO" or "Zitadel"
3. Redirected to Zitadel login
4. Enter Zitadel credentials
5. Redirected back to Nextcloud (logged in)
## Troubleshooting
### OIDC App Not Created
Check Ansible output for errors in:
- `Get admin access token for API calls`
- `Create OIDC application for Nextcloud`
Common issues:
- Admin password incorrect
- Zitadel API not accessible
- Network connectivity issues
### Nextcloud OIDC Not Configured
Check if credentials were passed:
- `nextcloud_oidc_client_id` should be defined
- `nextcloud_oidc_client_secret` should be defined
Verify in Nextcloud:
```bash
docker exec -u www-data nextcloud php occ user_oidc:provider
```
### SSO Login Fails
Check redirect URI matches exactly:
```
https://nextcloud.{client}.vrije.cloud/apps/user_oidc/code
```
Check Zitadel application settings:
- Redirect URIs configured correctly
- Grant types include Authorization Code
- Application is active (not disabled)
## Future Enhancements
Potential improvements:
1. **Service Account**: Use dedicated service account instead of admin
2. **Token Caching**: Cache access tokens to reduce API calls
3. **Multi-App Support**: Automate Collabora, OnlyOffice, etc.
4. **Role Mapping**: Sync Zitadel roles to Nextcloud groups
5. **User Provisioning**: Auto-create users on first SSO login
## References
- [Zitadel Management API](https://zitadel.com/docs/apis/resources/mgmt)
- [Nextcloud OIDC App](https://github.com/nextcloud/user_oidc)
- [OAuth 2.0 Authorization Code Flow](https://oauth.net/2/grant-types/authorization-code/)