Question:
I have a Cognito user pool which has MFA set to Required
with TOTP
only (i.e. no SMS).
My question is how do I reset the MFA for a user? For example what if the user loses his phone so he doesn’t have anyway to login.
I have tried reset password but that only resets the password, it doesn’t remove the MFA.
At the bottom of this AWS documentation, it says
NOTE A delete TOTP software token operation is not currently available in the API. This functionality is planned for a future release. Use SetUserMFAPreference to disable TOTP MFA for an individual user.
So I tried SetUserMFAPreference
and AdminSetUserMFAPreference
, they just return 200 OK but doesn’t actually disable the MFA. I guess it’s due to the user pool has MFA set to Required
.
Answer:
At this point, since AWS does not support resetting the MFA (if your user pool requires MFA – disabling MFA using AdminSetUserMFAPreference
will return 200 OK but it will do nothing), the only way to do this is to create a new user pool with optional MFA (you have to create a new one since changing from required
to optional
is prohibited once the user pool is created). Then with the new user pool, you have to enforce the MFA (if that’s something that you want) manually within your code.
For that, once the user logs in successfully and the return object has the tokens in it, you have to call AssociateSoftwareToken
instead of returning the tokens and start the MFA registration process. The tokens (like IdToken
) will only be returned to the user when they managed to complete the call to AdminRespondToAuthChallenge
successfully.
Bottom line, with the optional MFA, the AdminSetUserMFAPreference
will work. And this is the only way to reset MFA in a user pool on AWS (at this point).
[UPDATE]
Not that my original answer was invalid, but just to provide more information, here’s some extra explanation on how to use AdminSetUserMFAPreference
:
First of all, you need a user pool with optional MFA. The optional is the keyword here. This solution does not work on a user pool with required MFA.
Having the user pool setup, I assume there’s a user properly signed up to your user pool. This means that they can authenticate themselves against your user pool without any issues. Of course, the whole point is that they need to provide MFA as part of their authentication process. But since we already established, MFA is optional in your user pool so if you insist on enforcing MFA on your users, that means you have to do so within your code manually.
Alright, so far everyone’s happy. But just as the reality, come the sad days. Your user loses their MFA codes and cannot generate any new ones. So you would like to provide them with the possibility of resetting their MFA by re-registring a new device. Of course, first, you need to make sure that it’s the actual user requesting such a thing. I mean you don’t want anyone (but the true user) to be able to make such a request. So you need to authenticate them first. But the fact that they cannot authenticate (due to missing MFA) is the whole reason why they ended up here. So what can you do now? Well, even though this part is out of the scope of this post, but as a small hint, you can send them an email with a code and ask them to return it back to you as a one-time authentication mechanism.
OK, back to the question at hand. Now, you are sure that it’s the actual account owner is requesting the MFA reset. And this is how you do it:
1 2 3 4 5 6 7 8 9 10 11 |
async function resetMfa(username) { const cognito = new AWS.CognitoIdentityServiceProvider(); await cognito.adminSetUserMFAPreference({ UserPoolId: "user pool ID", Username: username, SoftwareTokenMfaSettings: { Enabled: false, } }).promise(); } |
Once their MFA is disabled, in order to re-register a new device, the account owner has to attempt a new login. This attempt will be just like the first time they are logging into their account and they will be asked to register a new MFA device.
I hope that clarifies things a bit more. If you want to know how to use MFA (manually), I have this other post which addresses it.