Skip to content

feat(ra-console): exécution des décisions signées approve/reject (étape 3b) - #65

Open
PhilippeVienne wants to merge 1 commit into
feat/ra-console-action-challengefrom
feat/ra-console-action-execute
Open

PhilippeVienne wants to merge 1 commit into
feat/ra-console-action-challengefrom
feat/ra-console-action-execute

Conversation

@PhilippeVienne

Copy link
Copy Markdown
Contributor

Objet

docs/WEBUI.md §15 étape 3, tranche 3b (après 3a, #64). Schéma §4, étapes 5 à 7. Empilée sur #64 (feat/ra-console-action-challenge, tête 37958f4 à l'ouverture) : merger #64 d'abord, puis git rebase --onto origin/dev 37958f4 et rebrancher sur dev.

  • POST /api/v1/requests/{id}/approve et /reject (session obligatoire) : {"challenge_id", "assertion"}. La console relaie à ca-server (/internal/v1/actions) l'identifiant du challenge et l'assertion brute — jamais de corps : ca-server exécute celui qu'il a figé.
  • Lien assertion ↔ demande contrôlé par ca-server (décision de l'utilisateur, conforme au §5) : la console joint expect (action et demande du chemin) ; oe_actions::Service::execute_expecting le compare au corps figé avant de retirer l'état de la cérémonie, et refuse (409 action_mismatch) s'il diffère. Une signature obtenue pour une demande ne décide jamais d'une autre, ni l'inverse de ce qui a été signé — et l'assertion reste utilisable sur la bonne route. expect ne peut que restreindre ; execute sans attente (appelants existants) est inchangé. /internal/v1/actions refuse toujours tout champ body (deny_unknown_fields).
  • Réponse de la forme du §5 : {"transaction_id", "state": "APPROVED"|"REJECTED", "decided_by", "action_id"} ; decided_by est l'opérateur dont la clé a signé, lu dans le registre de ca-server, pas celui de la session.
  • Journal de la console : ra.action_relayed (opérateur de la session, action, demande, action_id, signataire selon ca-server, statut).
  • docs/RA-CONSOLE.md : la route, et ce qui reste (étape 4 et suivantes).

Avec #64, l'étape 3 est complète côté API : un opérateur ra_operateur peut approuver ou rejeter une demande par sa clé FIDO2, de bout en bout, sans le CLI. Le frontend (étape 6) reste à faire.

Vérifications

  • bin/ra-console/tests/action_challenge.rs, contre le vrai service d'actions de ca-server et PostgreSQL : approbation et rejet de bout en bout (decided_by = signataire, état en base) ; rejeu refusé (already_used) ; assertion présentée pour une autre demande ou pour l'autre décision refusée (action_mismatch), rien de décidé, puis la même assertion acceptée sur la bonne route ; corps non relayés (UUID invalide, assertion absente, corps d'action glissé, non-JSON, sans session). Test unitaire d'Expect.
  • Mutation (3 mutants, tous tués) : contrôle expect retiré ; contrôle déplacé après la consommation de la cérémonie (l'assertion devient inutilisable sur la bonne route) ; expect non envoyé par la console.
  • 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.

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 3b)

docs/WEBUI.md §15 étape 3, §4 étapes 5 à 7 : `POST
/api/v1/requests/{id}/approve|reject` relaie à ca-server
(`/internal/v1/actions`) l'identifiant du challenge et l'assertion brute,
jamais de corps : ca-server exécute celui qu'il a figé.

- Lien assertion ↔ demande contrôlé par ca-server (décision de
  l'utilisateur) : la console joint `expect` (action et demande du
  chemin) ; oe_actions::Service::execute_expecting le compare au corps
  figé avant de retirer l'état de la cérémonie, et refuse (409
  action_mismatch) s'il diffère. Une signature obtenue pour une demande
  ne décide jamais d'une autre, ni l'inverse de ce qui a été signé, et
  l'assertion reste utilisable sur la bonne route. `expect` ne peut que
  restreindre ; `execute` sans attente est inchangé.
- Réponse de la forme du §5 : `decided_by` est l'opérateur dont la clé a
  signé, lu dans le registre de ca-server.
- Journal de la console : ra.action_relayed.
- Tests de bout en bout (approbation, rejet, rejeu, mauvaise cible,
  corps non relayés) et unitaire d'Expect ; trois mutations tuées
  (contrôle retiré, contrôle après consommation, expect non envoyé).

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