Executive summary
Amazon Cognito user pools have gained an administrative API operation,
AdminDeleteSoftwareToken, that deletes a user’s registered TOTP
authenticator. It closes a gap that had an almost comically bad workaround: before this
update, the only recovery path for users locked out of their TOTP devices was to recreate
their accounts. It is available in all AWS Regions where Amazon Cognito is available.
The operational win is obvious and worth having. The part worth reading carefully is what the permission means. An API that removes a user’s second factor is, by construction, an account-takeover primitive — and because the operation also removes the user’s TOTP preference without touching their other registered factors, granting it to a support role can silently convert a strong factor into a weaker one for any user in the pool.
What changed
The operation deletes a user’s registered time-based one-time password (TOTP) multi-factor authentication (MFA) factor, also known as a software token. It takes two parameters and returns nothing: if the action is successful, the service sends back an HTTP 200 response with an empty HTTP body.
aws cognito-idp admin-delete-software-token \
--user-pool-id us-west-2_EXAMPLE \
--username testuser
The Username parameter has a minimum length of 1 and a maximum length of 128, and
the UserPoolId parameter has a maximum length of 55. It returns a
ResourceNotFoundException when the user has no software token registration to
delete — which matters more than it looks, because that is the response you get for a
user who never enrolled, not a signal that the reset failed.
One narrower point that saves a support call: if your user still has access to their
TOTP-generating device, you don’t need to delete their software token to replace it.
Amazon Cognito disassociates the existing software token when your user verifies a new token
in a VerifySoftwareToken request. This operation is for the case where the user
cannot sign in at all.
Architecture
What makes this more than a delete call is that the outcome is not one path. The operation removes the user’s software token registration and any preference for TOTP MFA, and it doesn’t deactivate the other MFA factors that the user has registered. What happens at the next sign-in therefore depends on what is left.
AWS documents both branches plainly: when your user pool requires MFA and the user has no
other factor available, Amazon Cognito returns an MFA_SETUP challenge at the next
sign-in; when the user has another factor available, such as SMS or email message MFA,
sign-in falls back to that factor.
Those two sentences describe very different security events. The first is a recovery: the account is temporarily without a second factor and the next sign-in forces one to be registered. The second is a downgrade: the account keeps a second factor, but not the one you thought it had. The API returns an empty 200 in both cases.
The re-enrolment your WAF can block
Assume the good branch: MFA is required, TOTP was the only factor, and the user is now facing
an MFA_SETUP challenge. They still have to actually enrol, and there is a
documented way for that to fail permanently.
When you have an AWS WAF web ACL associated with a user pool, and a rule in your web ACL
presents a CAPTCHA, this can cause an unrecoverable error in managed login TOTP registration.
The CAPTCHA fires against the AssociateSoftwareToken and
VerifySoftwareToken calls that managed login makes in the background, and the
user sees only that registration will not complete.
The fix is a header exclusion rather than a rule removal: to create a rule that has a CAPTCHA
action and doesn’t affect TOTP in managed login pages, exclude the
x-amzn-cognito-operation-name header values of
AssociateSoftwareToken and VerifySoftwareToken from the CAPTCHA
action in your rule.
The chain is what to notice. The reset now succeeds where it used to be impossible, so this recovery path will get used far more often than it did — and it terminates in exactly the flow a CAPTCHA rule breaks. A protection added for one reason silently disables a recovery added for another. Test the whole path, not the API call.
Business value
The previous state of the world is the value case. Recreating an account to restore a lost
authenticator is not a workaround so much as a data-loss event dressed as one: the user
identifier changes, anything keyed to the old sub is orphaned, group memberships
and custom attributes have to be rebuilt, and any downstream system that treated the Cognito
subject as a durable key now has a stale reference.
Replacing that with a two-parameter API call moves MFA recovery from an engineering escalation to a support-desk action. For consumer-facing pools, lost-phone tickets are a steady and unavoidable volume; for workforce pools, the same event previously meant a person could not work until somebody rebuilt their account.
Security considerations
Amazon Cognito evaluates IAM policies for this operation: for this operation, you must use IAM credentials to authorize requests, and you must grant yourself the corresponding IAM permission in a policy. That sentence is the whole security design, and it puts the entire weight on how you scope one action.
The permission is a takeover primitive
A principal that can delete any user’s software token can strip the second factor from
any account in the pool and wait. If MFA is required and nothing else is registered, the next
sign-in is an MFA_SETUP challenge — which enrols whichever device answers
it first. Combine that with a password obtained by any other means and the second factor has
stopped being a second factor.
The quieter risk is the fallback
The downgrade branch is worse because it is invisible. Delete the TOTP token on an account that also has SMS registered, and sign-in falls back to that factor with no challenge, no re-enrolment, and no user-visible event. The account still reports MFA. It is now protected by a factor vulnerable to SIM swapping instead of one that is not.
There is a second-order effect worth tracing, because AWS documents the coupling: a user’s preferred MFA method influences the methods they can use to recover their password, and users whose preferred MFA is by SMS message can’t receive a password-reset code by SMS. Removing the TOTP preference does not only change which factor is used at sign-in — it can change which channel that user’s password recovery is allowed to use.
Two constraints that limit the blast radius, and one that does not
In your favour: after five unsuccessful attempts to present an MFA code, Amazon Cognito begins the exponential-timeout lockout process, so this is not a brute-force surface. And when you set MFA to required in a user pool, users can’t enable or disable any MFA methods, and you can only set a preferred method — so an attacker cannot use the ordinary self-service path to turn MFA off outright.
Not in your favour: if your users have set up TOTP, they can use it for MFA, even if you deactivate TOTP for the user pool later. Turning TOTP off at the pool level is therefore not a containment action for tokens already registered.
Cost considerations
There is no separate charge announced for the operation, and Cognito does not price user pool API calls individually. It prices people. A user is counted as a MAU if, within a calendar month, customers’ application generates an identity operation for that user, like administrative creation or update, sign-up, sign-in, sign-out, token refresh, password change, a user account attribute update, or an attribute query on a user.
Read that list against a bulk remediation. An administrative update counts, and it counts whether or not the user ever signs in that month. A scripted sweep that resets tokens across a dormant population is an identity operation per user, so it can make a set of otherwise inactive accounts billable for that month. The Essentials and Lite tiers include 10,000 MAUs per month per account for direct sign-ins or social identity providers, which absorbs incident-scale use comfortably and does not absorb a pool-wide sweep.
This is a scale caveat, not a reason to hesitate. Resetting one locked-out user costs nothing you were not already paying — that user was going to be an MAU the moment they signed in. It only becomes a line item when the reset is applied to accounts that would otherwise have stayed quiet.
Operational considerations
Call it in the right Region. The operation can return
OperationNotEnabledException, which is thrown when an operation is not available
in the current region or for the current user pool configuration, and this can occur when
attempting to perform operations that are not supported in secondary replica regions. If you
run a multi-Region user pool, a support tool pointed at the nearest Region will fail on
exactly the users it was built to help.
Know what you are debugging when re-enrolment fails. Two documented causes
look identical to the user. Amazon Cognito only accepts TOTPs from authenticator apps that
generate codes with the HMAC-SHA1 hash function, and codes generated with SHA-256 hashing
return a Code mismatch error. Separately, Amazon Cognito accepts TOTP tokens that
are within 30 seconds before or after the attempt, to account for minor clock skew — so
a device with a drifted clock produces the same symptom as a wrong hash function.
There is no hardware option to fall back on. Amazon Cognito supports software token MFA through an authenticator app that generates TOTP codes, and Amazon Cognito doesn’t support hardware-based MFA. If your threat model wanted a security key as the recovery factor for privileged users, this is not the pool feature that provides it.
Tradeoffs
| Decision | In favour | Against |
|---|---|---|
| Grant the permission to first-line support | Resolves lost-device tickets at first contact, which is where the volume is | Makes first-line support a tier-0 identity role for the whole pool |
| Restrict it to a break-glass role | Small, auditable set of principals; each use is an event | Every lost phone becomes an escalation, which is most of the old pain |
| Let users keep SMS as a secondary factor | Reset is non-disruptive — sign-in simply falls back | Deleting TOTP silently downgrades the account, with no re-enrolment prompt |
| Require TOTP as the only factor | Reset always forces a fresh enrolment, so the outcome is unambiguous | Puts every recovery through MFA_SETUP, the flow a WAF CAPTCHA can break |
Implementation guidance
Scope the permission to the pool and pair it with an identity check your IAM policy cannot make. The action authorizes on the user pool, not on the individual user, so IAM alone cannot express “support may reset Bob but not the administrator”. Put that boundary in the tool that calls the API, and put the tool behind a role that only the tool assumes.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ResetTotpForOneWorkforcePool",
"Effect": "Allow",
"Action": "cognito-idp:AdminDeleteSoftwareToken",
"Resource": "arn:aws:cognito-idp:us-west-2:111122223333:userpool/us-west-2_EXAMPLE"
}
]
}
Then make the two branches distinguishable before you call. The API will not tell you which
one you triggered, so read the user’s registered factors first with
AdminGetUser and decide deliberately: if another factor is registered, deleting
the token is a downgrade and should be paired with
AdminSetUserMFAPreference rather than left to fall back.
Finally, exercise the whole recovery in a non-production pool that carries the same WAF web ACL as production. The CAPTCHA interaction is invisible until somebody actually tries to enrol, and a staging pool with no web ACL will pass a test that production fails.
Best practices
- Treat
cognito-idp:AdminDeleteSoftwareTokenas a privileged action in the same tier as password reset, not as a helpdesk convenience. - Alarm on it. A CloudTrail event per call is cheap, and the normal rate is low enough that a burst is meaningful on its own.
- Never grant it with a wildcard resource. Scope it to a specific user pool ARN, and to one pool per role where you run more than one.
- Decide the fallback policy explicitly. If SMS is registered anywhere in the pool, know that deleting TOTP is a downgrade rather than a reset.
- Check the WAF web ACL before you need the recovery path, using the documented header exclusion rather than dropping the CAPTCHA rule.
- Point support tooling at the primary Region, since secondary replica Regions can reject the operation outright.
- Prefer letting the user re-verify a new token where they still hold the old device, because Cognito disassociates the previous one automatically.
Who should adopt this
Adopt now: anyone running a Cognito user pool with TOTP MFA required and a real support function. The previous workaround was account recreation, so there is no argument for staying on it — the only work is deciding who holds the permission before anyone needs it at 2 a.m.
Adopt with a design pass first: pools that offer both TOTP and SMS. The fallback behaviour means this operation does something different from what its name suggests for a large fraction of your users, and that difference is silent.
Not urgent: pools where MFA is off or optional and unused, and pools that are entirely federated — in the case of federated users, Amazon Cognito delegates all authentication processes to the IdP, so the second factor is not Cognito’s to reset.
Key takeaways
AdminDeleteSoftwareTokendeletes a user’s registered TOTP factor and their TOTP preference, and is available in all Regions where Cognito is.- It replaces a workaround that was, in AWS’s own words, recreating the account.
- The outcome branches:
MFA_SETUPwhen no other factor remains, silent fallback when one does. The response is an empty 200 either way. - The permission removes a second factor, so it belongs in the same tier as password reset, scoped to one pool ARN and alarmed on.
- An AWS WAF CAPTCHA rule can make the re-enrolment that follows a reset unrecoverable; the fix is excluding two
x-amzn-cognito-operation-nameheader values. - Cognito bills monthly active users, and an administrative update counts as an identity operation — so bulk resets can make dormant accounts billable.
Official AWS references
- Amazon Cognito adds admin API operation to reset user TOTP configurations
- AdminDeleteSoftwareToken, Amazon Cognito user pools API reference
- TOTP software token MFA, Amazon Cognito Developer Guide
- Adding MFA to a user pool, Amazon Cognito Developer Guide
- AdminSetUserMFAPreference, Amazon Cognito user pools API reference
- VerifySoftwareToken, Amazon Cognito user pools API reference
- Amazon Cognito pricing
Comments