Logto Security Best Practices: Enterprise-Grade Hardening in the Source Code

Logto implements defense-in-depth security through Helmet-based HTTP headers, automatic secret rotation, configurable MFA policies, scoped Personal Access Tokens, and built-in rate limiting, all enforced at the middleware and database layers.

Logto is an open-source identity and access management platform that embeds enterprise security controls directly into its architecture. Understanding Logto security best practices requires examining how the codebase implements OWASP guidelines, secret management, and tenant isolation. This analysis explores the concrete implementations in the logto-io/logto repository that protect authentication flows and sensitive data.

HTTP Security Headers and Content Security Policy

Logto uses Helmet middleware to enforce OWASP-recommended security headers across all applications (core, console, and experience).

Centralized Header Configuration

The koa-security-headers.ts middleware in packages/core/src/middleware/koa-security-headers.ts defines baseline security settings through the basicSecurityHeaderSettings object. This configuration enforces Strict-Transport-Security (HSTS) with long max-age values and enables Cross-Origin Opener Policy (COOP) and Cross-Origin Embedder Policy (COEP) protections.

Dynamic CSP Per Tenant

Logto tailors Content-Security-Policy directives per application context. The implementation defines specific source arrays including experienceScriptSource for trusted JavaScript origins, experienceConnectSource for API endpoints and CDNs, and avatarCropImageSources for image upload functionality. Production guards ensure development-only relaxations—such as Google One-Tap iframe support—never reach production builds.

Extending CSP for Custom Scripts

When organizations need to whitelist additional script sources, they can leverage the internal createSecurityHeaderSettings factory:

// src/tenant/custom-csp.ts
import { getTenantId } from '@logto/core';
import { createSecurityHeaderSettings } from '@logto/core/src/middleware/koa-security-headers';

export const getCustomHeader = (tenantId: string) => {
  const { getExperienceSecurityHeaderSettings } =
    createSecurityHeaderSettings(tenantId);

  // Append a trusted script host for this tenant only
  const customCsp = {
    scriptSrc: ['https://trusted.example.com/'],
  };

  return getExperienceSecurityHeaderSettings(customCsp);
};

This approach merges custom sources with secure defaults while respecting the isProduction environment checks defined in lines 15-22 of the middleware file.

Secret Management and Cryptographic Key Rotation

Logto never hard-codes secrets. Instead, it persists encrypted configuration in the database and implements automated rotation mechanisms.

Cookie signing keys are stored in the logto_config table under the oidc.cookieKeys key, as defined in packages/schemas/src/types/logto-config/index.ts. The system maintains multiple valid keys simultaneously to ensure zero-downtime rotation.

Automated Rotation via CLI

Administrators rotate keys using the built-in CLI:


# Rotate cookie keys – generates a fresh key, keeps the previous one for graceful rollout

pnpm cli config rotate-cookie-keys

This command executes migration logic similar to 1.0.0_rc.1-1676190092-migrate-admin-data.ts, which safely inserts new keys while preserving existing sessions.

Configuration Library

The LogtoConfigLibrary in packages/core/src/libraries/logto-config.ts handles encrypted reads and writes for sensitive values including JWT signing keys and OIDC private keys, ensuring secrets never exist in environment variables or code repositories.

Multi-Factor Authentication Implementation

Logto supports TOTP, WebAuthn, and backup codes through a flexible policy engine embedded in the sign-in experience schema.

MFA Policy Configuration

The JSONB schema in packages/schemas/src/foundations/jsonb-types/sign-in-experience.ts (lines 190-210) defines three policy levels: Mandatory requires MFA on every authentication, Optional allows user-configured MFA, and Adaptive enables risk-based step-up authentication.

Enforcing Mandatory MFA

Administrators configure tenant-wide MFA requirements via the Admin API:

await fetch(`${tenantEndpoint}/api/tenants/${tenantId}/sign-in-experience`, {
  method: 'PATCH',
  headers: { Authorization: `Bearer ${adminToken}` },
  body: JSON.stringify({
    mfa: {
      // Force MFA on every sign‑in
      policy: 'mandatory',
      factors: ['totp', 'webauthn']
    },
  }),
});

The require_mfa_verification check in the authentication flow validates these policies before issuing tokens.

Personal Access Tokens and Scoped Authorization

Logto implements scoped API access through Personal Access Tokens (PATs) with strict isolation guarantees.

Token Architecture

PATs are stored in the personal_access_tokens table with Row-Level Security (RLS) policies that isolate tenant data. The token type is explicitly declared as urn:logto:token-type:personal_access_token in packages/core/src/oidc/grants/token-exchange/types.ts.

Programmatic Token Creation

import { createPersonalAccessToken } from '@logto/core/src/queries/personal-access-token';

const pat = await createPersonalAccessToken({
  name: 'CI‑pipeline',
  expiresAt: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000), // 30 days
  scopes: ['read:users', 'write:applications']
});
console.log('PAT value (store securely):', pat.value);

The database schema and RLS setup are defined in packages/schemas/alterations/1.20.0-1723448981-personal-access-tokens.ts.

Rate Limiting and Brute-Force Protection

The Sentinel middleware protects authentication endpoints from abuse through IP and device-based throttling.

Message Rate Guarding

The message-rate-guard.ts file in packages/core/src/sentinel/ implements limits on login attempts, blocking abusive patterns before they reach the authentication logic. This prevents credential stuffing and brute-force attacks against the OIDC endpoints.

Summary

  • HTTP Security: Helmet-based headers with tenant-specific CSP, HSTS, and COOP/COEP protections enforced in koa-security-headers.ts
  • Secret Rotation: Automated cookie key rotation via CLI and encrypted storage in logto_config table accessed through LogtoConfigLibrary
  • MFA Policies: Flexible multi-factor configuration through sign-in-experience JSONB schema supporting mandatory, optional, and adaptive modes
  • Token Security: Scoped PATs with RLS isolation and explicit token type declarations (urn:logto:token-type:personal_access_token)
  • Attack Prevention: Built-in rate limiting through Sentinel middleware protecting against brute-force attempts

Frequently Asked Questions

How does Logto handle Content Security Policy violations?

Logto implements CSP through the koa-security-headers.ts middleware, which configures Helmet with strict directives for script-src, style-src, and connect-src. The system dynamically adjusts allowed sources based on tenant configuration while maintaining production guards that prevent unsafe development settings from deploying to production environments.

Use the CLI command pnpm cli config rotate-cookie-keys to generate new keys while maintaining backward compatibility. This updates the oidc.cookieKeys array in the logto_config table, allowing existing sessions to remain valid while new sessions use the fresh key. The rotation logic follows the migration pattern established in 1.0.0_rc.1-1676190092-migrate-admin-data.ts.

How does Logto protect against brute-force authentication attacks?

Logto employs the Sentinel middleware (message-rate-guard.ts) to limit login attempts per IP address and device fingerprint. This rate-limiting layer intercepts suspicious traffic patterns before they reach the OIDC grant handlers, effectively mitigating credential stuffing and automated brute-force attempts.

Are Personal Access Tokens isolated between tenants?

Yes. PATs implement Row-Level Security (RLS) policies at the database level as defined in 1.20.0-1723448981-personal-access-tokens.ts, ensuring tokens created in one tenant cannot access resources in another. The tokens use the specific type URI urn:logto:token-type:personal_access_token and store only hashed identifiers in the database, with the full value displayed only once during creation.

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 →