From 6a73c6f050a13e49ce4f33837a408c73d33f4708 Mon Sep 17 00:00:00 2001 From: Samuel-Zacharie FAURE Date: Mon, 13 Jul 2026 15:50:36 +0200 Subject: [PATCH 1/3] Give CNAV v3 endpoints their own 100 req/min throttle --- commons/data/throttle.yml | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/commons/data/throttle.yml b/commons/data/throttle.yml index fd156b1e0..7f9732253 100644 --- a/commons/data/throttle.yml +++ b/commons/data/throttle.yml @@ -56,6 +56,28 @@ shared: throttle_type: 'by_group_of_endpoints' endpoints: - api_particulier_v3_ants_extrait_immatriculation_vehicule_with_france_connect + - api_particulier_v3_cnous_etudiant_boursier_with_civility + - api_particulier_v3_cnous_etudiant_boursier_with_france_connect + - api_particulier_v3_cnous_etudiant_boursier_with_ine + - api_particulier_v3_dsnj_service_national_with_civility + - api_particulier_v3_dsnj_service_national_with_france_connect + - api_particulier_v3_france_travail_indemnites_with_identifiant + - api_particulier_v3_france_travail_statut_with_identifiant + - api_particulier_v3_men_scolarites_with_civility + - api_particulier_v3_mesri_statut_etudiant_with_civility + - api_particulier_v3_mesri_statut_etudiant_with_france_connect + - api_particulier_v3_mesri_statut_etudiant_with_ine + - api_particulier_v3_sdh_statut_sportif_with_identifiant + - api_particulier_v3_gip_mds_service_civique_with_civility + - api_particulier_v3_gip_mds_service_civique_with_france_connect + limit: 20 + period: 1 + + cnav: + throttle_type: 'by_single_endpoint' + limit: 100 + period: 60 + endpoints: - api_particulier_v3_cnav_allocation_adulte_handicape_with_civility - api_particulier_v3_cnav_allocation_adulte_handicape_with_france_connect - api_particulier_v3_cnav_allocation_soutien_familial_with_civility @@ -74,22 +96,6 @@ shared: - api_particulier_v3_cnav_quotient_familial_with_france_connect - api_particulier_v3_cnav_revenu_solidarite_active_with_civility - api_particulier_v3_cnav_revenu_solidarite_active_with_france_connect - - api_particulier_v3_cnous_etudiant_boursier_with_civility - - api_particulier_v3_cnous_etudiant_boursier_with_france_connect - - api_particulier_v3_cnous_etudiant_boursier_with_ine - - api_particulier_v3_dsnj_service_national_with_civility - - api_particulier_v3_dsnj_service_national_with_france_connect - - api_particulier_v3_france_travail_indemnites_with_identifiant - - api_particulier_v3_france_travail_statut_with_identifiant - - api_particulier_v3_men_scolarites_with_civility - - api_particulier_v3_mesri_statut_etudiant_with_civility - - api_particulier_v3_mesri_statut_etudiant_with_france_connect - - api_particulier_v3_mesri_statut_etudiant_with_ine - - api_particulier_v3_sdh_statut_sportif_with_identifiant - - api_particulier_v3_gip_mds_service_civique_with_civility - - api_particulier_v3_gip_mds_service_civique_with_france_connect - limit: 20 - period: 1 inpi_rne: throttle_type: 'by_single_endpoint' From d0df9e6c80e2cf402212b998a792f7b19e64d0e4 Mon Sep 17 00:00:00 2001 From: Samuel-Zacharie FAURE Date: Mon, 13 Jul 2026 15:50:41 +0200 Subject: [PATCH 2/3] Throttle legacy CNAV v2 endpoints at 100 req/min too --- commons/data/throttle.yml | 6 ++++++ .../requests/rack_attack_acceptance_spec.rb | 21 ++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/commons/data/throttle.yml b/commons/data/throttle.yml index 7f9732253..6650ea37e 100644 --- a/commons/data/throttle.yml +++ b/commons/data/throttle.yml @@ -96,6 +96,12 @@ shared: - api_particulier_v3_cnav_quotient_familial_with_france_connect - api_particulier_v3_cnav_revenu_solidarite_active_with_civility - api_particulier_v3_cnav_revenu_solidarite_active_with_france_connect + - api_particulier_v2_cnav_allocation_adulte_handicape + - api_particulier_v2_cnav_allocation_soutien_familial + - api_particulier_v2_cnav_complementaire_sante_solidaire + - api_particulier_v2_cnav_prime_activite + - api_particulier_v2_cnav_quotient_familial_v2 + - api_particulier_v2_cnav_revenu_solidarite_active inpi_rne: throttle_type: 'by_single_endpoint' diff --git a/siade/spec/requests/rack_attack_acceptance_spec.rb b/siade/spec/requests/rack_attack_acceptance_spec.rb index 38e1da0e1..cc6e2b0a3 100644 --- a/siade/spec/requests/rack_attack_acceptance_spec.rb +++ b/siade/spec/requests/rack_attack_acceptance_spec.rb @@ -97,6 +97,12 @@ api_entreprise_proxied_files api_entreprise_v3_inpi_rne_beneficiaires_effectifs_open_data mcp + api_particulier_v2_cnav_allocation_adulte_handicape + api_particulier_v2_cnav_allocation_soutien_familial + api_particulier_v2_cnav_complementaire_sante_solidaire + api_particulier_v2_cnav_prime_activite + api_particulier_v2_cnav_quotient_familial_v2 + api_particulier_v2_cnav_revenu_solidarite_active ] end @@ -132,15 +138,28 @@ end describe 'all throttled endpoints' do + let(:throttled_v2_route_confs) do + %w[ + api_particulier_v2_cnav_allocation_adulte_handicape + api_particulier_v2_cnav_allocation_soutien_familial + api_particulier_v2_cnav_complementaire_sante_solidaire + api_particulier_v2_cnav_prime_activite + api_particulier_v2_cnav_quotient_familial_v2 + api_particulier_v2_cnav_revenu_solidarite_active + ].map { |op_id| OperationIdResolver.resolve(op_id) } + end + let(:all_routes) do Rails.application.routes.routes.each_with_object([]) do |route, res| next if route.defaults == {} - next if route.defaults[:controller] =~ %r{api_particulier/v2/} route_conf = { controller: route.defaults[:controller], action: route.defaults[:action] } + unthrottled_v2 = route.defaults[:controller] =~ %r{api_particulier/v2/} && throttled_v2_route_confs.exclude?(route_conf) + next if unthrottled_v2 + res.push(route_conf) unless non_throttled_endpoints.include?(route_conf) end end From f44c367ef679a45cb7079d2f5844e2dd5b137b15 Mon Sep 17 00:00:00 2001 From: Samuel-Zacharie FAURE Date: Mon, 13 Jul 2026 15:50:46 +0200 Subject: [PATCH 3/3] Document CNAV's dedicated rate limit on the API Particulier volumetry page --- site/config/locales/api_particulier/documentation.fr.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/site/config/locales/api_particulier/documentation.fr.yml b/site/config/locales/api_particulier/documentation.fr.yml index 08b166e69..31835719f 100644 --- a/site/config/locales/api_particulier/documentation.fr.yml +++ b/site/config/locales/api_particulier/documentation.fr.yml @@ -297,13 +297,16 @@ fr: content: |+ #### Les plafonds - Les limites de volumétrie sur API Particulier se décomposent en deux règles principales :  + Les limites de volumétrie sur API Particulier se décomposent comme suit :  - **Un plafond général par IP de 1000 requêtes/minute** ; - **Une volumétrie par habilitation :** 20 requêtes/secondes. + - **Exceptions :** certains endpoints échappent à cette règle et présentent une volumétrie spécifique par endpoint. C'est le cas des endpoints CNAV (ex. [allocation adulte handicapé](<%= endpoint_path(uid: 'cnav/allocation_adulte_handicape') %>), [RSA](<%= endpoint_path(uid: 'cnav/revenu_solidarite_active') %>)), limités à 100 requêtes/minute par endpoint. + {:.fr-highlight} + > La limite d'appels applicable est également indiquée sur la **fiche de chaque API** dans le catalogue, dans la section « Spécifications de l'API ». > ℹ️ Si une habilitation possède **plusieurs jetons** (par exemple un jeton classique et un jeton éditeur délégué), **la limite est partagée** entre tous : les appels de chaque jeton s'additionnent sur un même compteur. #### Informations volumétrie dans le header