Cognito threat protection: the basics
What threat protection actually does to a user pool
Amazon Cognito user pools are how millions of apps authenticate end users — sign-up, sign-in, password reset, MFA. Threat protection (renamed from "Advanced Security" in late 2024) is the security layer Cognito layers on top of the raw auth flow. It scores every authentication attempt for risk and can challenge or block the ones that look wrong, without requiring a single line of application code.
Three things get scored on every sign-in: whether the password appears in a globally-maintained breach corpus (compromised credentials), whether the device/IP/geo/velocity looks anomalous for that user (account takeover), and whether the request looks like an automated scraper or credential-stuffing bot. Each attempt comes out with a LOW / MEDIUM / HIGH risk label, and you decide what happens at each level — no action, an MFA challenge, or an outright block.
Security Hub flags two related findings: Cognito.3 ("User pools should have threat protection activated") and Cognito.4 ("Threat protection should be activated for custom authentication"). The standard control covers USER_SRP_AUTH and USER_PASSWORD_AUTH; the custom-auth control covers Lambda-trigger flows like passwordless or magic-link sign-in. Both have to be set to ENFORCED — AUDIT mode logs the risk but doesn't act on it, which fails the control.
In this lesson you'll learn what threat protection scores, the three enforcement modes, how to wire risk levels to actions, and the difference between standard and custom-auth coverage. You'll see real CLI to inspect a pool's current configuration and the exact set-risk-configuration call to enable full enforcement with sensible defaults.
Credential stuffing is the #1 attack vector
Verizon's 2024 Data Breach Investigations Report attributes roughly 24% of all confirmed breaches to credential stuffing and brute-force — attackers replaying leaked username/password pairs from other sites against your login endpoint. Cognito's compromised-credentials check compares each sign-in against a corpus of billions of leaked pairs and blocks the match before the password is even validated. Turning it on takes one API call; not turning it on is roughly the security equivalent of leaving the login form unrate-limited.
Enabling threat protection in action
Priya is the platform lead at a healthtech SaaS. Security Hub fires Cognito.3 against their production user pool us-east-1_aB3cD4eF5 — threat protection is OFF. Two weeks earlier the pool saw a 40× spike in failed logins from a single ASN; the SOC suspected credential stuffing but had no per-attempt risk signal to confirm.
She doesn't flip everything to ENFORCED blind — she wants to see what's currently configured and what the risk distribution looks like first. AUDIT mode is a useful stepping stone: it logs risk decisions to CloudWatch without blocking real users, so you can tune the action map before turning enforcement on.
She starts by describing the pool to see the current security mode.
First, check the pool's current threat-protection state. The relevant field is UserPoolAddOns.AdvancedSecurityMode.
Current state of the flagged pool. Threat protection is dark.
Enable threat protection in ENFORCED mode and wire the risk-action map. HIGH blocks, MEDIUM challenges with MFA, LOW logs only. Compromised credentials always block.
Risk configuration applied. Compromised passwords blocked outright; ATO scored and acted on per risk level.
Threat protection under the hooddeep dive
Threat protection runs as an inline interceptor in the Cognito auth flow. When a sign-in lands, Cognito computes a fingerprint from device characteristics, source IP, AS number, geo-location, time-of-day relative to the user's historical pattern, and velocity (how fast the user moves between locations or devices). That fingerprint is scored against the user's behavioural baseline and against global indicators of compromise, and the result is a risk band — LOW, MEDIUM, or HIGH.
The compromised-credentials check is a separate pipeline. Cognito maintains an indexed corpus of credentials leaked across known public dumps; on every SIGN_IN, PASSWORD_CHANGE, or SIGN_UP it hashes the submitted password client-side-style and looks it up. A match means "this exact username+password pair is already in the wild" — the safe action is always BLOCK because letting it through is opting in to credential stuffing.
Modes form a ladder: OFF (no scoring, no logs, no cost), AUDIT (full scoring, CloudWatch events, no enforcement — useful for tuning), and ENFORCED (full scoring and the configured EventAction per risk level — what Cognito.3 requires). Custom-auth flows (CUSTOM_AUTH challenges driven by Lambda triggers) have their own configuration block because the auth pipeline is different — that's why Cognito.4 exists as a separate control.
# Inspect both standard and custom-auth risk configs in one call.
aws cognito-idp describe-risk-configuration \
--user-pool-id us-east-1_aB3cD4eF5 \
--query 'RiskConfiguration.{Std:AccountTakeoverRiskConfiguration.Actions,Compromised:CompromisedCredentialsRiskConfiguration.Actions}' What is the impact of leaving threat protection off?
The direct impact is unscored auth. Without threat protection, every sign-in attempt is treated the same — a legitimate user logging in from their usual device gets the same trust as a credential-stuffing bot replaying a leaked password from a residential proxy in another country. Cognito has no signal to block the second case, so it doesn't.
The second-order impact is breach blast radius. Once an attacker takes over a user's account they can change the email, rotate MFA, exfiltrate data, and pivot to internal flows the user has access to. The cost of one successful account takeover at a SaaS company is typically measured in tens of thousands of dollars in incident response, customer communication, and credential rotation — multiples of the per-MAU threat-protection charge across an entire pool.
Regulatory consequences compound the picture. SOC 2, ISO 27001, HIPAA, and GDPR all expect risk-based authentication controls. A Security Hub Cognito.3 finding sitting open in your audit trail is documented evidence that you knew the control existed and chose not to enable it — which materially affects how an auditor treats the rest of your identity stack.
The cost side is straightforward: threat protection bills per monthly active user (MAU) above the free tier, typically a small fraction of a cent per MAU. For most pools the bill is a rounding error compared to the engineering hours one account-takeover incident consumes. The math almost never says "leave it off".
How do you enable threat protection safely?
Turning threat protection on is a four-step loop. Skipping any step gets you either a flood of false-positive blocks or a configuration that passes the Security Hub check but does nothing useful.
1. Inventory the pool's current state and auth flows
Use describe-user-pool to read AdvancedSecurityMode and MfaConfiguration, and list-user-pool-clients to see which clients use USER_SRP_AUTH, USER_PASSWORD_AUTH, or CUSTOM_AUTH. The custom-auth flows need their own configuration block — Cognito.4 will keep failing if you only set the standard one.
2. Start in AUDIT mode and tune the action map
Set the pool to AUDIT for a week and watch the CloudWatch events. You'll see the real risk distribution for your user base — what fraction of sign-ins score MEDIUM, where geo-anomaly false positives are coming from (travelling employees, mobile carriers that NAT through unexpected regions). Tune the per-risk action map before flipping to ENFORCED.
3. Flip to ENFORCED with compromised-credentials always BLOCK
Use set-risk-configuration with AccountTakeoverRiskConfiguration set to your tuned map (typical: LOW=NO_ACTION+notify, MEDIUM=MFA_IF_CONFIGURED, HIGH=BLOCK) and CompromisedCredentialsRiskConfiguration set to BLOCK across SIGN_IN, PASSWORD_CHANGE, and SIGN_UP. Set the pool's UserPoolAddOns.AdvancedSecurityMode to ENFORCED. Then repeat for the custom-auth configuration if any client uses CUSTOM_AUTH.
4. Pair with MFA-required and WebAuthn for phishing-resistance
Threat protection challenges with MFA on medium-risk sign-ins, which only helps if MFA is actually enrolled. Move MfaConfiguration to ON (required) for high-value pools and enable WebAuthn so the second factor is phishing-resistant. Re-evaluate the risk distribution quarterly — attacker behaviour drifts, and so does your user base.
# Step 1: flip the pool into ENFORCED.
aws cognito-idp update-user-pool \
--user-pool-id us-east-1_aB3cD4eF5 \
--user-pool-add-ons AdvancedSecurityMode=ENFORCED
# Step 2: wire the standard-auth risk configuration.
aws cognito-idp set-risk-configuration \
--user-pool-id us-east-1_aB3cD4eF5 \
--compromised-credentials-risk-configuration \
EventFilter=SIGN_IN,PASSWORD_CHANGE,SIGN_UP,Actions={EventAction=BLOCK} \
--account-takeover-risk-configuration \
Actions='{LowAction={EventAction=NO_ACTION,Notify=true},MediumAction={EventAction=MFA_IF_CONFIGURED,Notify=true},HighAction={EventAction=BLOCK,Notify=true}}'
# Step 3: same call scoped to a CUSTOM_AUTH client closes Cognito.4.
aws cognito-idp set-risk-configuration \
--user-pool-id us-east-1_aB3cD4eF5 \
--client-id 7abcd1234efgh5678ijklmnop \
--account-takeover-risk-configuration \
Actions='{HighAction={EventAction=BLOCK,Notify=true}}' Quick quiz
Question 1 of 5Security Hub fires Cognito.3 against your production user pool with AdvancedSecurityMode set to AUDIT. What's the right next move?
You scored
0 / 5
Keep learning
Dig deeper into Cognito threat protection and the broader identity-hardening picture.
- Amazon Cognito — Threat protection Service docs covering risk levels, action map, compromised credentials, and custom-auth configuration.
- AWS Security Hub controls — Cognito Exact definitions, severity, and remediation guidance for Cognito.3, Cognito.4, and related controls.
- Amazon Cognito MFA and WebAuthn Pair threat protection with required MFA and phishing-resistant WebAuthn second factors.
- Verizon 2024 Data Breach Investigations Report Industry baseline for credential-stuffing and account-takeover trends that drive the threat-protection feature set.
You've completed Enable Cognito threat protection. You can now read a user pool's current security mode, run AUDIT-then-tune-then-ENFORCED, configure compromised-credentials and account-takeover actions per risk level, and cover both standard and custom-auth flows. The next time Security Hub fires Cognito.3 or Cognito.4, you'll have a four-step loop ready to run.
Back to the library