Skip to content

feat(ra-console): relais de l'enregistrement de clé vers ca-server - #29

Merged
PhilippeVienne merged 2 commits into
devfrom
feat/ra-console-relais-inscription
Sep 21, 2026
Merged

PhilippeVienne merged 2 commits into
devfrom
feat/ra-console-relais-inscription

Conversation

@PhilippeVienne

Copy link
Copy Markdown
Contributor

PR empilée sur #28 (pile : #19 → #20 → #21 → #22 → #24 → #25 → #26 → #28 → celle-ci). Base : feat/ra-console-squelette. À rebrancher sur dev après chaque merge : gh api -X PATCH repos/open-eidas/open-eidas/pulls/N -f base=dev.

Contenu

Tranche 1b de ra-console (docs/WEBUI.md §15 étape 1) : POST /api/v1/webauthn/register/begin puis /finish. L'invité présente son jeton d'invitation, la console relaie à ca-server par le lien mTLS (/internal/v1/register/*). Elle ne lit pas l'attestation et ne la comprend pas : ca-server la vérifie contre la liste blanche de modèles et range la clé ; la console n'en garde rien.

  • La console reconstruit ce qu'elle relaie à partir de champs qu'elle a validés : Content-Type: application/json exigé (pas d'envoi « aveugle » d'un formulaire piégé, qui ne peut pas déclarer du JSON sans pré-requête CORS), champs connus seulement, jeton de 1 à 256 caractères, identifiant de cérémonie au format UUID, corps de 64 Kio au plus. Elle ne fait jamais suivre tel quel ce qu'un navigateur lui envoie.
  • Refus vs pannes : un refus de ca-server (4xx) est rendu avec son code et son message, faits pour cela (jeton invalide, attestation refusée…) ; une panne (5xx, injoignable, registre bloqué) devient un 502 ca_unavailable générique : ni adresse, ni cause, ni divergence du registre. Le jeton n'est ni journalisé ni renvoyé.
  • Le certificat que ca-server présente est maintenant contrôlé (politique, SAN, validité) à chaque réponse relayée, plus seulement à la sonde : CaLink::send factorise l'appel.

Points d'attention

  • Pas de limitation de débit sur ces routes anonymes : le jeton fait 256 bits et vit 24 h au plus, mais l'endpoint peut être martelé. C'est en TODO (par adresse et globale, en tenant compte du proxy de la Gateway) ; à traiter avant d'exposer la console.
  • Ces routes relaient le seul chemin par jeton d'invitation. La variante « admin authentifié » et l'auto-ajout de clé (avec réassertion) viendront avec les sessions (1c).
  • Deux contrôles de la console (format UUID de la cérémonie, limite de 64 Kio) survivent à la mutation : ca-server les refait de son côté (même limite, même parsing), donc ils ne sont pas observables depuis un test de bout en bout. Ils protègent la mémoire et le réseau interne de la console elle-même ; je les ai gardés pour cela.

Vérifications

  • cargo fmt --check, cargo clippy --workspace --all-targets -- -D warnings, cargo test --workspace (avec PostgreSQL, 79 suites), cargo audit --ignore RUSTSEC-2023-0071 : verts.
  • 5 tests de bout en bout : navigateur factice → ra-console → lien mTLS → le vrai routeur interne de ca-server, sur un vrai PostgreSQL et un authentificateur logiciel.
    • un administrateur invité enregistre sa clé (elle est bien dans le registre, rangée par ca-server), puis le jeton est consommé et son rejeu refusé sans jamais le renvoyer ;
    • ce que la console refuse elle-même (Content-Type, corps mal formés, champs inconnus, jeton hors bornes, UUID, trop gros) ;
    • un jeton inconnu reçoit le refus de ca-server ;
    • un registre bloqué côté ca-server (divergence du journal) ne fuit rien vers le navigateur ;
    • ca-server injoignable : 502 générique, sans adresse ni port ni cause ni jeton (ce test ne demande aucune base).
  • Contrôle par mutation : Content-Type non exigé, champs inconnus relayés, détail des pannes relayé, jeton non borné, refus de ca-server masqué. Chacun fait échouer le test visé.

POST /api/v1/webauthn/register/begin puis /finish (docs/WEBUI.md §5, §10) :
l'invité présente son jeton d'invitation, et la console relaie à ca-server par
le lien mTLS. Elle ne lit pas l'attestation et ne la comprend pas : ca-server
la vérifie contre la liste blanche de modèles et range la clé, la console n'en
garde rien.

- la console reconstruit ce qu'elle relaie à partir de champs qu'elle a
  validés : Content-Type application/json exigé (pas d'envoi aveugle d'un
  formulaire piégé), champs connus seulement, jeton de 1 à 256 caractères,
  identifiant de cérémonie au format UUID, corps de 64 Kio au plus ;
- un refus de ca-server (4xx) est rendu avec son code et son message ; une
  panne (5xx, injoignable, registre bloqué) devient un 502 ca_unavailable
  générique, sans adresse, sans cause ni divergence. Le jeton n'est ni
  journalisé ni renvoyé ;
- le certificat que ca-server présente est contrôlé (politique, SAN,
  validité) à chaque réponse relayée, plus seulement à la sonde.

Pas encore de limitation de débit sur ces routes anonymes (TODO).
Le clippy de Rust 1.98 (celui de la CI, toolchain stable) refuse une variante
Err d'au moins 128 octets (result_large_err) ; celui de la 1.97 locale ne la
connaissait pas. Le contrôle du Content-Type devient un booléen, et le refus
415 est construit par l'appelant. Comportement inchangé.
@PhilippeVienne
PhilippeVienne force-pushed the feat/ra-console-relais-inscription branch from a35a411 to 4a0fba2 Compare September 21, 2026 11:15
@PhilippeVienne
PhilippeVienne changed the base branch from feat/ra-console-squelette to dev September 21, 2026 11:15
@PhilippeVienne
PhilippeVienne merged commit bb8b19f into dev Sep 21, 2026
26 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant