---
id: totp
title: Multi-factor authentication with TOTP (Google Authenticator)
sidebar_label: TOTP (Google Authenticator)
---

# Time-based one-time passwords (TOTP)

```mdx-code-block
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import BrowserWindow from "@site/src/theme/BrowserWindow"
```

Time-based one-time passwords are codes made up of digits, that are valid for a short amount of time, usually 30 seconds or less.
Users generate these passwords with companion apps such as [Google Authenticator](https://g.co/kgs/YgRFR5) or
[FreeOTP](https://freeotp.github.io/) and enter them when asked to provide their second authentication factor.

When accessing resources protected with the second-factor requirement, the paired application generates a one-time password that
expires after a certain time. Users must input this password before it expires to authenticate and perform the protected actions.

You can enable Time-Based One-Time Password (TOTP) authentication in Ory Identities (Kratos) to allow users to perform 2FA with
TOTP apps such as Google Authenticator, LastPass, or [FreeOTP](https://freeotp.github.io/).

When enabled, users can pair a TOTP app to their account:

:::note

The example screenshot is captured using the Ory Account Experience.

:::

```mdx-code-block
<BrowserWindow url="https://playground.projects.oryapis.com/ui">

  ![TOTP linking in Ory Account Experience](../_static/mfa/1.png)

</BrowserWindow>
```

When attempting to perform actions while having 2FA enabled, users are asked to enter the short code in the Ory Identities UI.
This proves that they have access to their chosen second factor.

```mdx-code-block
<BrowserWindow url="https://playground.projects.oryapis.com/ui">

![2FA with Google Authenticator](../_static/mfa/2.png)

</BrowserWindow>
```

:::info

In this example, the user identifier (email - `alice@example.com`) is used. To learn how to enable this behavior, read
[Distinguishing identities requesting TOTP](#distinguishing-identities-requesting-totp).

:::

## Enabling TOTP authentication

```mdx-code-block
<Tabs groupId="console-or-cli">
<TabItem value="oc" label="Ory Console" default>
```

1. Go to <ConsoleLink route="project.mfa" />.
2. In the **TOTP Authenticator App** section, use the switch to enable TOTP.
3. Define the name of the requesting party in the **Display Name**. The users see this name in the TOTP application when getting a
   one-time password.
4. Click **Save**.

```mdx-code-block
   <BrowserWindow url="https://console.ory.sh/">

   ![TOTP setup in Ory Console](../_static/mfa/3.png)

   </BrowserWindow>
```

5. After TOTP has been enabled for the Ory Network project, each user is responsible for enabling TOTP in their own account by
   pairing their account with a TOTP app.

   :::note

   In the Ory Account Experience, users are not automatically prompted to enable TOTP for their accounts. To enable TOTP, users
   must sign in to their accounts and go to the **Authenticator App** section of the **Account Settings** page.

   :::

```mdx-code-block
</TabItem>
<TabItem value="cli" label="Ory CLI" default>
```

1. Get the Ory Identities configuration from your project and save it to a file:

   ```shell
   ## List all available workspaces
   ory list workspaces

   ## List all available projects
   ory list projects --workspace <workspace-id>

   ## Get config
   ory get identity-config --project <project-id> --workspace <workspace-id> --format yaml > identity-config.yaml
   ```

2. Find `totp` in `selfservice/methods`, set `enabled` to `true`, and define the `issuer`:

   ```yaml title="identity-config.yaml"
   selfservice:
     methods:
       totp:
         // highlight-start
         config:
           # The "issuer" is the name in the TOTP application users see when getting a one-time password.
           issuer: ExampleIssuer.com
         enabled: true
         // highlight-end
   ```

3. Update the Ory Identities configuration using the file you worked with:

   ```shell
   ory update identity-config --project <project-id> --workspace <workspace-id> --file identity-config.yaml
   ```

4. After TOTP has been enabled for the Ory Network project, each user is responsible for enabling TOTP in their own account by
   pairing their account with a TOTP app.

   :::note

   In the Ory Account Experience, users are not automatically prompted to enable TOTP for their accounts. To enable TOTP, users
   must sign in to their accounts and go to the **Authenticator App** section of the **Account Settings** page.

   :::

```mdx-code-block
</TabItem>
</Tabs>
```

## Custom identity schema

By default, the identity schema is preconfigured to display the user's email address when requesting the TOTP short code. If you
are working with a custom identity schema, however, you must ensure that the identity schema is properly configured to work with
TOTP.

### Distinguishing identities requesting TOTP

To help users distinguish which identity the registered TOTP code belongs to, add a `totp` section to the identity schema section
of the trait you want to show up in the TOTP app.

For example, to select the user's email address as the identifier for TOTP:

```json title="sample identity schema"
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "traits": {
      "type": "object",
      "properties": {
        // highlight-start
        "email": {
          // highlight-end
          "type": "string",
          "format": "email",
          "title": "Your E-Mail",
          "minLength": 3,
          "ory.sh/kratos": {
            "credentials": {
              // ...
              // highlight-start
              "totp": {
                "account_name": true
              }
              // highlight-end
            }
            // ...
          }
        }
        // ...
      }
      // ...
    }
  }
}
```

## Writing E2E tests

When writing end-to-end (E2E) tests for TOTP implementation in your app,
[you can reference the Cypress tests used in Ory Identities (Ory Kratos)](https://github.com/ory/kratos/blob/fc2cecfbeab811aa1a851f953b6bc2a4c119c412/test/e2e/cypress/integration/profiles/mfa/totp.spec.ts).

## Identity credentials

When the user enables TOTP, Ory adds the following entries to the `credentials` object of the associated Identity:

```yaml
credentials:
  password:
    id: totp
    identifiers:
      - 802471b9-06f5-49d4-a88d-5e7d6bcfed22
    config:
      # This is the TOTP URL which contains the pre-shared key and some additional meta-information.
      totp_url: otpauth://totp/Example:alice@example.org?secret=JBSWY3DPEHPK3PXP&issuer=Example
```
