Reemplazar la configuración de protección frente a ataques
PUT /v1/attack-protection · permiso attack-protection:write
Reemplaza el objeto completo de protección frente a ataques (application/json). Las secciones y los campos que omita vuelven a sus valores predeterminados. If-Match es obligatorio: si falta, se devuelve 428; si el ETag está desactualizado, 412. Volver a escribir el mismo objeto no escribe nada y conserva el ETag. Para cambiar unos pocos campos, use PATCH.
Solicitud
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
If-Match |
encabezado | sí | El ETag del objeto tal como se leyó por última vez. Si falta: 428; si está desactualizado: 412. |
| cuerpo | objeto | sí | El objeto configurado, como máximo 32 KiB. Cada sección es opcional; cada campo dentro de una sección también lo es. |
| Campo | Tipo | Rango o valores | Predeterminado | Mínimo |
|---|---|---|---|---|
brute_force.mode |
texto | log, enforce |
enforce |
|
brute_force.max_failures |
entero | 5-100 | 20 | como máximo 100 |
brute_force.window_minutes |
entero | 5-60 | 15 | |
brute_force.lock_minutes |
entero | 5-60 | 15 | al menos 5 |
brute_force.notify_user |
booleano | true |
||
suspicious_ip_throttling.mode |
texto | log, enforce |
enforce |
|
suspicious_ip_throttling.login_failures_per_ip_per_day |
entero | 10-10000 | 100 | |
suspicious_ip_throttling.signups_per_ip_per_hour |
entero | 1-20 | 20 | como máximo 20 |
suspicious_ip_throttling.allowlist |
array de texto | hasta 100 prefijos CIDR; IPv4 no más amplio que /8, IPv6 no más amplio que /32 | [] |
|
credential_stuffing.mode |
texto | log, enforce |
enforce |
|
credential_stuffing.attack_mode_auto |
booleano | true |
||
credential_stuffing.attack_mode_duration_minutes |
entero | 15-240 | 30 | |
bot_protection.mode |
texto | off, risk_based, always |
risk_based |
|
bot_protection.provider |
texto | altcha |
altcha |
|
breached_password.on_signup |
texto | block |
block |
block |
breached_password.on_password_change |
texto | block |
block |
block |
breached_password.on_login |
texto | require_reset, notify |
require_reset |
|
breached_password.notify_user |
booleano | true |
||
signup_protection.block_disposable_email |
booleano | true |
||
signup_protection.block_email_subaddress |
booleano | false |
||
signup_protection.max_signups_per_device_30d |
entero | 1-50 | 3 | |
sms_protection.allowed_countries |
array de texto | hasta 250 códigos ISO 3166-1 alpha-2 | [] (predeterminado del plan) |
|
sms_protection.daily_cap |
entero | null | 1-1000000; null es el valor del plan |
null |
|
sms_protection.conversion_breaker |
booleano | true |
true |
|
risk_policy.mode |
texto | log, enforce (enforce requiere el plan Startup o superior) |
log |
|
risk_policy.challenge_threshold |
entero | 3-8 | 4 | |
risk_policy.block_threshold |
entero | null | 6-12, mayor que challenge_threshold; null está desactivado |
null |
|
risk_policy.notify_user_on_new_device |
booleano | true |
Un valor por debajo del mínimo de seguridad se rechaza con 422 below_security_floor, aunque esté dentro del rango general del campo: el mínimo protege a todos los entornos y no puede rebajarse.
Comportamiento
- El cambio se aplica de inmediato a los nuevos inicios de sesión: la configuración en caché se invalida en la misma transacción.
- El registro de auditoría contiene los nombres de los campos modificados y los objetos anterior y nuevo.
Respuesta
200 OK con el objeto, como en Obtener la configuración de protección frente a ataques, y el nuevo ETag.
Errores
| HTTP | código | Cuándo |
|---|---|---|
| 400 | unknown_field |
Una sección o un campo no forma parte del objeto. errors[] enumera los punteros. |
| 400 | malformed_request |
El cuerpo no es JSON válido o el encabezado If-Match está mal formado. |
| 401 | unauthenticated |
La credencial falta, no es válida o fue revocada. |
| 403 | insufficient_permissions |
La credencial no tiene attack-protection:write. |
| 403 | plan_feature_unavailable |
risk_policy.mode es enforce y el plan no lo incluye; el cuerpo contiene feature y required_plan. |
| 412 | precondition_failed |
El objeto cambió desde que lo leyó. Léalo de nuevo y reintente. |
| 413 | payload_too_large |
El objeto supera 32 KiB. |
| 422 | validation_failed |
Un valor tiene un tipo incorrecto o está fuera de rango, o block_threshold no es mayor que challenge_threshold. errors[] enumera los punteros. |
| 422 | below_security_floor |
Un valor está por debajo del mínimo de seguridad. Cada entrada de errors[] indica en detail el campo y su mínimo. |
| 422 | allowlist_range_too_broad |
Un prefijo de la lista de permitidos es más amplio que /8 (IPv4) o /32 (IPv6). |
| 428 | precondition_required |
Falta If-Match. |
| 429 | rate_limited |
Se superó el límite de frecuencia; reintente después del periodo indicado en Retry-After. |
| 503 | service_unavailable |
Una dependencia no está disponible temporalmente; reintente después del periodo indicado en Retry-After. |
Si hay varios tipos de error, solo se devuelve el más grave, en este orden: unknown_field, validation_failed, below_security_floor, allowlist_range_too_broad, plan_feature_unavailable. Los valores escritos nunca se devuelven en la respuesta.
Ejemplo
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"}}'