From e214dcf4ed0044b7b16f786d2e109897673f4c9b Mon Sep 17 00:00:00 2001 From: Daniel Allaire Date: Fri, 3 Jul 2026 15:52:38 -0400 Subject: [PATCH] =?UTF-8?q?Forgejo=20au=20SSO=20OIDC=20(2e=20app=20SSO)=20?= =?UTF-8?q?=E2=80=94=20=C3=A9prouv=C3=A9=20sur=20forge-01?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit serveur_forgejo (10.0.0) : PostgreSQL via registre, exposé par l'edge (auto-dérivé), source OAuth2 vers Keycloak (add-oauth idempotent), client OIDC forgejo via serveur_keycloak_clients, auto-enregistrement OIDC (identités depuis l'annuaire seulement). Prouvé : testmail (LDAP) → « Se connecter avec Chezlepro » → compte auto-créé, connecté au tableau de bord. 5 bugs de 1er déploiement corrigés : dépendance sendmail→postfix ; app.ini propriété git (persiste secrets) ; ordre admin/migrations (flush_handlers + wait_for) ; HTTP_ADDR 0.0.0.0 (edge distant) ; auto-enregistrement OIDC. Co-Authored-By: Claude Opus 4.8 --- CHANGELOG.md | 13 +++++++ docs/dependances-groupes.yml | 4 +-- roles/serveur_forgejo/defaults/main.yml | 13 +++++++ roles/serveur_forgejo/tasks/main.yml | 41 +++++++++++++++++++++- roles/serveur_forgejo/templates/app.ini.j2 | 16 ++++++++- 5 files changed, 83 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ee767c..bd62e9b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,19 @@ ## 2026-07-03 ### Ajouté +- **Forgejo branché au SSO OIDC (« Se connecter avec Chezlepro ») — 2e app SSO, prouvée.** + `serveur_forgejo` (10.0.0) éprouvé sur `forge-01` (🔧→⭐), adossé à PostgreSQL (base `forgejo` + auto-provisionnée depuis le registre), exposé par l'edge (vhost + cert SAN + A PowerDNS + alias + plancher, tout auto-dérivé de `expose`). **Source OAuth2** vers Keycloak + (`forgejo admin auth add-oauth`, idempotent, realm `chezlepro`), client OIDC `forgejo` + enregistré via `serveur_keycloak_clients`. Auto-enregistrement OIDC (`[oauth2_client] + ENABLE_AUTO_REGISTRATION` + `ALLOW_ONLY_EXTERNAL_REGISTRATION` : identités depuis l'annuaire + seulement). **Prouvé** (flux authorization code headless) : `testmail` (LDAP) se connecte, + **compte auto-créé** (`testmail@lab.chezlepro.internal`), atterrit sur le tableau de bord. + **5 bugs de 1er déploiement corrigés** : dépendance périmée `serveur_sendmail`→`serveur_postfix` + (le vrai MTA) ; `app.ini` doit appartenir au user `git` (Forgejo persiste des secrets générés) ; + ordre admin/migrations (`flush_handlers` + `wait_for` avant `admin user create`) ; `HTTP_ADDR` + `127.0.0.1`→`0.0.0.0` (l'edge nginx est sur un autre hôte, 502 sinon) ; auto-enregistrement OIDC. - **PowerDNS — A d'exposition auto-dérivés (le DNS de la Phase 3 des bindings).** `serveur_powerdns` génère désormais, dans la zone interne, un enregistrement A pour chaque FQDN d'exposition (champ `expose` des applications) vers l'**edge qui le sert** (`domaines.edge`) — via diff --git a/docs/dependances-groupes.yml b/docs/dependances-groupes.yml index 32d35d1..957f8ba 100644 --- a/docs/dependances-groupes.yml +++ b/docs/dependances-groupes.yml @@ -66,8 +66,8 @@ groupes: requiert_groupes_actifs: - serveur_postgresql - serveur_nginx - - serveur_sendmail - raison: "Forgejo depend d'une base, d'une publication HTTP(S) et du courriel." + - serveur_postfix + raison: "Forgejo depend d'une base, d'une publication HTTP(S) et d'un relais courriel (MTA Postfix)." surveillance: "Verifier HTTP(S), base, files Git et envoi courriel." serveur_nextcloud: diff --git a/roles/serveur_forgejo/defaults/main.yml b/roles/serveur_forgejo/defaults/main.yml index 7bfbb42..fef313a 100644 --- a/roles/serveur_forgejo/defaults/main.yml +++ b/roles/serveur_forgejo/defaults/main.yml @@ -13,6 +13,9 @@ serveur_forgejo_service: "forgejo" # Publication (derriere serveur_nginx, TLS a l'edge). serveur_forgejo_hostname: "forge.{{ domaine_interne }}" +# Adresse d'ecoute : 0.0.0.0 car l'edge nginx est sur un AUTRE hote (le distant doit +# joindre le backend). A restreindre par pare-feu (nftables) au reseau interne / a l'edge. +serveur_forgejo_http_addr: "0.0.0.0" serveur_forgejo_http_port: 3000 # Base de donnees : resolue depuis le registre par le groupe consommateur. @@ -28,3 +31,13 @@ serveur_forgejo_internal_token: "{{ vault_forgejo_internal_token | default('') } serveur_forgejo_admin_user: "forgejo-admin" serveur_forgejo_admin_email: "admin@{{ domaine_interne }}" serveur_forgejo_admin_password: "{{ vault_forgejo_admin | default('') }}" # rempli depuis la voute (vault_forgejo_admin) + +# --- SSO OIDC (Keycloak, realm applicatif) — « Se connecter avec Chezlepro » --- +# Requiert client_pki (confiance step_ca) + résolution de l'hôte Keycloak (plancher/DNS). +# Le client OIDC doit exister dans le realm (serveur_keycloak_clients). +serveur_forgejo_oidc_actif: true +serveur_forgejo_oidc_nom: "chezlepro" # slug du callback : /user/oauth2//callback +serveur_forgejo_oidc_client_id: "forgejo" +serveur_forgejo_oidc_client_secret: "{{ vault_forgejo_oidc | default('') }}" # voûte (vault_forgejo_oidc) +serveur_forgejo_oidc_realm: "chezlepro" +serveur_forgejo_oidc_discovery: "https://keycloak.{{ domaine_interne }}/realms/{{ serveur_forgejo_oidc_realm }}/.well-known/openid-configuration" diff --git a/roles/serveur_forgejo/tasks/main.yml b/roles/serveur_forgejo/tasks/main.yml index 74e9778..7318f15 100644 --- a/roles/serveur_forgejo/tasks/main.yml +++ b/roles/serveur_forgejo/tasks/main.yml @@ -88,7 +88,7 @@ ansible.builtin.template: src: app.ini.j2 dest: "{{ serveur_forgejo_config }}" - owner: root + owner: "{{ serveur_forgejo_utilisateur }}" # Forgejo persiste des secrets générés (oauth2 JWT) → doit pouvoir écrire group: "{{ serveur_forgejo_utilisateur }}" mode: "0640" no_log: true @@ -111,6 +111,16 @@ state: started daemon_reload: true +- name: Appliquer les redemarrages Forgejo (config a jour) avant admin/OAuth2 + ansible.builtin.meta: flush_handlers + +- name: Attendre que Forgejo reponde (migrations terminees) + ansible.builtin.wait_for: + host: 127.0.0.1 + port: "{{ serveur_forgejo_http_port }}" + timeout: 120 + when: not ansible_check_mode + - name: Creer le compte administrateur (une fois) ansible.builtin.shell: cmd: >- @@ -126,3 +136,32 @@ environment: GITEA_WORK_DIR: "{{ serveur_forgejo_data }}" no_log: true + +- name: Configurer la source OAuth2 SSO (Keycloak, idempotent) + ansible.builtin.shell: + executable: /bin/bash + cmd: | + set -euo pipefail + FJ="{{ serveur_forgejo_binaire }} --config {{ serveur_forgejo_config }}" + if $FJ admin auth list 2>/dev/null | grep -qw "{{ serveur_forgejo_oidc_nom }}"; then + echo SETOPS_OK + else + $FJ admin auth add-oauth \ + --name "{{ serveur_forgejo_oidc_nom }}" \ + --provider openidConnect \ + --key "{{ serveur_forgejo_oidc_client_id }}" \ + --secret "$OIDC_SECRET" \ + --auto-discover-url "{{ serveur_forgejo_oidc_discovery }}" >/dev/null + echo SETOPS_CHANGED + fi + environment: + OIDC_SECRET: "{{ serveur_forgejo_oidc_client_secret }}" + GITEA_WORK_DIR: "{{ serveur_forgejo_data }}" + become: true + become_user: "{{ serveur_forgejo_utilisateur }}" + register: serveur_forgejo_oauth + changed_when: "'SETOPS_CHANGED' in serveur_forgejo_oauth.stdout" + no_log: true + when: + - serveur_forgejo_oidc_actif | bool + - not ansible_check_mode diff --git a/roles/serveur_forgejo/templates/app.ini.j2 b/roles/serveur_forgejo/templates/app.ini.j2 index f5d4e2a..2140afb 100644 --- a/roles/serveur_forgejo/templates/app.ini.j2 +++ b/roles/serveur_forgejo/templates/app.ini.j2 @@ -7,7 +7,7 @@ WORK_PATH = {{ serveur_forgejo_data }} [server] DOMAIN = {{ serveur_forgejo_hostname }} ROOT_URL = https://{{ serveur_forgejo_hostname }}/ -HTTP_ADDR = 127.0.0.1 +HTTP_ADDR = {{ serveur_forgejo_http_addr }} HTTP_PORT = {{ serveur_forgejo_http_port }} SSH_DOMAIN = {{ serveur_forgejo_hostname }} @@ -24,7 +24,21 @@ SECRET_KEY = {{ serveur_forgejo_secret_key }} INTERNAL_TOKEN = {{ serveur_forgejo_internal_token }} [service] +{% if serveur_forgejo_oidc_actif %} +; Identites depuis l'annuaire via le SSO uniquement : pas d'inscription locale, +; mais auto-enregistrement des utilisateurs OIDC. +DISABLE_REGISTRATION = false +ALLOW_ONLY_EXTERNAL_REGISTRATION = true +{% else %} DISABLE_REGISTRATION = true +{% endif %} + +{% if serveur_forgejo_oidc_actif %} +[oauth2_client] +ENABLE_AUTO_REGISTRATION = true +USERNAME = preferred_username +ACCOUNT_LINKING = auto +{% endif %} [mailer] ENABLED = true