Remplacer l'ensemble des paramètres de protection contre les attaques
PUT /v1/attack-protection · permission attack-protection:write
Remplace l'objet complet de protection contre les attaques (application/json). Les sections et champs omis reviennent à leurs valeurs par défaut. If-Match est obligatoire : absent, cela donne 428 ; ETag périmé, 412. Réécrire le même objet n'écrit rien et conserve l'ETag. Pour modifier quelques champs, utilisez PATCH.
Requête
| Champ | Type | Obligatoire | Description |
|---|---|---|---|
If-Match |
en-tête | oui | L'ETag de l'objet tel que lu en dernier. Absent : 428 ; périmé : 412. |
| corps | objet | oui | L'objet configuré, au plus 32 KiB. Chaque section est facultative ; chaque champ d'une section l'est aussi. |
| Champ | Type | Plage ou valeurs | Valeur par défaut | Plancher |
|---|---|---|---|---|
brute_force.mode |
texte | log, enforce |
enforce |
|
brute_force.max_failures |
entier | 5-100 | 20 | au plus 100 |
brute_force.window_minutes |
entier | 5-60 | 15 | |
brute_force.lock_minutes |
entier | 5-60 | 15 | au moins 5 |
brute_force.notify_user |
booléen | true |
||
suspicious_ip_throttling.mode |
texte | log, enforce |
enforce |
|
suspicious_ip_throttling.login_failures_per_ip_per_day |
entier | 10-10000 | 100 | |
suspicious_ip_throttling.signups_per_ip_per_hour |
entier | 1-20 | 20 | au plus 20 |
suspicious_ip_throttling.allowlist |
tableau de texte | jusqu'à 100 préfixes CIDR ; IPv4 pas plus large que /8, IPv6 pas plus large que /32 | [] |
|
credential_stuffing.mode |
texte | log, enforce |
enforce |
|
credential_stuffing.attack_mode_auto |
booléen | true |
||
credential_stuffing.attack_mode_duration_minutes |
entier | 15-240 | 30 | |
bot_protection.mode |
texte | off, risk_based, always |
risk_based |
|
bot_protection.provider |
texte | altcha |
altcha |
|
breached_password.on_signup |
texte | block |
block |
block |
breached_password.on_password_change |
texte | block |
block |
block |
breached_password.on_login |
texte | require_reset, notify |
require_reset |
|
breached_password.notify_user |
booléen | true |
||
signup_protection.block_disposable_email |
booléen | true |
||
signup_protection.block_email_subaddress |
booléen | false |
||
signup_protection.max_signups_per_device_30d |
entier | 1-50 | 3 | |
sms_protection.allowed_countries |
tableau de texte | jusqu'à 250 codes ISO 3166-1 alpha-2 | [] (valeur du plan) |
|
sms_protection.daily_cap |
entier | null | 1-1000000 ; null est la valeur du plan |
null |
|
sms_protection.conversion_breaker |
booléen | true |
true |
|
risk_policy.mode |
texte | log, enforce (enforce requiert le plan Startup ou supérieur) |
log |
|
risk_policy.challenge_threshold |
entier | 3-8 | 4 | |
risk_policy.block_threshold |
entier | null | 6-12, supérieur à challenge_threshold ; null désactive |
null |
|
risk_policy.notify_user_on_new_device |
booléen | true |
Une valeur en dessous du plancher de sécurité est refusée avec 422 below_security_floor, même si elle se situe dans la plage générale du champ : le plancher protège tous les environnements et ne peut pas être abaissé.
Comportement
- La modification s'applique immédiatement aux nouvelles connexions : les paramètres en cache sont invalidés dans la même transaction.
- L'enregistrement d'audit contient les noms des champs modifiés, ainsi que l'objet précédent et le nouveau.
Réponse
200 OK avec l'objet, comme dans Obtenir les paramètres de protection contre les attaques, et le nouvel ETag.
Erreurs
| HTTP | code | Quand |
|---|---|---|
| 400 | unknown_field |
Une section ou un champ ne fait pas partie de l'objet. errors[] liste les pointeurs. |
| 400 | malformed_request |
Le corps n'est pas un JSON valide, ou l'en-tête If-Match est mal formé. |
| 401 | unauthenticated |
L'identifiant est absent, invalide ou révoqué. |
| 403 | insufficient_permissions |
L'identifiant n'a pas attack-protection:write. |
| 403 | plan_feature_unavailable |
risk_policy.mode vaut enforce et le plan ne l'inclut pas ; le corps contient feature et required_plan. |
| 412 | precondition_failed |
L'objet a changé depuis votre lecture. Relisez-le et réessayez. |
| 413 | payload_too_large |
L'objet dépasse 32 KiB. |
| 422 | validation_failed |
Une valeur a le mauvais type ou est hors plage, ou block_threshold n'est pas supérieur à challenge_threshold. errors[] liste les pointeurs. |
| 422 | below_security_floor |
Une valeur est sous le plancher de sécurité. Chaque entrée de errors[] nomme le champ et son plancher dans detail. |
| 422 | allowlist_range_too_broad |
Un préfixe de liste d'autorisation est plus large que /8 (IPv4) ou /32 (IPv6). |
| 428 | precondition_required |
If-Match est absent. |
| 429 | rate_limited |
La limite de débit est dépassée ; réessayez après la durée Retry-After. |
| 503 | service_unavailable |
Une dépendance est temporairement indisponible ; réessayez après la durée Retry-After. |
Si plusieurs types d'erreur sont présents, seul le plus grave est renvoyé, dans cet ordre : unknown_field, validation_failed, below_security_floor, allowlist_range_too_broad, plan_feature_unavailable. Les valeurs écrites ne sont jamais renvoyées dans la réponse.
Exemple
curl -X PUT https://api.eu.keenauth.com/v1/attack-protection \
-H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
-H "Content-Type: application/json" \
-H 'If-Match: "3f1c9a0b5d7e2a4c6b8d0e1f2a3b4c5d"' \
-d '{"brute_force": {"max_failures": 10, "lock_minutes": 30}, "bot_protection": {"mode": "always"}}'