Qualifie sources et hypothèses (pronotepy 2.15.7, 2026-09-12), corrige le nombre d'ENT, exclut CAS/SAML/EduConnect générique, aligne la procédure QR sur .env.example et supprime les exemples copiables. Refs #10
20 KiB
⚠️ AVERTISSEMENT
Ce document n'est pas un guide officiel. Il n'est ni approuvé, ni validé, ni autorisé par le Ministère de l'Éducation Nationale française ni par Docaposte (éditeur de Pronote / Index Éducation). Les informations présentées reposent sur :
- des observations directes du code source de
pronotepy(version 2.15.7, vérifiée localement le 2026-09-12) ;- des issues publiques du dépôt bain3/pronotepy (ex. #309, #344) ;
- des tests d'intégration du projet
pronote-sync.⚠️ Note importante (2026-09-12) : Un essai réel sur l'instance Pronote cible est nécessaire avant tout usage en production. Les tests/mocks ne prouvent pas la compatibilité d'instance.
Convention de qualification : ✅ Observé dans le code local : Mécanisme vérifié dans le code source de
pronotepy2.15.7 oupronote-sync. 🔍 Observé localement : Comportement constaté dans les interfaces Pronote (version non spécifiée, hypothèse à valider). ⚠️ Hypothèse à valider : Affirmation non vérifiée, nécessitant une confirmation par test sur une instance réelle.
Authentification Pronote — Référence technique pour pronote-sync
Introduction
Ce document documente uniquement les méthodes d'authentification prises en charge ou délégables par pronote-sync, en alignement strict avec :
- Le code source de
pronote_sync/sources/pronote/client.py(liste fermée_ENT_NAMES, gestion des tokens). - La bibliothèque
pronotepy2.15.7 (contrat des méthodesqrcode_login,token_login,export_credentials). - Les paramètres de configuration
.env.example(lignes 21–25).
Périmètre :
- Pris en charge : Méthodes implémentées et testées dans
pronote-sync. - Délégable à pronotepy : Méthodes gérées par
pronotepymais non directement exposées parpronote-sync. - Non implémenté : Méthodes non supportées (ex. CAS/SAML générique, EduConnect direct).
Public cible : Développeurs et intégrateurs de pronote-sync.
Tableau de compatibilité avec pronote-sync
| Méthode | Statut dans pronote-sync |
Implémentation | Source | Notes |
|---|---|---|---|---|
URL iCal sécurisée (icalsecurise) |
✅ Pris en charge | Source ical (prioritaire en mode auto) |
🔍 pronote_sync/sources/ical.py |
Jeton dans l'URL traité comme secret. |
| Connexion directe (mot de passe + ENT) | ✅ Pris en charge | Source pronotepy (repli si iCal échoue) |
🔍 pronote_sync/sources/pronote/client.py |
Liste fermée _ENT_NAMES (lignes 52–84). |
| QR Code + token mobile | ✅ Pris en charge | Mode PRONOTE_AUTH_MODE=qr_token |
🔍 pronotepy.Client.qrcode_login + token_login |
Voir Procédure QR. |
| SSO ENT (CAS/SAML) | ❌ Non implémenté | — | — | Seuls les 30 ENT de la liste fermée _ENT_NAMES (pronotepy 2.15.7) sont supportés via ent dans ParentClient. Pas de SSO générique CAS/SAML. |
| EduConnect (HubEduConnect) | ❌ Non implémenté | — | — | Nécessite une intégration CAS/SAML générique, non supportée par ce projet. |
| CAS direct | ❌ Non implémenté | — | — | Non supporté. |
| API publique | ❌ Inexistante | — | — | Aucune API publique n'est utilisée/implémentée par ce projet ; aucune API officielle publique n'a été vérifiée à la date du 2026-09-12. |
Méthode 1 : URL iCal sécurisée (icalsecurise)
Principe général
Pronote expose un flux de calendrier en lecture seule conforme à la norme iCalendar (RFC 5545). L'accès est contrôlé par un jeton secret intégré dans l'URL sous forme de paramètre de requête icalsecurise.
✅ Statut : Observé localement (fonctionnalité native de Pronote, version non spécifiée).
Obtention du jeton
- Se connecter à Pronote (Espace Parents ou Élève) via n'importe quelle méthode.
- Accéder à la vue « Emploi du temps ».
- Utiliser la fonction « Export iCal » ou « Exporter ».
- Pronote génère une URL contenant un jeton secret
icalsecurise. - Copier cette URL : elle constitue une crédentiale unique sensible qui doit être protégée comme un mot de passe.
🔹 Source : 🔍 Observé localement dans les interfaces Pronote (version non spécifiée, hypothèse à valider). ⚠️ Note : Les étapes dépendent de l'instance et du type de compte. L'exemple ci-dessus est non fonctionnel et ne contient aucun secret.
Format de l'URL
https://{etablissement}.index-education.net/pronote/ical/Edt_{prenom}.ics?icalsecurise={jeton}&version={version}¶m={param}
icalsecurise: Jeton secret (crédentiale).version: Version de Pronote (ex.2024).param: Paramètres optionnels.
🔹 Source : 🔍 Analysé via pronote_sync/sources/ical.py.
Cycle de vie
- Pérennité : Le jeton reste valide jusqu'à :
- Révocation manuelle par l'utilisateur dans Pronote.
- Régénération par l'établissement (ex. à la rentrée scolaire). ⚠️ Hypothèse à valider : La durée exacte dépend des politiques de l'établissement (non documentée officiellement).
🔹 Source : ⚠️ Comportement variable selon les instances (à tester localement).
Sécurité
- Surface d'attaque : Le jeton est encodé dans l'URL → risque d'exposition via :
- Logs serveur/proxy.
- En-tête
Referer. - Historique du navigateur.
- Recommandations :
- Ne jamais versionner l'URL (ex. dans
.envou Git). - Utiliser HTTPS (obligatoire).
- Masquer l'URL dans les logs (ex. via
redact_url()danspronote-sync).
- Ne jamais versionner l'URL (ex. dans
🔹 Source : ⚠️ Recommandation du projet (inspirée des bonnes pratiques générales de sécurité).
Intégration dans pronote-sync
- Paramètre :
PRONOTE_ICAL_URL(ex..env.exampleligne 2). - Comportement :
- Prioritaire en mode
PRONOTE_AGENDA_SOURCE=auto. - Si l'URL est invalide ou expire, repli automatique vers
pronotepy(siPRONOTE_AGENDA_SOURCE=auto). - Aucun repli si
PRONOTE_AGENDA_SOURCE=ical(échec explicite).
- Prioritaire en mode
🔹 Source : 🔍 pronote_sync/config/settings.py + pronote_sync/sources/ical.py.
Méthode 2 : Connexion directe (identifiant / mot de passe + ENT)
Principe général
Connexion via le protocole propriétaire de Pronote (JSON sur HTTPS), avec chiffrement AES-CBC utilisant une clé dérivée par MD5 (16 octets, soit AES-128) comme implémenté dans pronotepy 2.15.7 et mécanisme de défi-réponse. Utilisé par l'interface web.
✅ Statut : Observé dans le code local (délégable à pronotepy via ParentClient ou Client).
Flux d'authentification
- Initialisation : Requête GET vers
/pronote/{espace}.html(ex.parent.html).- Récupère
h(ID de session),a(ID espace),sCrA/sCoA(drapeaux chiffrement/compression).
- Récupère
- Échange de clés : Requête POST vers
/pronote/appelfonction/{a}/{h}/{numeroOrdre}. - Identification : Soumission de
identifiant,genreConnexion=0,genreEspace={a}. - Résolution du défi :
- Calcul de
mtp = MAJUSCULE(HEX(SHA256(alea + mot_de_passe))). - Dérivation de
key_challenge = MD5(nom_utilisateur + mtp). - Déchiffrement du
challengeavec AES-CBC utilisant une clé dérivée par MD5 (16 octets, soit AES-128).
- Calcul de
- Authentification : Soumission de la réponse au défi.
🔹 Source : 🔍 Observé dans le code local de pronotepy 2.15.7 (module clients.py et pronoteAPI.py, vérifié le 2026-09-12).
Intégration dans pronote-sync
- Paramètres :
PRONOTE_URL(ex..env.exampleligne 3).PRONOTE_USERNAME,PRONOTE_PASSWORD.PRONOTE_ENT(slug dans_ENT_NAMES).PRONOTE_ACCOUNT_TYPE(ex.parent).
- Comportement :
- Utilise
pronotepy.ParentClientpour les comptes parents. - Repli : Si iCal échoue en mode
auto,pronotepyest utilisé. - Pas de repli si
PRONOTE_AGENDA_SOURCE=pronotepy(échec explicite).
- Utilise
🔹 Source : 🔍 pronote_sync/sources/pronote/client.py (méthode _connect_password).
ENT supportés
Liste fermée des 30 ENT résolubles (lignes 52–83 de pronote_sync/sources/pronote/client.py) :
_monbureaunumerique, ent_elyco, bordeaux, ent_creuse, occitanie_montpellier, ...
⚠️ Hypothèse à valider : Les ENT non listés nécessitent une contribution à pronotepy.
🔹 Source : 🔍 Code source local de pronote-sync (2026-09-12).
Méthode 3 : QR Code + token mobile (pour pronote-sync)
Principe général
Mécanisme d'appairage par QR code pour les appareils mobiles, contournant l'authentification ENT/EduConnect. Le QR code est généré depuis l'interface web Pronote, espace parent → paramètres → QR code, puis utilisé avec un PIN à 4 chiffres pour obtenir un token dont la durée dépend de l'instance/serveur.
✅ Statut : Pris en charge par pronote-sync (mode PRONOTE_AUTH_MODE=qr_token).
Procédure QR pour pronote-sync
Étape 1 : Génération du QR code (interface web)
- Se connecter à Pronote via un navigateur (espace Parent).
- Aller dans Paramètres → Accès mobile / Application mobile.
- Définir un PIN temporaire à 4 chiffres.
- Pronote affiche un QR code contenant un JSON avec les clés :
login,jeton, eturl(ex.https://[host]/pronote/mobile.parent.html). Le fichier JSON réel contient des identifiants chiffrés et ne doit jamais être copié, partagé, ou committé. - Exporter le QR code :
- Sauvegardez le fichier JSON localement ou scannez-le avec un appareil.
- Ne jamais partager le JSON ou le PIN.
- Le fichier JSON du QR code contient des identifiants chiffrés : ne jamais le coller dans la documentation ni le committer.
🔹 Source : 🔍 Observé localement dans l'interface web Pronote (version non spécifiée, hypothèse à valider).
Étape 2 : Configuration de pronote-sync
- Enregistrer le QR code :
- Sauvegarder le JSON dans un fichier (ex.
/path/to/qr_code.json). - Permissions :
chmod 600 /path/to/qr_code.json.
- Sauvegarder le JSON dans un fichier (ex.
- Configurer
.env:⚠️ Note :PRONOTE_AUTH_MODE=qr_token PRONOTE_QR_CODE_FILE=/path/to/qr_code.json PRONOTE_QR_PIN= # renseigner localement la valeur secrète du PIN (jamais committée).env.examplene doit jamais contenir de PIN concret.
🔹 Source : 🔍 Observé dans .env.example (lignes 21–25) et pronote_sync/sources/pronote/client.py.
Étape 3 : Premier login (enrôlement)
pronote-synclitPRONOTE_QR_CODE_FILEetPRONOTE_QR_PIN.- Appel à
pronotepy.ParentClient.qrcode_login(qr_code, pin, uuid):qr_code: JSON du fichier QR.pin: PIN à 4 chiffres.uuid: UUID permanent généré parpronote-sync(ex.pronote-sync-{uuid4()}).
- Déchiffrement :
- Algorithme : AES-CBC utilisant une clé dérivée par MD5 (16 octets, soit AES-128).
- Clé :
MD5(PIN)(dérivée du PIN secret). - IV : 16 octets nuls.
- Résultat :
loginetjetonen clair.
- Échange de token : Pronote retourne un
jetonConnexionAppliMobile(token dont la durée dépend de l'instance/serveur). - Persistance :
pronote-syncsauvegarde les credentials viaexport_credentials()dans.pronote_auth_state.json(mode0600).
🔹 Source : 🔍 Observé dans le code local de pronotepy 2.15.7 (clients.py lignes 181–189) + pronote_sync/sources/pronote/client.py (méthode _enroll_qr_code).
Étape 4 : Connexions ultérieures (auto-login)
pronote-synccharge.pronote_auth_state.json.- Appel à
pronotepy.ParentClient.token_login(**credentials):pronote_url,username,password(token),uuid.
- Rotation du token : Le token est remplacé uniquement si le serveur renvoie
jetonConnexionAppliMobile(observé danspronotepy2.15.7,clients.py:382–387). - Persistance : Les credentials sont sauvegardés dans
.pronote_auth_state.jsonaprès chaque opération réussie.
🔹 Source : 🔍 Observé dans le code local de pronotepy 2.15.7 (clients.py lignes 245–280) + pronote_sync/sources/pronote/client.py (méthode _connect_qr_token).
Cycle de vie des tokens
- QR code : Valide ~10 minutes après génération (⚠️ Hypothèse à valider : cette durée n'est attestée que par un message d'exception dans
pronotepyet n'est pas une garantie officielle/indépendante de l'instance). jetonConnexionAppliMobile:- Durée dépendante de l'instance/serveur (observation du 2026-09-12, hypothèse : peut persister jusqu'à la fin de l'année scolaire, non garanti).
- Remplacé uniquement si le serveur renvoie
jetonConnexionAppliMobile(observé danspronotepy2.15.7,clients.py:382–387). - Révocable manuellement dans Pronote (Paramètres → Accès mobile).
🔹 Source : ⚠️ Comportement variable selon les instances (à tester localement).
Sécurité
- Fichiers sensibles :
.pronote_auth_state.json: Ne jamais versionner (couvert par.gitignore).PRONOTE_QR_CODE_FILE: Ne jamais committer (ex. dans Git).
- Secrets :
- Le PIN et le contenu du QR code sont masqués dans les logs (via
redact_secrets()). - Les exceptions sont expurgées (via
redact_exception()).
- Le PIN et le contenu du QR code sont masqués dans les logs (via
- Recommandations :
- Utiliser un PIN robuste (éviter les codes simples comme
0000ou des séquences évidentes). - Révoquer le token en cas de compromission (via Pronote web).
- Utiliser un PIN robuste (éviter les codes simples comme
🔹 Source : 🔍 pronote_sync/utils/redaction.py + pronote_sync/sources/pronote/client.py (méthode _collect_auth_secrets).
Erreurs et repli
PronoteAuthRotationError: Levée si :- Le token persisté est invalide/expiré.
- Le fichier QR ou le PIN est manquant/invalide.
- Action requise :
- Supprimer
.pronote_auth_state.json. - Générer un nouveau QR code depuis l'interface web Pronote, espace parent.
- Relancer
pronote-sync.
- Supprimer
🔹 Source : 🔍 Observé dans pronote_sync/errors.py + pronote_sync/sources/pronote/client.py (lignes 346–364).
Incompatibilités
- Mode
dry-run: Incompatible avecPRONOTE_AUTH_MODE=qr_token(risque de désynchronisation du token local).pronote-sync --dry-runrefuse le modeqr_tokenavant toute connexion.
🔹 Source : 🔍 docs/exploitation.md (ligne 65–66).
Annexe A : Bibliothèques tierces
| Bibliothèque | Langage | Dépôt | Méthodes supportées | Statut dans pronote-sync |
|---|---|---|---|---|
| pronotepy | Python | bain3/pronotepy | Connexion directe, QR code/token, 30 ENT (liste fermée) | ✅ Dépendance principale (version 2.15.7 vérifiée). |
| pronote-api | TypeScript | Litarvan/pronote-api | Connexion directe, CAS, ENT | ❌ Non utilisée. |
| pronote-qrcode-api | JavaScript | Androz2091/pronote-qrcode-api | Déchiffrement QR code | ❌ Non utilisée (intégration native via pronotepy). |
🔹 Source : 🔍 Observé dans pyproject.toml (dépendances) + code source local (2026-09-12).
Annexe B : Tableau comparatif synthétique
| Méthode | Périmètre | Identifiants | Expiration | Complexité | Statut dans pronote-sync |
|---|---|---|---|---|---|
| URL iCal sécurisée | EDT + devoirs (si inclus dans le flux) | Jeton URL | Longue durée (dépend de l'instance) | Très faible | ✅ Pris en charge |
| Connexion directe (mot de passe + ENT) | Agenda/EDT, devoirs, messages | Identifiant + mot de passe + ENT | Session dépendante de l'instance | Élevée | ✅ Pris en charge |
| QR Code + token mobile | Agenda/EDT, devoirs, messages | PIN 4 chiffres → token + UUID | QR ~10 min (⚠️ hypothèse) ; token dépendant de l'instance | Modérée | ✅ Pris en charge |
| SSO ENT (CAS/SAML) | — | Identifiants ENT | Session ENT | Très élevée | ❌ Non implémenté (seuls les 30 ENT de la liste fermée _ENT_NAMES sont supportés via pronotepy) |
| EduConnect | — | Identifiants nationaux | Session EduConnect | Très élevée | ❌ Non implémenté |
| CAS direct | — | Identifiants CAS | Ticket single-use | Modérée | ❌ Non implémenté |
| API publique | N/A | N/A | N/A | N/A | ❌ Inexistante |
Légende :
- Périmètre : Les méthodes iCal sont en lecture seule (EDT + devoirs si inclus dans le flux). Les méthodes Connexion directe et QR Code + token mobile permettent les opérations
pronotepyeffectivement implémentées par ce projet (agenda, devoirs, messages ; informations ignorées en modeqr_token). - QR ~10 min : ⚠️ Hypothèse non vérifiée (observé dans
pronotepyvia un message d'exception, dépend de l'instance). - Session dépendante de l'instance : ⚠️ Hypothèse non vérifiée (nécessite un essai réel).
Annexe C : Écarts et notes de cohérence
Alignement avec .env.example
| Paramètre | Document | Code | Statut |
|---|---|---|---|
PRONOTE_ICAL_URL |
✅ Lignes 2, 42–50 | ✅ sources/ical.py |
Cohérent |
PRONOTE_URL |
✅ Ligne 3 | ✅ client.py (ligne 294) |
Cohérent |
PRONOTE_ENT |
✅ Ligne 7 | ✅ client.py (ligne 297, _ENT_NAMES) |
Cohérent |
PRONOTE_AUTH_MODE=qr_token |
✅ Ligne 23 | ✅ client.py (ligne 334) |
Cohérent |
PRONOTE_QR_CODE_FILE |
✅ Ligne 24 | ✅ client.py (ligne 387) |
Cohérent |
PRONOTE_QR_PIN |
✅ Ligne 25 | ✅ client.py (ligne 388) |
Cohérent |
| « Le QR code se génère sur le site web » | ✅ Ligne 21 | ✅ Section Procédure QR | Cohérent |
Écarts avec docs/exploitation.md
| Élément | exploitation.md |
Ce document | Action |
|---|---|---|---|
| « Le QR code expire ~10 minutes » | Ligne 22 | ⚠️ Hypothèse non vérifiée (section Cycle de vie) | Aucune (hors périmètre). |
« Mode qr_token incompatible avec dry-run » |
Lignes 65–66 | ✅ Section Incompatibilités | Cohérent |
« Fichier .pronote_auth_state.json (mode 0600) » |
Lignes 70–75 | ✅ Section Sécurité | Cohérent |
Glossaire
| Terme | Définition |
|---|---|
| ENT | Espace Numérique de Travail (ex. Mon Bureau Numérique, Paris Classe Numérique). |
Jeton icalsecurise |
Token secret intégré dans l'URL iCal, équivalent à un mot de passe. |
jetonConnexionAppliMobile |
Token obtenu après appairage QR code, dont la durée dépend de l'instance/du serveur et n'est pas garantie. |
| UUID | Identifiant unique permanent pour l'application (ex. pronote-sync-{uuid4()}). |
| PIN | Code à 4 chiffres défini lors de la génération du QR code. |
Historique des révisions
| Date | Auteur | Modifications |
|---|---|---|
| 2026-09-12 | Agent tech-writer | Refonte complète : qualification des affirmations, ajout des sources, tableau de compatibilité, procédure QR alignée sur pronotepy 2.15.7. |
| 2026-09-12 | Agent tech-writer | Corrections suite à revue indépendante (ticket #10) : précision cryptographie (AES-128), qualification des sources, alignement nombre d'ENT (30), clarification SSO/CAS, exemples non copiables, note d'essai réel. |
| 2026-09-12 | Agent tech-writer | Corrections suite à revue ticket #10 : suppression de tous les placeholders de secrets remplacés par de la prose descriptive ; clarification du périmètre réel des méthodes d'authentification (accès limité aux opérations implémentées) ; qualification de la durée du token jetonConnexionAppliMobile comme dépendante de l'instance/serveur et non garantie. |