ETQ admin, je dois fournir un filtrage réseau pour avoir un jeton API#13357
Merged
Conversation
mfo
force-pushed
the
harden-api-token
branch
6 times, most recently
from
June 26, 2026 14:20
ecadbd4 to
5a64d0b
Compare
mfo
marked this pull request as ready for review
June 26, 2026 14:24
colinux
approved these changes
Jun 29, 2026
colinux
left a comment
Member
There was a problem hiding this comment.
security review OK
Bien que ce soit un gain net en sécu, je réalise qu'on va augmenter la durée de tokens à vie illimitée, ce qui n'est pas idéal pour autant. Je crois qu'une prochaine étape c'est de limiter les tokens à 1 an comme un peu partout, sinon on pousse à l'inertie
| end | ||
|
|
||
| def assign_first_ip!(ip) | ||
| return unless requires_ip_filtering? && authorized_networks.empty? |
Member
There was a problem hiding this comment.
Suggested change
| return unless requires_ip_filtering? && authorized_networks.empty? | |
| return if !requires_ip_filtering? || authorized_networks.any? |
(pas de unless sur conditions multiples)
Existing tokens get `requires_ip_filtering: false` so their behavior is unchanged. A follow-up migration will flip the default to true for newly created tokens. Then change default requires_ip_filtering=true by default, enforcing mandatory network filtering at creation time. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
assign_first_ip! writes the caller's IP into authorized_networks on the first API call when the token has requires_ip_filtering=true but no networks configured yet (auto-assign mode). pending_auto_ip? returns true when a token is waiting for its first call to lock onto an IP. Ref demarche-numerique#13282 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When a token with requires_ip_filtering=true and empty authorized_networks makes its first API call, the caller's IP is written into authorized_networks. Subsequent calls from a different IP will be rejected (403). Legacy tokens (requires_ip_filtering=false) are unaffected. Ref demarche-numerique#13282 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
All new tokens are created with requires_ip_filtering=true. The autoAssign network filtering mode creates a token with empty authorized_networks that will lock onto the first caller's IP. Infinite lifetime is now allowed no matter what since the token will be IP-filtered after its first use. Ref demarche-numerique#13282 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace the old radio buttons ("custom networks" / "any IP") with
two new options:
- "Détection automatique au 1er appel API" (default)
- "Saisie manuelle des réseaux autorisés"
The "no filtering" option is removed. The "Infini" lifetime is
always available since every new token will have IP filtering.
Ref demarche-numerique#13282
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tokens awaiting their first API call show an info badge "en attente de détection IP (1er appel)" instead of the legacy "aucun filtrage réseau" warning. Ref demarche-numerique#13282 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add two new system specs covering the full token creation journey: - auto-assign mode: token created with empty networks, pending IP - manual mode: token created with explicit IP/CIDR Update existing test to use the new autoAssign radio value. Ref demarche-numerique#13282 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
IP filtering is now mandatory for all new tokens, so the guard on infinite lifetime is no longer needed. Remove the conditional and always accept infinite lifetime. Add an info message below the network input on the edit page when a token is pending auto-IP assignment. Ref demarche-numerique#13282 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Cover the same auto-assign scenarios as API v1: - auto-assign on first call when requires_ip_filtering is true - legacy token (requires_ip_filtering false) does not auto-assign - forbidden after IP is locked and request comes from different IP Ref demarche-numerique#13282 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
mfo
enabled auto-merge
June 30, 2026 03:11
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problème
Les jetons API peuvent être créés sans aucun filtrage réseau, ce qui permet leur utilisation depuis n'importe quelle adresse IP. En cas de vol de jeton, il peut être exploité depuis n'importe quelle machine.
Ref: #13282
Solution
Rend le filtrage réseau obligatoire pour tout nouveau jeton API via une colonne
requires_ip_filtering(2 migrations : default false pour le stock, puis default true pour les nouveaux).Deux modes au moment de la création :
assign_first_ip!)Les anciens jetons ne sont pas impactés. Un badge "en attente de détection IP" s'affiche dans la liste des jetons, et un message info apparaît sur la page d'édition sous l'input réseau.
Screenshots
Page sécurité – mode "Détection automatique" (défaut)
Page sécurité – mode "Saisie manuelle"
Confirmation de création du jeton
Profil – badge "en attente" sur le nouveau jeton
🤖 Generated with Claude Code