Skip to content

docs: OTP within secure enclaves — new security page + updated activity types#583

Open
turnkeyintern wants to merge 1 commit intotkhq:mainfrom
turnkeyintern:feat/otp-enclave-security-docs
Open

docs: OTP within secure enclaves — new security page + updated activity types#583
turnkeyintern wants to merge 1 commit intotkhq:mainfrom
turnkeyintern:feat/otp-enclave-security-docs

Conversation

@turnkeyintern
Copy link

@turnkeyintern turnkeyintern commented Mar 9, 2026

Summary

Adds documentation for the new enclave-based OTP architecture released in SDK v2026.2.8.

What changed

New file: security/otp-enclave.mdx
A dedicated security page covering:

  • Overview of the two OTP use cases (contact verification vs. login) and which enclave flow each uses
  • The key invariant: coordinator never sees plaintext OTP in INIT_OTP_V3
  • Full sequence flow for INIT_OTP_V3 (enclave-generated), INIT_OTP_AUTH_V3 (coordinator-generated, legacy), and VERIFY_OTP_V2
  • Token consumption (OTP_LOGIN_V2, signup)
  • Security controls: bundle signature verification, HPKE encryption of OTP attempt, constant-time comparison, brute-force protection, inflight limits, TTL
  • Client-side SDK changes table (publicKey required, verifyEnclaveSignature, HPKE replaces quorumKeyEncrypt, etc.)
  • Error codes

Updated: authentication/email.mdx

  • New callout card at the top of Core Mechanism section linking to the security page, with a summary of the v2026.2.8 client-side security improvements
  • Activity type references updated: INIT_OTPINIT_OTP_V3, VERIFY_OTPVERIFY_OTP_V2, OTP_LOGINOTP_LOGIN_V2
  • Breaking Change warning expanded to include VERIFY_OTP_V2 and OTP_LOGIN_V2 version progressions
  • Authorization section updated to show both enclave (V3) and legacy auth (V3) paths

Updated: authentication/sms.mdx

  • How It Works section updated to use V3/V2 activity types with brief enclave note
  • Sandbox section references updated
  • Note linking to the security page added

Updated: docs.json

  • security/otp-enclave added to the Security tab navigation (after enclave-secure-channels)

- Add security/otp-enclave.mdx: comprehensive doc covering the enclave-first
  OTP architecture (INIT_OTP_V3, VERIFY_OTP_V2, OTP_LOGIN_V2), including
  sequence flows, key invariants, client-side security changes from SDK v2026.2.8,
  and security controls (bundle sig verification, HPKE encryption, brute-force
  protection, inflight limits)

- Update authentication/email.mdx:
  - Add callout card linking to new security page with summary of SDK v2026.2.8
    client-side security improvements
  - Update activity type references: INIT_OTP → INIT_OTP_V3, VERIFY_OTP →
    VERIFY_OTP_V2, OTP_LOGIN → OTP_LOGIN_V2
  - Expand Breaking Change policy table with VERIFY_OTP_V2 and OTP_LOGIN_V2
    version progression
  - Update Authorization section to list both enclave (V3) and legacy auth (V3)
    paths with correct activity types

- Update authentication/sms.mdx:
  - Update How it Works activity types to V3/V2 equivalents
  - Add note linking to OTP enclave security page
  - Fix sandbox verify/login activity type references

- Update docs.json: add security/otp-enclave to Security tab navigation

References: tkhq/sdk#1220, tkhq/sdk#1221

## Enclave-based OTP security

Starting with SDK `v2026.2.8`, Turnkey's OTP system uses an **enclave-first architecture** where the OTP code is generated, delivered, and verified entirely inside the TLS Fetcher Enclave. The coordinator never sees a plaintext OTP code.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OTP system can be changed to OTP flow or OTP signup and login authentication flows


## Enclave-based OTP security

Starting with SDK `v2026.2.8`, Turnkey's OTP system uses an **enclave-first architecture** where the OTP code is generated, delivered, and verified entirely inside the TLS Fetcher Enclave. The coordinator never sees a plaintext OTP code.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we use the term coordinator extensively in our external facing documentation?? Feels like an internal architectural detail. I do indeed see a couple of instances in our documentation so not a super strong rebuff here, but I wonder if it would be better for general understanding to say something like -- "Turnkey's non-enclave services never see a plaintext OTP code"

- The client verifies the enclave's bundle signature before trusting the `otpEncryptionTargetBundle` public key
- OTP attempts are HPKE-encrypted before being sent to the server
- `publicKey` is now required when encrypting an OTP attempt (no throwaway keypairs)
- Login/signup sign with the verification token key, not the session key
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

login/signup require a client signature generated using the key passed in during verification, not the session key

Old: `ACTIVITY_TYPE_INIT_OTP`, `ACTIVITY_TYPE_INIT_OTP_V2`<br/>
New: `ACTIVITY_TYPE_INIT_OTP_V3`

**INIT_OTP_AUTH** (coordinator-generated, existing-user login)<br/>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we're trying to deprecate these

**INIT_OTP**<br/>
Old: `ACTIVITY_TYPE_INIT_OTP`<br/>
New: `ACTIVITY_TYPE_INIT_OTP_V2`
**INIT_OTP** (enclave-generated, contact verification & signup)<br/>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only INIT_OTP_V3 is enclave generated

2. `VERIFY_OTP` - verifies the code and returns a verificationToken JWT
3. `OTP_LOGIN` - verified the verificationToken and returns a session JWT
1. `INIT_OTP_V3` — enclave generates and sends a 6–9 digit or alphanumeric OTP to the specified phone number; the coordinator never sees the plaintext code
2. `VERIFY_OTP_V2` — enclave verifies the code and returns a signed verificationToken JWT
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should clarify that the verification token from VERIFY_OTP_V2 is enclave generated and signed by TLSF unlike old verification tokens generated by VERIFY_OTP

description: "How Turnkey generates, delivers, and verifies one-time passwords entirely inside the TLS Fetcher Enclave, ensuring the coordinator never sees a plaintext OTP."
---

Turnkey's OTP system (email and SMS) has been redesigned so that the entire lifecycle of a one-time password — generation, delivery, and verification — happens inside the **TLS Fetcher Enclave**. This page explains the security architecture, the cryptographic invariants that protect your users, and how the SDK enforces them on the client side.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OTP system -> OTP flow or OTP signup and login authentication flows

| Use case | Init activity | Verify activity | OTP generator |
|---|---|---|---|
| Contact verification & signup | `ACTIVITY_TYPE_INIT_OTP_V3` | `ACTIVITY_TYPE_VERIFY_OTP_V2` | TLS Fetcher Enclave |
| Login (existing user auth) | `ACTIVITY_TYPE_INIT_OTP_AUTH_V3` | `ACTIVITY_TYPE_VERIFY_OTP_V2` | Coordinator (legacy) |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to deprecate the endpoints with AUTH, also cant use VERIFY_OTP_V2 with them

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants