-2

We are trying to migrate the TOTP factor from Authy to Verify API in Twilio. We reference the following article for the same

https://www.twilio.com/docs/authy/export-totp-secret-seed-for-migrating-to-verify-totp#export-totp-secret-seed-of-a-user

From above URL, we were able to pinpoint how to extract the secret created in the Authy. But, we are unsure as to how a secret extracted from the Authy can be used to create a factor in the Verify API. Can you please tell us in detail how to achieve the same?

Swimburger
  • 6,681
  • 6
  • 36
  • 63

1 Answers1

0

Since I don't know what programming language you're using, I'll use cURL commands and you can translate those HTTP requests into your language of choice.

First, you'll need to ask Twilio support to enable the migration tools for your Authy app. They will ask you for Authy app ID which you can find in the URL of the Twilio Console when you navigate to your Authy app.

Then you can use the export TOTP secret API that you linked earlier:

curl -i "https://api.authy.com/protected/json/users/$AUTHY_USER_ID/secret/export" \
    -H "X-Authy-API-Key: $AUTHY_API_KEY"
  • $AUTHY_USER_ID is the individual Authy User ID for which you are trying to move their TOTP factor to the Verify service.
  • $AUTHY_API_KEY is the API key for your Authy App.

The output will look like this:

{"secret":"[REDACTED]","otp":"[REDACTED]","success":true}
  • The secret is what you need to create a Factor in the Verify service
  • The otp is the one time passcode, the same as what the user would see in their TOTP consumer app (Authy/Google Authenticator/etc).

Now you can use the Verify API to create a new Factor:

curl -X POST "https://verify.twilio.com/v2/Services/$VERIFY_SERVICE_SID/Entities/$IDENTITY/Factors" \
--data-urlencode "Binding.Secret=$EXPORTED_AUTHY_SECRET" \
--data-urlencode "Config.Alg=sha1" \
--data-urlencode "Config.TimeStep=30" \
--data-urlencode "Config.CodeLength=6" \
--data-urlencode "Config.Skew=1" \
--data-urlencode "FriendlyName=John's Phone" \
--data-urlencode "FactorType=totp" \
-u $TWILIO_ACCOUNT_SID:$TWILIO_AUTH_TOKEN
  • $VERIFY_SERVICE_SID is the SID of your Verify Service.
  • $IDENTITY is a unique ID for your user, length between 8 and 64 characters, generated by your external system, such as your user's UUID, GUID, or SID. If the identity does not exist yet, it'll be created automatically as part of this API call.
  • $EXPORTED_AUTHY_SECRET is the secret that was returned by the Authy Export API earlier.
  • $TWILIO_ACCOUNT_SID is your Twilio Account SID.
  • $TWILIO_AUTH_TOKEN is your Twilio Auth Token.

This API call is documented here: https://www.twilio.com/docs/verify/quickstarts/totp#create-a-new-totp-factor

You can use the otp returned by the Authy Export API to verify the new Factor you created:

curl -X POST "https://verify.twilio.com/v2/Services/$VERIFY_SERVICE_SID/Entities/$IDENTITY/Factors/$FACTOR_SID" \
--data-urlencode "AuthPayload=$OTP_CODE" \
-u $TWILIO_ACCOUNT_SID:$TWILIO_AUTH_TOKEN
  • $FACTOR_SID is the SID of your newly created Factor.
  • $OTP_CODE is the otp code returned by the Authy Export API.

This API call is documented here: https://www.twilio.com/docs/verify/quickstarts/totp#verify-that-the-user-has-successfully-registered

That's it! If you want to verify your user's OTP code, you can create a challenge like this:

curl -X POST "https://verify.twilio.com/v2/Services/$VERIFY_SERVICE_SID/Entities/$IDENTITY/Challenges" \
--data-urlencode "AuthPayload=$OTP_CODE" \
--data-urlencode "FactorSid=$FACTOR_SID" \
-u $TWILIO_ACCOUNT_SID:$TWILIO_AUTH_TOKEN
  • $OTP_CODE is the otp code given to your application by your user.

This API call is documented here: https://www.twilio.com/docs/verify/quickstarts/totp#validate-a-token


When exporting from Authy API and creating new factors in Verify, you need to do this quickly so you can verify the new factor using the OTP code given from the Authy export. Here's how I did it for a single Authy user using a bash script:

#!/bin/bash

EXPORTED_RESPONSE=$(
curl -s "https://api.authy.com/protected/json/users/$AUTHY_USER_ID/secret/export" \
    -H "X-Authy-API-Key: $AUTHY_API_KEY" 
)
echo "$EXPORTED_RESPONSE"

EXPORTED_AUTHY_SECRET=$(echo -n "$EXPORTED_RESPONSE" | jq -r .secret)
OTP_CODE=$(echo -n "$EXPORTED_RESPONSE" | jq -r .otp)
IDENTITY=$(uuidgen)

NEW_FACTOR_RESPONSE=$(curl -s -X POST "https://verify.twilio.com/v2/Services/$VERIFY_SERVICE_SID/Entities/$IDENTITY/Factors" \
--data-urlencode "Binding.Secret=$EXPORTED_AUTHY_SECRET" \
--data-urlencode "Config.Alg=sha1" \
--data-urlencode "Config.TimeStep=30" \
--data-urlencode "Config.CodeLength=6" \
--data-urlencode "Config.Skew=1" \
--data-urlencode "FriendlyName=John's Phone" \
--data-urlencode "FactorType=totp" \
-u $TWILIO_ACCOUNT_SID:$TWILIO_AUTH_TOKEN)

echo "$NEW_FACTOR_RESPONSE"

FACTOR_SID=$(echo -n "$NEW_FACTOR_RESPONSE" | jq -r .sid)

VERIFY_FACTOR_RESPONSE=$(curl -s -X POST "https://verify.twilio.com/v2/Services/$VERIFY_SERVICE_SID/Entities/$IDENTITY/Factors/$FACTOR_SID" \
--data-urlencode "AuthPayload=$OTP_CODE" \
-u $TWILIO_ACCOUNT_SID:$TWILIO_AUTH_TOKEN)

echo "$VERIFY_FACTOR_RESPONSE"

The various environment variables that were described earlier should be set prior to executing this.

Swimburger
  • 6,681
  • 6
  • 36
  • 63
  • After creating the factor, when I use the otp returned by the Authy Export API to verify the new factor, it is not able to verify the factor with that otp. – Shivam Gupta Nov 23 '22 at 08:49
  • Is there a delay between the export and verification? When I did it, it verified but I did the verification immediately. – Swimburger Nov 24 '22 at 04:49
  • No, there was no such delay but when I proceeded with step 2 it shows after its completion that user is unverified. Also, do we need to proceed with the challenge creation as I do not think it has any use in migrating the user? – Shivam Gupta Nov 24 '22 at 06:24
  • You don't need to create a new challenge as part of this process, but I included it to verify that the migration was successful. I did this last verification manually for the sake of testing. – Swimburger Nov 24 '22 at 22:27
  • We are not currently able to migrate the user because of the factor remaining unverified. Is there any other way around this? – Shivam Gupta Nov 25 '22 at 03:34
  • What error are you getting when trying to verify the factor using the otp code from the export? – Swimburger Nov 25 '22 at 21:04
  • We are actually not getting any error but after we use that factor for authentication, for the first time it says invalid secure access code but starts to work after that – Shivam Gupta Nov 28 '22 at 06:35
  • @ShivamGupta I just verified this works as expected for me. I added the bash script I used to export a single user and verify their factor. – Swimburger Dec 05 '22 at 20:30