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

4.5 KiB

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:

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:

# 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:

- 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:

- 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:

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