Commit graph

4 commits

Author SHA1 Message Date
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
Pieter
4e72ddf4ef Complete Ansible base configuration (#2)
Completed Issue #2: Ansible Base Configuration

All objectives met:
-  Hetzner Cloud dynamic inventory (hcloud plugin)
-  Common role (SSH hardening, UFW firewall, fail2ban, auto-updates)
-  Docker role (Docker Engine + Compose + networks)
-  Traefik role (reverse proxy with Let's Encrypt SSL)
-  Setup playbook (orchestrates all base roles)
-  Successfully tested on live test server (91.99.210.204)

Additional improvements:
- Fixed ansible.cfg for Ansible 2.20+ compatibility
- Updated ADR dates to 2025
- All roles follow Infrastructure Agent patterns

Test Results:
- SSH hardening applied (key-only auth)
- UFW firewall active (ports 22, 80, 443)
- Fail2ban protecting SSH
- Automatic security updates enabled
- Docker running with traefik network
- Traefik deployed and ready for SSL

Files added:
- ansible/playbooks/setup.yml
- ansible/roles/docker/* (complete)
- ansible/roles/traefik/* (complete)

Closes #2

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-27 14:13:15 +01:00
Pieter
171cbfbb32 WIP: Ansible base configuration - common role (#2)
Progress on Issue #2: Ansible Base Configuration

Completed:
-  Ansible installed via pipx (isolated Python environment)
-  Hetzner Cloud dynamic inventory configured
-  Ansible configuration (ansible.cfg)
-  Common role for base system hardening:
  - SSH hardening (key-only, no root password)
  - UFW firewall configuration
  - Fail2ban for SSH protection
  - Automatic security updates
  - Timezone and system packages
-  Comprehensive Ansible README with setup guide

Architecture Updates:
- Added Decision #15: pipx for isolated Python environments
- Updated ADR changelog with pipx adoption

Still TODO for #2:
- Docker role
- Traefik role
- Setup playbook
- Deploy playbook
- Testing against live server

Files added:
- ansible/README.md - Complete Ansible guide
- ansible/ansible.cfg - Ansible configuration
- ansible/hcloud.yml - Hetzner dynamic inventory
- ansible/roles/common/* - Base hardening role

Partial progress on #2

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-27 14:00:22 +01:00
Pieter
3848510e1b Initial project structure with agent definitions and ADR
- Add AI agent definitions (Architect, Infrastructure, Zitadel, Nextcloud)
- Add Architecture Decision Record with complete design rationale
- Add .gitignore to protect secrets and sensitive files
- Add README with quick start guide

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-24 12:12:17 +01:00