Post-Tyranny-Tech-Infrastru.../docs/sso-automation.md
Pieter a5fe631717 feat: Complete Authentik SSO integration with automated OIDC setup
## Changes

### Identity Provider (Authentik)
-  Deployed Authentik 2025.10.3 as identity provider
-  Configured automatic bootstrap with admin account (akadmin)
-  Fixed OIDC provider creation with correct redirect_uris format
-  Added automated OAuth2/OIDC provider configuration for Nextcloud
-  API-driven provider setup eliminates manual configuration

### Nextcloud Configuration
-  Fixed reverse proxy header configuration (trusted_proxies)
-  Added missing database indices (fs_storage_path_prefix)
-  Ran mimetype migrations for proper file type handling
-  Verified PHP upload limits (16GB upload_max_filesize)
-  Configured OIDC integration with Authentik
-  "Login with Authentik" button auto-configured

### Automation Scripts
-  Added deploy-client.sh for automated client deployment
-  Added rebuild-client.sh for infrastructure rebuild
-  Added destroy-client.sh for cleanup
-  Full deployment now takes ~10-15 minutes end-to-end

### Documentation
-  Updated README with automated deployment instructions
-  Added SSO automation workflow documentation
-  Added automation status tracking
-  Updated project reference with Authentik details

### Technical Fixes
- Fixed Authentik API redirect_uris format (requires list of dicts with matching_mode)
- Fixed Nextcloud OIDC command (user_oidc:provider not user_oidc:provider:add)
- Fixed file lookup in Ansible (changed to slurp for remote files)
- Updated Traefik to v3.6 for Docker API 1.44 compatibility
- Improved error handling in app installation tasks

## Security
- All credentials stored in SOPS-encrypted secrets
- Trusted proxy configuration prevents IP spoofing
- Bootstrap tokens auto-generated and secured

## Result
Fully automated SSO deployment - no manual configuration required!

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

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-08 16:56:19 +01:00

8.7 KiB

SSO Automation Workflow

Complete guide to the automated Authentik + Nextcloud SSO integration.

Overview

This infrastructure implements automated OAuth2/OIDC integration between Authentik (identity provider) and Nextcloud (application). The goal is to achieve zero manual configuration for SSO when deploying a new client.

Architecture

┌─────────────┐                    ┌─────────────┐
│  Authentik  │◄──────OIDC────────►│  Nextcloud  │
│  (IdP)      │   OAuth2/OIDC      │   (App)     │
└─────────────┘   Discovery URI    └─────────────┘
      │                                    │
      │ 1. Create provider via API         │
      │ 2. Get client_id/secret            │
      │                                    │
      └───────────► credentials ──────────►│
                    (temporary file)       │ 3. Configure OIDC app

Automation Workflow

Phase 1: Deployment (Ansible)

  1. Deploy Authentik (roles/authentik/tasks/docker.yml)

    • Start PostgreSQL database
    • Start Authentik server + worker containers
    • Wait for health check (HTTP 200/302 on root)
  2. Check for API Token (roles/authentik/tasks/providers.yml)

    • Look for client_secrets.authentik_api_token in secrets file
    • If missing: Display manual setup instructions and skip automation
    • If present: Proceed to Phase 2

Phase 2: OIDC Provider Creation (API)

Script: roles/authentik/files/authentik_api.py

  1. Wait for Authentik Ready

    • Poll root endpoint until 200/302 response
    • Timeout: 300 seconds (configurable)
  2. Get Authorization Flow UUID

    • GET /api/v3/flows/instances/
    • Find flow with slug=default-authorization-flow or designation=authorization
  3. Get Signing Key UUID

    • GET /api/v3/crypto/certificatekeypairs/
    • Use first available certificate
  4. Create OAuth2 Provider

    • POST /api/v3/providers/oauth2/
    {
      "name": "Nextcloud",
      "authorization_flow": "<flow_uuid>",
      "client_type": "confidential",
      "redirect_uris": "https://nextcloud.example.com/apps/user_oidc/code",
      "signing_key": "<key_uuid>",
      "sub_mode": "hashed_user_id",
      "include_claims_in_id_token": true
    }
    
  5. Create Application

    • POST /api/v3/core/applications/
    {
      "name": "Nextcloud",
      "slug": "nextcloud",
      "provider": "<provider_id>",
      "meta_launch_url": "https://nextcloud.example.com"
    }
    
  6. Return Credentials

    {
      "success": true,
      "client_id": "...",
      "client_secret": "...",
      "discovery_uri": "https://auth.example.com/application/o/nextcloud/.well-known/openid-configuration",
      "issuer": "https://auth.example.com/application/o/nextcloud/"
    }
    

Phase 3: Nextcloud Configuration

Task: roles/nextcloud/tasks/oidc.yml

  1. Install user_oidc App

    docker exec -u www-data nextcloud php occ app:install user_oidc
    docker exec -u www-data nextcloud php occ app:enable user_oidc
    
  2. Load Credentials from Temp File

    • Read /tmp/authentik_oidc_credentials.json (created by Phase 2)
    • Parse JSON to Ansible fact
  3. Configure OIDC Provider

    docker exec -u www-data nextcloud php occ user_oidc:provider:add \
      --clientid="<client_id>" \
      --clientsecret="<client_secret>" \
      --discoveryuri="<discovery_uri>" \
      "Authentik"
    
  4. Cleanup

    • Remove temporary credentials file

