--- # Configure invitation stage for enrollment flow - name: Use bootstrap token for API access set_fact: authentik_api_token: "{{ client_secrets.authentik_bootstrap_token }}" - name: Wait for Authentik API to be ready uri: url: "https://{{ authentik_domain }}/api/v3/root/config/" method: GET validate_certs: no status_code: 200 register: api_result until: api_result.status == 200 retries: 12 delay: 5 ignore_errors: yes failed_when: false - name: Create blueprints directory on server file: path: /opt/config/authentik/blueprints state: directory mode: '0755' when: api_result.status is defined and api_result.status == 200 - name: Copy public enrollment flow blueprint to server copy: src: enrollment-flow.yaml dest: /opt/config/authentik/blueprints/enrollment-flow.yaml mode: '0644' register: enrollment_blueprint_copied when: api_result.status is defined and api_result.status == 200 - name: Copy enrollment blueprint into authentik-worker container shell: | docker cp /opt/config/authentik/blueprints/enrollment-flow.yaml authentik-worker:/blueprints/enrollment-flow.yaml when: api_result.status is defined and api_result.status == 200 - name: Copy enrollment blueprint into authentik-server container shell: | docker cp /opt/config/authentik/blueprints/enrollment-flow.yaml authentik-server:/blueprints/enrollment-flow.yaml when: api_result.status is defined and api_result.status == 200 - name: Wait for enrollment blueprint to be discovered and applied shell: | echo "Waiting for public enrollment blueprint to be discovered and applied..." sleep 10 # Check if blueprint instance was created i=1 while [ $i -le 24 ]; do result=$(docker exec authentik-server curl -sf -H 'Authorization: Bearer {{ authentik_api_token }}' \ 'http://localhost:9000/api/v3/managed/blueprints/' 2>/dev/null || echo '') if echo "$result" | grep -q 'public-enrollment-flow'; then echo "Blueprint instance found" if echo "$result" | grep -A 10 'public-enrollment-flow' | grep -q 'successful'; then echo "Blueprint applied successfully" exit 0 fi fi sleep 5 i=$((i+1)) done echo "Blueprint deployment in progress (may take 1-2 minutes)" register: enrollment_blueprint_result changed_when: false when: api_result.status is defined and api_result.status == 200 - name: Verify enrollment flow was created shell: | docker exec authentik-server curl -sf -H 'Authorization: Bearer {{ authentik_api_token }}' \ 'http://localhost:9000/api/v3/flows/instances/?slug=default-enrollment-flow' | \ python3 -c "import sys, json; d = json.load(sys.stdin); print(json.dumps({'found': len(d.get('results', [])) > 0, 'count': len(d.get('results', []))}))" register: enrollment_flow_check changed_when: false failed_when: false when: api_result.status is defined and api_result.status == 200 - name: Display public enrollment flow configuration status debug: msg: | ======================================== Authentik Public Enrollment Flow ======================================== Configuration Method: YAML Blueprints Blueprint File: /blueprints/enrollment-flow.yaml ✓ Blueprint Deployed: {{ enrollment_blueprint_copied.changed | default(false) }} ✓ Blueprint Applied: {{ 'In Progress' if (enrollment_blueprint_result is defined and enrollment_blueprint_result.rc is defined and enrollment_blueprint_result.rc != 0) else 'Complete' }} Verification: {{ enrollment_flow_check.stdout | default('{}') }} Features: - Invitation-only enrollment (requires valid invitation token) - User prompts: username, name, email, password - Automatic user creation and login Note: Brand enrollment flow is NOT auto-configured (API restriction). Flow is accessible via direct URL even without brand configuration. To use enrollment: 1. Create invitation: Directory > Invitations > Create Invitation 2. Share invitation link: https://{{ authentik_domain }}/if/flow/default-enrollment-flow/?itoken=TOKEN To verify: - Login to https://{{ authentik_domain }} - Check Admin > Flows for "default-enrollment-flow" - Test enrollment URL: https://{{ authentik_domain }}/if/flow/default-enrollment-flow/ ======================================== when: api_result.status is defined and api_result.status == 200