Configuring Logto Verification Records and CAPTCHA Providers: A Complete Guide

Logto stores authentication steps in verification records indexed by type in a VerificationRecordsMap, while CAPTCHA providers like reCAPTCHA Enterprise and Turnstile are configured via the /api/captcha-provider endpoint and managed through the Security → CAPTCHA settings in the admin console.

When implementing secure authentication flows in the logto-io/logto identity platform, understanding how verification records and CAPTCHA providers work together is essential. This guide explores the internal architecture of verification tracking and the practical steps for configuring bot protection in your sign-in experiences.

Understanding Verification Records in Logto

Logto tracks every step a user takes during authentication through verification records. These records represent distinct verification methods including password validation, one-time tokens, social logins, Enterprise SSO, and CAPTCHA challenges.

How Verification Records Are Stored

Each verification record is persisted in the verification_records database table. The records are assembled into an array attached to the interaction context, making them accessible to custom token-claims scripts, the admin console, and the front-end experience.

The interaction schema defines these records in packages/schemas/src/types/interactions.ts, where you can also find the optional captchaToken field used when CAPTCHA verification completes:

// From packages/schemas/src/types/interactions.ts
captchaToken?: string;  // Present when CAPTCHA verification succeeds

The VerificationRecordsMap Class

The core interaction engine implements verification tracking through the ExperienceInteraction class in packages/core/src/routes/experience/classes/experience-interaction.ts. This class maintains a VerificationRecordsMap that indexes records by VerificationType.

Key implementation details from the source code include:

  • Records are added via the setValue method when a verification step completes
  • The map exposes helper methods like isMfaVerified to evaluate multi-factor authentication status
  • Records are converted to JSON for API responses using verificationRecords: this.verificationRecordsArray.map(r => r.toJson())
// Conceptual usage from the ExperienceInteraction implementation
class VerificationRecordsMap {
  // Indexes records by verification type
  setValue(type: VerificationType, record: VerificationRecord): void;
  
  // Evaluates MFA completion status
  isMfaVerified(): boolean;
  
  // Converts records for API responses
  get verificationRecordsArray(): VerificationRecord[];
}

Supported CAPTCHA Providers and Configuration

Logto supports two enterprise-grade CAPTCHA providers to protect registration, sign-in, and password-recovery flows. Only one provider can be active at a time according to the single provider policy enforced in the core routes.

reCAPTCHA Enterprise Configuration

The reCAPTCHA Enterprise provider requires specific configuration fields defined in packages/schemas/src/foundations/jsonb-types/captcha.ts:

Field Type Description
type string "RecaptchaEnterprise"
siteKey string Your reCAPTCHA site key
secretKey string Your reCAPTCHA secret key
projectId string Google Cloud project identifier
domain string Optional custom domain (e.g., recaptcha.net)
mode string Optional: "invisible" or "checkbox"

Turnstile Configuration

Cloudflare Turnstile offers a simpler configuration schema with fewer required fields:

Field Type Description
type string "Turnstile"
siteKey string Your Turnstile site key
secretKey string Your Turnstile secret key

Database Schema and REST API

Provider configurations are stored in the captcha_providers table, which was added by the 1.26.0-1741572426-add-captcha-providers alteration script. The REST API exposes these settings through endpoints defined in packages/core/src/routes/captcha-provider/index.ts.

The API enforces a single provider policy, meaning you can configure either reCAPTCHA Enterprise or Turnstile, but not both simultaneously.

Enabling CAPTCHA in Authentication Flows

Once configured, CAPTCHA protection must be explicitly enabled for specific authentication flows through the admin console or management API.

Admin Console Configuration

In the Logto admin console, navigate to Security → CAPTCHA to:

  • Toggle CAPTCHA on/off for registration, sign-in, and password-recovery flows
  • Select your configured provider (reCAPTCHA Enterprise or Turnstile)
  • Enter required credentials (siteKey, secretKey, projectId for reCAPTCHA)
  • Optionally specify a custom domain for regions where default endpoints are restricted