Result

  • "Login with Authentik" button appears on Nextcloud login page
  • Users can log in with Authentik credentials
  • Zero manual configuration required (if API token is present)

Manual Bootstrap (One-Time Setup)

If authentik_api_token is not in secrets, follow these steps once per Authentik instance:

Step 1: Complete Initial Setup

  1. Visit: https://auth.example.com/if/flow/initial-setup/
  2. Create admin account:
    • Username: akadmin (recommended)
    • Password: Secure random password
    • Email: Your admin email

Step 2: Create API Token

  1. Login to Authentik admin UI
  2. Navigate: Admin Interface → Tokens & App passwords
  3. Click Create → Tokens
  4. Configure token:
    • User: Your admin user (akadmin)
    • Intent: API Token
    • Description: Ansible automation
    • Expires: Never (or far future date)
  5. Copy the generated token

Step 3: Add to Secrets

Edit your client secrets file:

cd infrastructure
export SOPS_AGE_KEY_FILE="keys/age-key.txt"
sops secrets/clients/test.sops.yaml

Add line:

authentik_api_token: ak_<your_token_here>

Step 4: Re-run Deployment

cd infrastructure/ansible
export HCLOUD_TOKEN="..."
export SOPS_AGE_KEY_FILE="../keys/age-key.txt"

~/.local/bin/ansible-playbook -i hcloud.yml playbooks/deploy.yml \
  --tags authentik,oidc \
  --limit test

API Token Security

Best Practices

  1. Scope: Token has full API access - treat as root password
  2. Storage: Always encrypted with SOPS in secrets files
  3. Rotation: Rotate tokens periodically (update secrets file)
  4. Audit: Monitor token usage in Authentik logs

Alternative: Service Account

For production, consider creating a dedicated service account:

  1. Create user: ansible-automation
  2. Assign minimal permissions (provider creation only)
  3. Create token for this user
  4. Use in automation

Troubleshooting

OIDC Provider Creation Fails

Symptom: Script returns error creating provider

Check:

# Test API connectivity
curl -H "Authorization: Bearer $TOKEN" \
     https://auth.example.com/api/v3/flows/instances/

# Check Authentik logs
docker logs authentik-server
docker logs authentik-worker

Common Issues:

  • Token expired or invalid
  • Authorization flow not found (check flows in admin UI)
  • Certificate/key missing

"Login with Authentik" Button Missing

Symptom: Nextcloud shows only username/password login

Check:

# List configured providers
docker exec -u www-data nextcloud php occ user_oidc:provider

# Check user_oidc app status
docker exec -u www-data nextcloud php occ app:list | grep user_oidc

Fix:

# Re-configure OIDC
cd infrastructure/ansible
~/.local/bin/ansible-playbook -i hcloud.yml playbooks/deploy.yml \
  --tags oidc \
  --limit test

API Token Not Working

Symptom: "Authentication failed" from API script

Check:

  1. Token format: Should start with ak_
  2. User still exists in Authentik
  3. Token not expired (check in admin UI)

Fix: Create new token and update secrets file

Testing SSO Flow

End-to-End Test

  1. Open Nextcloud: https://nextcloud.example.com
  2. Click "Login with Authentik"
  3. Redirected to Authentik: https://auth.example.com
  4. Enter Authentik credentials (created in Authentik admin UI)
  5. Redirected back to Nextcloud (logged in)

Create Test User in Authentik

# Access Authentik admin UI
https://auth.example.com

# Navigate: Directory → Users → Create
# Fill in:
# - Username: testuser
# - Email: test@example.com
# - Password: <secure_password>

Test Login

  1. Logout of Nextcloud (if logged in as admin)
  2. Go to Nextcloud login page
  3. Click "Login with Authentik"
  4. Login with testuser credentials
  5. First login: Nextcloud creates local account linked to Authentik
  6. Subsequent logins: Automatic via SSO

Future Improvements

Fully Automated Bootstrap

Goal: Automate the initial admin account creation via API

Approach:

  • Research Authentik bootstrap tokens
  • Automate initial setup flow via HTTP POST requests
  • Generate admin credentials automatically
  • Store in secrets file

Status: Not yet implemented (initial setup still manual)

SAML Support

Add SAML provider alongside OIDC for applications that don't support OAuth2/OIDC.

Multi-Application Support

Extend automation to create OIDC providers for other applications:

  • Collabora Online
  • OnlyOffice
  • Custom web applications
  • API Script: ansible/roles/authentik/files/authentik_api.py
  • Provider Tasks: ansible/roles/authentik/tasks/providers.yml
  • OIDC Config: ansible/roles/nextcloud/tasks/oidc.yml
  • Main Playbook: ansible/playbooks/deploy.yml
  • Secrets Template: secrets/clients/test.sops.yaml
  • Agent Config: .claude/agents/authentik.md

References