Skip to content

feat(ra-console): préparation des actions signées approve/reject (étape 3a) - #64

Open
PhilippeVienne wants to merge 1 commit into
devfrom
feat/ra-console-action-challenge
Open

PhilippeVienne wants to merge 1 commit into
devfrom
feat/ra-console-action-challenge

Conversation

@PhilippeVienne

Copy link
Copy Markdown
Contributor

Objet

docs/WEBUI.md §15 étape 3 (actions RA signées), tranche 3a du découpage validé (3a : préparation du challenge → 3b : exécution avec lien à la cible contrôlé par ca-server). Schéma de signature §4, étapes 1 à 3. Base dev, indépendante des autres PR ouvertes.

Côté ca-server, tout existait déjà (oe-actions : /internal/v1/challenge fige l'action, /internal/v1/actions l'exécute sur assertion) ; il manquait le relais dans ra-console.

  • POST /api/v1/webauthn/challenge (session obligatoire) : le corps est l'action, dans la forme d'oe_actions ({"action": "approve_request", "transaction_id": "…", "comment": "…"}). La console relaie à ca-server, qui rend le corps figé, body_hash, action_id, challenge_id et les options WebAuthn.
  • Le challenge vise l'opérateur de la session : operator_hint vient de la session (Authenticated gagne operator_id), jamais du navigateur. L'action est relue dans l'énumération fermée puis resérialisée : un champ en trop ne franchit pas la console.
  • Seuls approve_request / reject_request sont préparés à ce stade ; toute autre action → 403 action_not_available, sans solliciter ca-server (révocation : étape 4).
  • Le rôle est jugé par ca-server, pas par la console (§3) : un administrateur ne peut pas approuver, la console relaie le refus.
  • Journal de la console : ra.action_challenge (opérateur, action, action_id, body_hash, statut), rapprochable du journal de ca-server ; AppState gagne journal.
  • docs/RA-CONSOLE.md : la nouvelle route, et la section « ce qui n'existe pas encore » corrigée (elle disait la connexion absente).

Limites

  • L'exécution (relais de l'assertion) est la tranche 3b : elle ajoutera à /internal/v1/actions un champ expect contrôlé par ca-server, pour qu'une assertion obtenue pour la demande A ne puisse pas être présentée sur /requests/B/approve (décision de l'utilisateur : contrôle côté ca-server).
  • Pas de limitation de débit (décidée à la Gateway, TODO §2).

Vérifications

  • bin/ra-console/tests/action_challenge.rs, contre le vrai service d'actions de ca-server (routeur interne réel, mTLS) et un vrai PostgreSQL, authentificateur logiciel : challenge émis pour les clés de la session même si le navigateur glisse l'identifiant d'un autre opérateur ; rien de figé sans session, hors étape 3, pour une action inconnue ou un corps non JSON ; refus de ca-server pour un administrateur et pour une demande inconnue.
  • Mutation (3 mutants, tous tués) : operator_hint repris du navigateur, filtre de l'étape 3 retiré, session non exigée.
  • cargo fmt --check, cargo clippy --workspace --all-targets -- -D warnings (1.97 et 1.98.1), cargo test --workspace avec PostgreSQL, cargo audit --ignore RUSTSEC-2023-0071 : verts. Aucune nouvelle dépendance normale de ra-console (no_pkcs11.rs vert).

Revue humaine obligatoire

Voir PROVENANCE.md. Chaque case est cochée par le
contributeur humain qui valide la PR, après l'avoir fait lui-même.

  • Revue d'architecture validée par l'humain
  • Code relu et tests unitaires/intégration vérifiés localement
  • Absence de dépendances tierces incompatibles avec la double licence EUPL-1.2 / AGPL-3.0 (make licenses)
  • Validation de l'apport intellectuel et de la paternité humaine sur la modification

Assistance par IA

  • Cette PR a été produite avec l'assistance de Claude Code : les commits concernés portent la remorque Co-authored-by: Claude <noreply@anthropic.com>, auteur et committer restent humains, et scripts/provenance.py archive a été lancé
  • Cette PR a été écrite sans assistance par IA

…pe 3a)

docs/WEBUI.md §15 étape 3, schéma de signature §4 étapes 1 à 3 :
`POST /api/v1/webauthn/challenge` relaie à ca-server
(`/internal/v1/challenge`) l'action demandée par l'opérateur connecté ;
ca-server la fige et rend le corps qu'il exécutera, son empreinte et les
options WebAuthn.

- Le challenge vise l'opérateur de la session : `operator_hint` vient de
  la session (Authenticated gagne `operator_id`), jamais du navigateur.
  L'action est relue dans l'énumération fermée d'oe_actions puis
  resérialisée : un champ en trop ne franchit pas la console.
- Seuls approve_request et reject_request sont préparés à ce stade (403
  action_not_available sinon, sans solliciter ca-server). Le rôle et
  l'état de la demande restent jugés par ca-server.
- Journal de la console : ra.action_challenge (AppState gagne `journal`).
- action_challenge.rs, contre le vrai service d'actions de ca-server et
  PostgreSQL ; trois mutations tuées (indice venu du navigateur, filtre
  de l'étape, session non exigée).
- docs/RA-CONSOLE.md mis à jour.

Co-authored-by: Claude <noreply@anthropic.com>
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