The UI implementation fetches configuration data from packages/console/src/pages/Security/Captcha/use-data-fetch.ts.

Interaction Flow Integration

When CAPTCHA is enabled, the interaction flow checks the captchaEnabled flag before presenting the widget. Upon successful verification, the captchaToken is added to the interaction record and validated during the authentication process.

The system queries verification records through the database layer defined in packages/core/src/tenants/Queries.ts, ensuring persistence across interaction steps.

Practical Implementation Examples

Below are complete examples for interacting with verification records and configuring CAPTCHA providers via the Logto Management API.

Fetching Verification Records

Retrieve the current interaction state to inspect verification progress:

const interaction = await fetch(
  `${baseUrl}/api/interaction/${interactionId}`,
  { 
    headers: { 
      Authorization: `Bearer ${adminToken}` 
    } 
  }
).then(r => r.json());

console.log('Verification records:', interaction.verificationRecords);

Configuring reCAPTCHA Enterprise

Update your CAPTCHA provider configuration using the REST API:

await fetch(`${baseUrl}/api/captcha-provider`, {
  method: 'PUT',
  headers: {
    'Content-Type': 'application/json',
    Authorization: `Bearer ${adminToken}`,
  },
  body: JSON.stringify({
    type: 'RecaptchaEnterprise',
    siteKey: 'your-site-key',
    secretKey: 'your-secret-key',
    projectId: 'your-project-id',
    domain: 'recaptcha.net',  // Optional: for regions requiring custom domains
    mode: 'invisible',        // Optional: or 'checkbox'
  }),
});

Enabling CAPTCHA via Management API

Activate CAPTCHA protection for your sign-in experience:

await fetch(`${baseUrl}/api/sign-in-experience`, {
  method: 'PATCH',
  headers: {
    'Content-Type': 'application/json',
    Authorization: `Bearer ${adminToken}`,
  },
  body: JSON.stringify({
    captchaConfig: {
      enabled: true,
    },
  }),
});

Summary

  • Verification records track authentication steps in the verification_records table and are managed through the VerificationRecordsMap class in ExperienceInteraction
  • CAPTCHA providers are configured in the captcha_providers table with support for reCAPTCHA Enterprise and Cloudflare Turnstile
  • The system enforces a single provider policy through the /api/captcha-provider endpoints
  • Admin console configuration is available under Security → CAPTCHA for visual management
  • Successful CAPTCHA verification adds a captchaToken to the interaction record, which is defined in the interaction schema

Frequently Asked Questions

What are verification records in Logto?

Verification records are database entries that track each step a user completes during authentication. Stored in the verification_records table, they represent distinct methods like password verification, social login, or CAPTCHA completion. The ExperienceInteraction class indexes these by type in a VerificationRecordsMap and exposes helper methods like isMfaVerified to evaluate authentication status.

How do I configure CAPTCHA in Logto?

You can configure CAPTCHA through the admin console at Security → CAPTCHA or via the /api/captcha-provider REST endpoint. You must provide the provider type (RecaptchaEnterprise or Turnstile), site key, and secret key. For reCAPTCHA Enterprise, you also need a projectId. Only one provider can be active at a time according to the enforcement logic in packages/core/src/routes/captcha-provider/index.ts.

What CAPTCHA providers does Logto support?

Logto currently supports two providers: reCAPTCHA Enterprise and Cloudflare Turnstile. reCAPTCHA Enterprise supports optional configuration for custom domains and display modes (invisible or checkbox), while Turnstile requires only the site key and secret key. Both are defined in packages/schemas/src/foundations/jsonb-types/captcha.ts.

Where are verification records stored in the database?

Verification records are stored in the verification_records table and queried through the database layer in packages/core/src/tenants/Queries.ts. The records are attached to interaction contexts and converted to JSON for API responses, allowing inspection by custom token-claims scripts and the admin console.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →