Forgejo au SSO OIDC (2e app SSO) — éprouvé sur forge-01
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 <noreply@anthropic.com>
This commit is contained in:
parent
fa945de5a7
commit
e214dcf4ed
5 changed files with 83 additions and 4 deletions
13
CHANGELOG.md
13
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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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/<nom>/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"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue