2024-01-27

Authy desktop app end of life (EOL)

Update 2024-02-13:  Twilio today finally emailed Authy end-users users to inform them of the Authy desktop app desupport -- and they changed the effective date from August 2024 to March 19, 2024.  The post below (originally published on January 27) has been updated to reflect this.

Twilio has announced that it will be killing its Authy desktop app on March 19, 2024, leaving only its Authy mobile apps. This is not so good, for various reasons outlined below. Also below is what you can and possibly should do about it.

TL;DR:

  • On March 19 you'll lose the ability to (a) view your Authy TOTP tokens on a desktop computer and (b) export your TOTP tokens from Authy (so that you can import them to some other TOTP authenticator).
  • If you have few tokens in Authy (and you don't mind losing the ability to access your TOTP tokens from your computer), you can safely ignore this post (that's Option 1). 
  • If you have many tokens in Authy, you should consider exporting them before March 19, when you'll lose that ability.
  • If you do export them, you can just store the export file for future use (Option 2), or you can import it into your password manager (Options 3 and 4).
  • If you do import it into your password manager, you will continue to be able to access your TOTP tokens on your desktop computer -- an ability which you will lose with Authy on March 19.

Note that this page is written on the assumption that you're using Bitwarden as your password manager. What's described here would work for another TOTP authenticator or another password manager with TOTP authenticator functionality, but only if it supports bulk import of TOTP tokens in JSON format.

The Problem

Read these for background:

Authy is a TOTP authenticator service and set of apps. TOTP tokens are used for two-factor authentication (2FA) and generate a (typically) 6-digit code that rotates every (typically) 30 seconds. You can read these if your understanding of TOTP 2FA and/or TOTP authenticators is not very strong:

The issues are:
  1. An important part of Authy's value is the desktop app, so desupporting it is a big change for the worse. Will Twilio make other future changes to degrade Authy?
  2. After the change you won't be able to access your TOTP tokens on your desktop computer, and you'll need to always have a mobile device with you so you can use the Authy mobile app.
  3. Users will now have fewer devices with Authy installed, so will have less resilience in case something goes wrong.
  4. Authy doesn't support exporting TOTP tokens, unlike almost all other TOTP authenticators. This tends to lock in users.
  5. There's a third-party procedure to export Authy's TOTP tokens, but after the desktop app is desupported on March 19, that export procedure will no longer work, so you'll be locked into Authy. After March 19, if Authy does something (else) that displeases you and you decide to move off their app, it will be necessary, for every TOTP token in your Authy vault, to log into the corresponding account, disable 2FA, and re-enable it using a different TOTP authenticator. This is painful if you have a lot of TOTP tokens, as you should (unless you also use a hardware security key, like a YubiKey).

Solution Overview

After the desktop app is desupported, switching out of Authy could be painful, depending on how many TOTP tokens you have. Unless, that is, you do what I'm suggesting below in Option 3 or 4. With this solution, you won't be dependent on Authy because you'll have copied all your TOTP tokens into Bitwarden.

Options 3 and 4 -- the preferred options -- are possible because Bitwarden has (in addition to its password manager feature) a built-in Bitwarden Authenticator feature that is functionally equivalent to Authy. Like Authy -- today but not from March 19 onwards -- Bitwarden Authenticator is supported on desktop and mobile, and, like Authy, it supports multiple devices, backs up to its own cloud, syncs between the cloud and devices in real time, and is end-to-end encrypted (E2EE).

A few notes:

  • Bitwarden Authenticator is not supported on the Free tier, so you'll have to upgrade to at least Premium tier. But you'd probably want to pay for Bitwarden anyway in order to get the important Encrypted File Attachments and Emergency Access features. See https://bitwarden.com/pricing/.
  • You should of course have 2FA on your Bitwarden account, and this page assumes that it's TOTP 2FA and stored in Authy. Whichever of the options below you choose, you'll need to continue to use Authy to access your Bitwarden TOTP token. (To understand why this is necessary, see the 2FA Catch-22 described below in Step A.) Depending on the option chosen, you will use Bitwarden and/or Authy for your other TOTP tokens.

Your Options

Here is a high-level view of your strategic options.  Some notes on the table first:

  • The "Now*" in the "Steps Now*" column heading means any time between now and the August Authy desktop app desupport at the latest. But the longer you wait to do this, the more you're taking the chance that something goes wrong, e.g., that Twilio blocks the export before then, or that it desupports the desktop app earlier than August without warning. If you're going to export, I suggest you do it as soon as you can. 
  • You might think there is another option not shown in the table: export your Authy vault, import it to Bitwarden Authenticator, and delete your Authy account. Don't do this! You need to keep Authy because of the 2FA Catch-22 described in Step A.

 

#

Option

      Steps Now*        

      Steps Ongoing      

Notes

Pro

Con

1

Stay:

Stay with Authy (no changes)

A

 

OK option only if you have but a few tokens in Authy and you have 2+ mobile devices for resilience

No effort at all

From March 19 you will no longer be able to export your tokens from Authy

You can access your TOTP tokens only on your mobile device(s), which is fewer devices than before, so less resilient

2

Export and stay:

Export Authy vault but stay with Authy

A, B

 

OK option only if you have 2+ mobile devices for resilience

In the future you have the option of using the exported JSON file to help you move to another TOTP authenticator

The small effort required now for export/import

You can access your TOTP tokens only on your mobile device(s), which is fewer devices than before, so less resilient

If/when you move to another TOTP authenticator, you'll need to manually redo the 2FA for all tokens added to Authy since your export

3

BW with frozen-in-time Authy:

Export Authy vault, import to BW Authenticator, and only add/delete tokens in BW going forward

A, B, C

D

Good option

You'll be able to access new tokens only in BW Authenticator, and Authy will gradually contain more and more outdated tokens, so will eventually be unusable

At any point you can decide to delete all tokens in Authy except for the BW token (per the 2FA Catch-22)

The convenience of Authy on mobile for some of your tokens, the convenience of access to your TOTP tokens on the desktop and mobile via BW, and the limited resilience of having a partial backup of your BW Authenticator in Authy

The small effort required now for export/import

 

4

BW and Authy in parallel:
Export Authy vault, import to BW Authenticator, and add/delete tokens in both BW and Authy going forward

A, B, C

E

Good option

You can access all your tokens in either BW Authenticator or Authy

It's easy to transition to Option 3 at any point if you want

The convenience of Authy on mobile, the convenience of access to your TOTP tokens on the desktop (and mobile) via BW, and the resilience of having a complete backup of your Authy vault in BW

The small effort required now for export/import

The small additional effort for each new TOTP token in the future to add it to two authenticators instead of one



The Solution

Options 3 and 4 give you the most convenience, future flexibility, and independence from Authy. If you choose Option 3, you'll likely use Authy only when you're in the 2FA Catch-22 situation described in Step A. If instead you choose Option 4, you have the flexibility of using either Bitwarden or Authy for TOTP tokens -- although you're likely to find that Bitwarden is often more convenient. For either option, don't forget to use Authy occasionally to ensure it continues to work: you need Authy to be in full working condition when you encounter the 2FA Catch-22 situation.

Once you successfully implement -- and test -- either of those options, Bitwarden will be your primary TOTP authenticator. I suggest that soon thereafter you delete the Authy desktop app. This will simulate what will happen when Authy desupports their desktop app, to help ensure that you won't have any surprises on March 19. If needed you can reinstall it to allow you to resolve an issue, until March 19.

If you're undecided between Options 3 and 4, you might as well start with Option 4. Then, once you're sure Bitwarden is working well for you for TOTP, you could easily move to Option 3 if you want by simply no longer updating Authy. 

If you use a different password manager that doesn't import JSON files but does provide TOTP authenticator functionality, you could probably import the JSON file to a temporary Bitwarden account then export a CSV file to import to your password manager.  Note that I haven't tested this so I can't vouch for it.  I imagine there are many other ways of doing this too.

The Bare Minimum

Even if you decide to stay with Authy alone, you should still choose Option 2: export from Authy now and then do it again shortly before they desupport the desktop app. That will give you backup of your tokens as of March 19 that you can import to a new TOTP authenticator if you later decide to move off Authy. (The suggestion to do the export now is to cover you in case something prevents you from exporting just before the desktop app desupport on March 19.)

If you have very few tokens in Authy, you could reasonably choose Option 1 instead.

Detailed Steps

Here are the steps referenced in the table above:

  • Step A: Ensure you can get into your Bitwarden vault if something goes wrong with 2FA
  • Step B: Export the Authy vault as a JSON file
  • Step C: Import the Authy JSON file into Bitwarden
  • Step D: Ongoing: update only Bitwarden Authenticator with added/deleted account tokens
  • Step E: Ongoing: update both Bitwarden Authenticator and Authy with added/deleted account tokens

Step A: Ensure you can get into your Bitwarden vault if something goes wrong with 2FA

For your security you should have TOTP 2FA set up on your BW account. Not doing so is very risky.

·         If you don't have it already, set it up now, using Authy: https://bitwarden.com/learning/enable-two-step-login/

·         Make sure you save the resulting BW Two-Step Login Recovery Code both in your BW vault and somewhere else, outside of BW, because of the 2FA Catch-22 described below.

·         Later, as part of Steps B and C, you'll copy the BW token in Authy over to your BW vault.  You want it there for two reasons:

·         it makes it easy to log into a different BW client from your current one, e.g., logging into the web vault from the browser extension, and

·         when you export your BW vault for backup purposes, you'll automatically get the BW token too.

 
If anything goes wrong with the 2FA on your BW account at any time in the future, you need a way to bypass the 2FA so you can log into your account.

To that end, read and understand this very important BW help article: https://bitwarden.com/help/lost-two-step-device/

The bottom line of that article is that you must do one or more of these things ahead of time (i.e., now) to ensure you can get into your BW account in the case of a 2FA problem:

·         Save your BW Two-Step Login Recovery Code somewhere outside of that BW vault in a way that allows you to always get at it.  Suggestions:

·         You could save it somewhere on your computer outside of BW -- but only if your computer drive has full-disk encryption, e.g., BitLocker or File Vault.  And this won't help you if you're away from your computer, e.g., traveling.

·         You could print it, but you might not want to carry it with you given the risk of loss or theft.

·         You could share it with a trusted contact and, when you need it, ask them to send it to you via an E2EE messaging services like Signal.  But they might not be available when you need them.

·         You could save it in an E2EE cloud service, such as second password manager account.  Make sure you don't rely on your main BW vault in question in order to log into that second account! That would be another Catch-22.

·         Set up BW Emergency Access to a trusted contact: https://bitwarden.com/help/emergency-access/.  This is the simplest and most reliable method -- and you should do this anyway --, but you won't get access until the delay you specified (a minimum of one day) has elapsed.


As mentioned above you should also store your Two-Step Login Recovery Code in BW, as all your secrets should be stored there. But this won't help you with 2FA recovery.

 
There is a separate but related 2FA issue -- a 2FA Catch-22 -- that would arise if you were to try to use only BW for 2FA, i.e., if you got rid of your Authy account:

·         The Catch-22 happens because a BW client will occasionally (once a month or so) ask you for a second factor (a TOTP token in this case) when you try to log in.  But if you've used BW Authenticator for the 2FA for the BW login, you can't access that TOTP token until you've logged in -- and you can't log in without that TOTP token.

·         The Catch-22 is more likely to occur if you have only a single mobile device with you, e.g., when you are out of the house or, worse, traveling with only your phone.  That's because on your desktop computer you might have the Two-Step Login Recovery Code saved outside of BW or accessible on a piece of paper, and if you have two mobile devices with you, one of them will likely (but not assuredly) still have an active BW 2FA session when the other device's BW is asking for a TOTP token.

·         To address this Catch-22 you'll need to implement both these two points:

1)    run a second TOTP authenticator that offers at least a mobile app -- like Authy -- in parallel with BW, so that it can be used to generate the TOTP token for BW when needed

2)    save your Two-Step Login Recovery Code somewhere outside of BW so that you can always get at it, as described above

·         The steps below (B, C, D, and E) describe setting yourself up to use Authy as your second TOTP authenticator, at a minimum for your BW token and optionally for your other tokens too.


