Files
ObsiGate/docs/features/devprod-urls-config-223.md
T
Spark f29a22886a
CI / lint (push) Successful in 3m11s
CI / security (push) Failing after 1m55s
CI / test (push) Successful in 5m23s
CI / build (push) Successful in 2m35s
CI / e2e (push) Successful in 18m24s
feat: URLs publiques de l'écosystème par configuration — dev/prod sans noms en dur #223
2026-10-25 18:10:59 +00:00

4.7 KiB

#223 — Dev/prod sans noms publics en dur : URLs de l'écosystème par configuration

Ouvert le 2026-10-25 (chantier dev/prod de Bruno). Contexte : l'installation actuelle (deepin.lab.home) devient l'environnement dev (noms en -dev), la future installation (jump.point.mint.home) sera la prod (noms officiels sans suffixe), identique sauf noms et clés. Règle : aucun nom public de l'écosystème codé en dur dans le code vivant ; défauts = noms officiels ; le dev déclare ses -dev dans son seul .env.

Configuration (nouveau module backend/draco_config.py)

Lecture à l'appel, jamais à l'import. Défauts officiels :

Variable Défaut officiel Rôle
DRACO_AGENT_URL https://agent.dracodev.net Base du service d'agents. À défaut : origine dérivée d'AGENT_EVENEMENTS_URL, puis défaut.
DRACO_OBSIGATE_URL https://og.dracodev.net Liens profonds ObsiGate
DRACO_FLOWDECK_URL https://flowdeck.dracodev.net Liens profonds Flowdeck
DRACO_TIKTAK_URL https://tiktak.dracodev.net Liens profonds TikTak
DRACO_KANBANTE_URL https://kanbante.dracodev.net Onglet Kanbante de la barre
DRACO_GITEA_URL https://git.dracodev.net Cartes Kanbante (= issues Gitea). Distincte d'OBSIGATE_GITEA_URL (source connectée de l'assistant).

AGENT_EVENEMENTS_URL (existant, #220) reste la configuration première du journal d'événements ; agent_journal._url() retombe sur DRACO_AGENT_URL + /api/v1/evenements quand elle est absente.

Backend

  • CSP (backend/main.py, SecurityHeadersMiddleware) : connect-src et frame-src utilisent draco_config.agent_origine() — dérivée de la config à chaque réponse, plus aucun littéral. Tests dans tests/test_security_headers.py via la config (défaut officiel neutralisé, dérivation depuis AGENT_EVENEMENTS_URL, priorité DRACO_AGENT_URL).
  • Références croisées (backend/external_refs.py) :
    • parse_deep_link reconnaît les hôtes officiels et configurés (draco_config.hotes_reconnus()) — un lien collé depuis le dev comme depuis la prod est reconnu.
    • build_deep_link(app, type, id) construit l'URL d'affichage depuis la config ; list_refs / get_ref / delete_ref servent des copies dont target_url est reconstruite à la lecture. ⚠️ Les références stockées (data/external_refs/*.json) gardent l'URL absolue collée par l'utilisateur : aucune migration, la valeur stockée n'est simplement plus jamais servie telle quelle.
  • WebAuthn — confirmé, aucun changement : resolve_relying_party() (backend/auth/webauthn_mfa.py, BUG-070) dérive rp_id/origines de la requête (hôte exact, X-Forwarded-Host/X-Forwarded-Proto honorés si OBSIGATE_TRUST_PROXY=true), et OBSIGATE_WEBAUTHN_RP_ID / OBSIGATE_WEBAUTHN_ORIGINS priment quand ils sont posés. Aucun nom figé.

Frontend (contrat d'injection de dracodev-commons)

L'hôte fournit les URL : backend/main.py::_index_html() injecte window.DRACO_URLS = {…} (JSON issu de draco_config.urls_publiques(), nonce CSP par le mécanisme existant) dans index.html au service.

  • frontend/draco-panneau.js : API = window.DRACO_URLS.agent || défaut officiel ; appHote() retire un suffixe -dev éventuel du premier label d'hôte (og-dev → obsigate pour le lien profond ?app=).
  • frontend/draco-liens.js : « Ouvrir dans TikTak » = window.DRACO_URLS.tiktak || défaut officiel.
  • frontend/index.html : les href des onglets portent les défauts officiels ; le script de configuration de la barre les réécrit depuis DRACO_URLS. Le menu des apps (draco-barre.js) est construit depuis ces onglets : il suit donc sans changement.
  • Chemin réellement servi : /static/draco-*.js via le montage StaticFiles, Cache-Control: no-cache posé par SecurityHeadersMiddleware sur /static/*, et service worker network-first pour le code — aucun cache-busting par empreinte n'existe (revalidation systématique).

Restes assumés

  • Suffixe SSO dracodev.net (draco_session.validate_return_to, frontend/js/auth.js) : ce n'est pas un nom d'hôte mais le domaine parent commun aux deux environnements (les noms -dev restent des sous-domaines) ; le domaine du cookie est déjà configurable (DRACO_SESSION_COOKIE_DOMAIN).
  • Mentions textuelles (titres/messages du panneau, contact OpenAPI et lien « À propos » vers le dépôt Git) : infra Git hors périmètre, ou libellés.
  • OBSIGATE_SEARXNG_URL : déjà configurable, défaut officiel conservé.
  • Le panneau reste un asset partagé : la même ligne d'injection doit être recopiée dans les 3 autres apps par leurs chantiers respectifs pour retrouver l'octet-identique.