Of course it would be quite OK to copy your BW TOTP token to a TOTP authenticator other than Authy; that too would break the Catch-22.

The upshot of the 2FA Catch-22 issue is that you must have a way other than BW to access the TOTP token for your BW account. Beyond that, it's entirely optional to have any of your other TOTP tokens outside of BW, e.g.., in Authy.

 
Everything, not only 2FA, can go wrong, so it's a good idea to do a regular backup of your Bitwarden vault, using its JSON export capability. If you export it in the unencrypted format, be very careful where you store it or send it; for instance, don't store it on your computer's drive unless it has full-disk encryption, e.g., BitLocker or File Vault.

Step B: Export the Authy vault as a JSON file

In theory you can do this export any time before the March 19 Authy desktop desupport, but if do it sooner rather than later, you'll be insulated from anything Twilio might do the future.

This is the source for this export process: Export TOTP tokens from Authy (github.com)

Below is an extract from the source (and from one of the comments there) for Windows, to clarify the instructions. For Mac and Linux, see the source.

Before starting the export, verify that none of your Authy TOTP tokens have "#" in their name. If any do, open the desktop Authy app and edit the affected tokens to remove that character. 


1) On your computer, install Authy desktop app version 2.2.3 (versions after 2.2.3 won't work): https://pkg.authy.com/authy/stable/2.2.3/win32/x64/Authy%20Desktop%20Setup%202.2.3.exe

2) After you install Authy 2.2.3, Authy will launch -- exit it immediately.

3) In your "C:/Users/<yourusername>/AppData/Local/Authy" folder":

a) delete file "Update.exe"

b) delete the "app-2.4.2" folder (or newer version) if it exists

c) in the "app-2.2.3" folder, delete file "Update.exe".

4) Open the Authy app and log in, then click on a token and enter the Backups Password if necessary. You should now be able to see a 6-digit code for any token.

5) Close the Authy app.

6) Right-click the Authy desktop shortcut (make one if you don't already have one) and add this to the end of the Target field, without the quotes: "--remote-debugging-port=5858". Click OK

7) Open the Authy app by double-clicking that desktop shortcut.

8) Open the following URL in your Chrome web browser: http://localhost:5858

9) Click the "Twilio Authy" link in that webpage.

10) In the Chrome Developer Tools top navigation bar, go in the "Sources" tab (if you don't see it, click >> to expand the full list), then select the "Snippets" sub-tab (from the tabs on the second line; again, click >> to expand the full list), and finally choose "+ New snippet".

11) To reduce the risk that the code you paste and execute might send information to a remote server, disconnect your computer from the network (Internet).

12) In the snippet editor window that appears on the right, paste the code that appears in the grey box under "Export to Bitwarden JSON - Advanced". Before pasting, you should compare that code with the code snapshot in the Appendix at the bottom of this page (which worked for me), to ensure no malicious changes have been made to the source.

13) Right-click the snippet name on the navigator pane on the left, e.g., "Script snippet #1", and choose Run. You'll need to choose where to save the output JSON file.

14) You now have the Authy vault export in the form of a JSON file, suitable for importing to BW.

15) Reconnect your computer to the network (Internet).

16) Reinstall the latest version of the Authy app.

Step C: Import the Authy JSON file into Bitwarden

If you decide that you want to use something other than BW as your main TOTP authenticator, you should be able to instead import this JSON file into any password manager with TOTP authenticator functionality or into a TOTP authenticator, as long as it claims to accept a BW-compatible JSON file.


1) Go to any BW non-mobile client: the desktop app, the browser extension, or the web UI.

2) Go to Settings and choose Import Items:

a) Ensure Import Destination is "My vault"

b) Leave Folder set to "-- Select a folder --"

c) Set File Format to "Bitwarden (json)"

d) Click on Choose File and select the JSON file you created in Step B

e) Click on Import Data in top right of the dialog.

3) Your BW vault now contains a new folder "Imported from Authy", containing all the imported tokens.

4) Rename that folder to something like "___2FA TOTP" if you chose Option 3 or "___2FA TOTP (+AUTHY)" if you chose Option 4. (The latter name is to remind you to keep Authy in sync.)

5) Your import is done, and BW Authenticator is now working for you just like Authy, with the same set of TOTP tokens.

6) To test this, open any item in the new tokens folder. You'll see a six-digit code, a 30-second countdown clock, and a copy button.

Step D: Ongoing: update only Bitwarden Authenticator with added/deleted account tokens

This step is for Option 3. With Option 3 you are no longer updating Authy after the export from it, so over time Authy will (a) be missing more and more tokens, as you add 2FA to new accounts, and (b) hold more and more out-of-date/dead tokens (that have been deleted in BW Authenticator) because you disabled 2FA in the corresponding account.

 Usage: Whenever you need to get a TOTP token for an account, you might be able to use either BW or Authy:

1.     If Authy has the token -- as noted just above -- they will both generate the same code for the same token, so use either one.

2.     Otherwise you'll need to use BW.

3.     And starting on March 19, you'll have to use BW if you want to get a token on your desktop.


Adding: Whenever you add TOTP 2FA to an account (say, Twitter), add the token only to BW:

1.     Follow the account's 2FA settings web page until you see the QR code. 

2.     Go to the BW mobile app and open the folder "___2FA TOTP" that you created in Step B.

3.     Click on the "+" button to add a new Login.  Name it appropriately and simply, e.g., "Twitter".  (There's no need to include the account username / email address in the token name unless you have more than one such account.)

·         Note: I recommend that you do NOT add the TOTP token to the existing login for that account (the one that contains the userid and password for the account).  Keeping your real logins and TOTP tokens as separate entries in BW will mean more flexibility for you in the future, e.g., if you decide to move to a new, separate TOTP authenticator.

4.     Scan the QR code on the BW mobile app and follow its workflow.

5.     Go back to the account's 2FA settings web page and continue its workflow.


Deleting: Whenever you delete an account's TOTP token, delete it only in BW. Make sure you don't delete that account's actual login (the entry with userid and password) by mistake!

Step E: Ongoing: update both Bitwarden Authenticator and Authy with added/deleted account tokens

This step is for Option 4. With Option 4 you continue to update Authy alongside BW after the export from Authy, so Authy and BW Authenticator will continue to be in sync.

 Usage: Whenever you need to get a TOTP token for an account, you can use either BW or Authy:

1.     They will both generate the same code for the same token, so use either one.

2.     But starting on March 19, you'll have to use BW if you want to get a token on your desktop.


Adding: Whenever you add TOTP 2FA to an account (say, Twitter), add the token to both Authy and BW:

1.     Follow the account's 2FA settings web page until you see the QR code, then suspend its workflow, i.e., don't touch that page further until directed below. 

·         It’s important not to touch the page until you've scanned the QR code on both BW and Authy, otherwise you won't be able to scan the QR code on the second authenticator, Authy.

·         The order of BW first then Authy is best because: if you add the token to BW but forget to add it to Authy, you can copy the token string from the BW entry and paste it into Authy to create the missing entry; but the reverse doesn't work.

2.     Go to the BW mobile app and open the folder "___2FA TOTP (+AUTHY)" that you created in Step B.

3.     Click on the "+" button to add a new Login.  Name it appropriately and simply, e.g., "Twitter".  (There's no need to include the account username / email address in the token name unless you have more than one such account.)

·         Note: I recommend that you do NOT add the TOTP token to the existing login for that account (the one that contains the userid and password for the account).  Keeping your real logins and TOTP tokens as separate entries in BW will mean more flexibility for you in the future, e.g., if you decide to move to a new, separate TOTP authenticator.

4.     Scan the QR code on the BW mobile app and follow its workflow.

5.     Scan the QR code on Authy mobile app and follow its workflow, using the same token name as you chose for BW.

6.     Go back to the account's 2FA settings web page and continue its workflow.

7.     Verify that the tokens in BW and Authy show the same 6-digit code.


Deleting: Whenever you delete an account's TOTP token, delete it in both Authy and BW:

1.     Delete the token in Authy.

2.     Delete the token in your BW vault.  Make sure you don't delete that account's actual login (the entry with userid and password) by mistake!

Background Notes

  • Security: "Defence in depth" is a key principle in information security, and at first glance it might suggest using separate services for password manager and TOTP authenticator. To provide for account recovery, though, the entry for each account stored in your password manager (here Bitwarden) vault needs to also record recovery information such as the 2FA recovery code -- so an attacker getting access to a password manager vault not only gets the userid and password but also gets the information they need to bypass the 2FA for that account. As a result, using a separate TOTP authenticator does not improve security. Yes, you're putting all your eggs in one basket (Bitwarden) but you're going to watch (secure) that basket very carefully, including using a strong master password and 2FA.

Update 2024-02-09


If I didn't have a TOTP authenticator and wanted to set one up today, I'd still choose Authy, even though it won't run on the desktop starting on March 19 because there is nothing else I like as much. I'd definitely store the Bitwarden TOTP token in both Authy (where it's needed due to the Catch-22) and Bitwarden (where you can't use it due to the Catch-22), and I'd probably store all other tokens not only in Bitwarden (more convenient and resilient) but also in Authy. (As described in the latter post, at some point in the future I might decide to no longer add new tokens to Authy.)

Appendix: The script to paste in Step B

As noted above, this is a direct copy from the source used in Step B, found in the grey box under "Export to Bitwarden JSON - Advanced" in Export TOTP tokens from Authy (github.com). It's replicated here so that you can check if changes have been made to the code in the source.

// Based on https://github.com/LinusU/base32-encode/blob/master/index.js

function hex_to_b32(hex) { let alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; let bytes = []; for (let i = 0; i < hex.length; i += 2) { bytes.push(parseInt(hex.substr(i, 2), 16)); } let bits = 0; let value = 0; let output = ''; for (let i = 0; i < bytes.length; i++) { value = (value << 8) | bytes[i]; bits += 8; while (bits >= 5) { output += alphabet[(value >>> (bits - 5)) & 31]; bits -= 5; } } if (bits > 0) { output += alphabet[(value << (5 - bits)) & 31]; } return output; }

 

// from https://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid#answer-2117523

function uuidv4() { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); }); }

 

// from https://gist.github.com/gboudreau/94bb0c11a6209c82418d01a59d958c93

function saveToFile(data, filename) { if (!data) { console.error('Console.save: No data'); return; } if (typeof data === "object") { data = JSON.stringify(data, undefined, 4) } const blob = new Blob([data], { type: 'text/json' }); const e = document.createEvent('MouseEvents'); const a = document.createElement('a'); a.download = filename; a.href = window.URL.createObjectURL(blob); a.dataset.downloadurl = ['text/json', a.download, a.href].join(':'); e.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); a.dispatchEvent(e); }

 

function deEncrypt({ log = false, save = false }) {

  const folder = {

      id: uuidv4(),

      name: 'Imported from Authy'

  };

 

  const bw = {

      "encrypted": false,

      "folders": [

          folder

      ],

      "items": appManager.getModel().map((i) => {

          let secretSeed = i.secretSeed;

          if (typeof secretSeed == "undefined") {

              secretSeed = i.encryptedSeed;

          }

          const secret = (i.markedForDeletion === false ? i.decryptedSeed : hex_to_b32(secretSeed));

          const period = (i.digits === 7 ? 10 : 30);

 

          const [issuer, rawName] = (i.name.includes(":"))

              ? i.name.split(":")

              : ["", i.name];

          const name = [issuer, rawName].filter(Boolean).join(": ");

          const totp = `otpauth://totp/${name}?secret=${secret}&digits=${i.digits}&period=${period}${issuer ? '&issuer=' + issuer : ''}`;

 

          return ({

              id: uuidv4(),

              organizationId: null,

              folderId: folder.id,

              type: 1,

              reprompt: 0,

              name,

              notes: null,

              favorite: false,

              login: {

                  username: null,

                  password: null,

                  totp

              },

              collectionIds: null

          });

      }),

  };

 

  if (log) console.log(JSON.stringify(bw));

  if (save) saveToFile(bw, 'authy-to-bitwarden-export.json');

}

 

deEncrypt({

  log: true,

  save: true,

});