Is Logto Compatible with OAuth 2.0 and OpenID Connect?

Yes, Logto implements the full OAuth 2.1 and OpenID Connect 1.0 specifications, exposing standard discovery endpoints, JWKS URLs, and grant types required for complete compatibility.

Logto (logto-io/logto) is an open-source identity and access management (IAM) solution that provides native Logto OAuth 2.0 and OpenID Connect compatibility out of the box. The platform serves standard OIDC discovery documents, supports all required token grants including PKCE, and issues signed JWT ID tokens, ensuring interoperability with any standards-compliant client application.

OIDC Discovery and Standard Endpoints

Logto exposes the mandatory OpenID Connect discovery document at /.well-known/openid-configuration. In packages/core/src/sso/OidcConnector/utils.ts (line 30), the implementation confirms provider configuration retrieval:

const response = await got.get(`${issuer}/.well-known/openid-configuration`);

This endpoint returns standard metadata including authorization_endpoint, token_endpoint, and jwks_uri. The JWKS endpoint is served at /.well-known/jwks.json via the Koa middleware defined in packages/core/src/middleware/koa-auth/utils.ts (line 39), which constructs the JSON Web Key Set URL for token signature validation. The middleware tests in packages/core/src/middleware/koa-jwks-cache-control.test.ts validate these well-known endpoints.

Supported OAuth 2.0 Grant Types

Logto implements the complete OAuth 2.1 grant type specification as evidenced by the integration test suite. The codebase supports:

The OpenAPI security schema in packages/core/src/routes/swagger/consts.ts (line 63) defines the native OAuth 2 bearer token format, confirming standards-compliant token handling.

Scope Handling and ID Token Generation

Standard OIDC scopes are defined in packages/toolkit/core-kit/src/openid.ts, including the mandatory openid scope enum. ID tokens are generated as signed JWTs containing standard claims. The test file packages/integration-tests/src/tests/api/oidc/refresh-token-grant.test.ts (line 371) validates that ID tokens are only issued when the openid scope is present, ensuring strict OIDC compliance. The JWKS endpoint (packages/core/src/middleware/koa-auth/utils.ts) provides the RS256 public keys necessary for signature verification.

Implementing the Authorization Code Flow with PKCE

Below are practical examples demonstrating Logto OAuth 2.0 and OpenID Connect compatibility using the Authorization Code flow with PKCE.

Step 1: Retrieve OIDC Configuration

import got from 'got';

const LOGTO_HOST = 'https://your-logto-instance.com';

async function getOidcConfig() {
  const response = await got.get(
    `${LOGTO_HOST}/oidc/.well-known/openid-configuration`,
    { responseType: 'json' }
  );
  return response.body; // Contains issuer, endpoints, and supported scopes
}

Source reference: packages/core/src/sso/OidcConnector/utils.ts

Step 2: Generate PKCE Parameters and Authorization URL

import { randomBytes, createHash } from 'crypto';

// Generate PKCE verifier and challenge
const codeVerifier = randomBytes(32).toString('base64url');
const codeChallenge = createHash('sha256')
  .update(codeVerifier)
  .digest('base64url');

// Build authorization URL
const config = await getOidcConfig();
const params = new URLSearchParams({
  client_id: 'YOUR_CLIENT_ID',
  redirect_uri: 'https://your.app/callback',
  response_type: 'code',
  scope: 'openid profile email',
  code_challenge: codeChallenge,
  code_challenge_method: 'S256',
});
const authUrl = `${config.authorization_endpoint}?${params}`;

Source reference: Scope definitions in packages/toolkit/core-kit/src/openid.ts

Step 3: Exchange Authorization Code for Tokens

async function exchangeCodeForToken(code: string) {
  const config = await getOidcConfig();
  
  const tokenResponse = await got.post(config.token_endpoint, {
    form: {
      client_id: 'YOUR_CLIENT_ID',
      client_secret: 'YOUR_CLIENT_SECRET', // Omit for public clients
      grant_type: 'authorization_code',
      code,
      redirect_uri: 'https://your.app/callback',
      code_verifier: codeVerifier,
    },
    responseType: 'json',
  });
  
  return tokenResponse.body; // Contains access_token, id_token, refresh_token
}

Source reference: OAuth 2.1 implementation details in packages/core/CHANGELOG.md (line 1368)

Step 4: Validate the ID Token

import jwt from 'jsonwebtoken';
import jwkToPem from 'jwk-to-pem';

async function verifyIdToken(idToken: string) {
  const config = await getOidcConfig();
  const jwks = await got.get(config.jwks_uri, { responseType: 'json' });
  
  // Select appropriate key based on 'kid' header claim
  const key = jwks.body.keys[0];
  const publicKey = jwkToPem(key);
  
  return jwt.verify(idToken, publicKey, { algorithms: ['RS256'] });
}

Source reference: JWKS endpoint implementation in packages/core/src/middleware/koa-auth/utils.ts

Key Source Files and Implementation Details

Feature Source Location
OIDC Discovery packages/core/src/sso/OidcConnector/utils.ts (line 30)
JWKS Endpoint packages/core/src/middleware/koa-auth/utils.ts (line 39)
JWKS Cache Tests packages/core/src/middleware/koa-jwks-cache-control.test.ts
Scope Definitions packages/toolkit/core-kit/src/openid.ts
OIDC Constants packages/console/src/consts/oidc.ts
Token Grant Tests packages/integration-tests/src/tests/api/oidc/refresh-token-grant.test.ts (line 371)
OpenAPI Security Schema packages/core/src/routes/swagger/consts.ts (line 63)
OIDC Module Schema packages/schemas/src/foundations/jsonb-types/oidc-module.ts
Project Documentation README.md ("Full support for OIDC, OAuth 2.1")

Summary

  • Logto is fully compatible with OAuth 2.0 and OpenID Connect, implementing OAuth 2.1 and OIDC 1.0 specifications
  • Standard endpoints are available at /.well-known/openid-configuration and /.well-known/jwks.json
  • Complete grant type support includes Authorization Code with PKCE, Client Credentials, Device Flow, and Refresh Tokens
  • JWT ID tokens are signed with RS256 and validated via the JWKS endpoint defined in packages/core/src/middleware/koa-auth/utils.ts
  • Scope handling follows OIDC standards with the mandatory openid scope defined in packages/toolkit/core-kit/src/openid.ts

Frequently Asked Questions

Does Logto support PKCE for the Authorization Code flow?

Yes, Logto fully supports PKCE (Proof Key for Code Exchange) as required by OAuth 2.1 security best practices. The authorization endpoint accepts code_challenge and code_challenge_method parameters, and the token endpoint validates the code_verifier as implemented in the core OIDC provider (packages/core/src/sso/OidcConnector/utils.ts).

What OIDC discovery endpoints does Logto expose?

Logto exposes the standard discovery document at {issuer}/oidc/.well-known/openid-configuration and the JWKS endpoint at /.well-known/jwks.json. These endpoints provide metadata about authorization endpoints, token endpoints, supported scopes, and public signing keys, as confirmed by the middleware implementation in packages/core/src/middleware/koa-auth/utils.ts and validated in packages/core/src/middleware/koa-jwks-cache-control.test.ts.

Can I use Logto with existing OIDC client libraries?

Yes, any standards-compliant OIDC client library can authenticate against Logto. The platform issues standard JWT ID tokens when the openid scope is requested, supports the standard claims defined in packages/toolkit/core-kit/src/openid.ts, and exposes the UserInfo endpoint for retrieving user claims as defined in packages/schemas/src/foundations/jsonb-types/oidc-module.ts, ensuring interoperability with libraries like openid-client, AppAuth, and native platform implementations.

Does Logto implement OAuth 2.0 Device Authorization Grant?

Yes, Logto supports the Device Authorization Grant (RFC 8628) for input-constrained devices. This grant type is documented in the changelog (packages/schemas/CHANGELOG.md) and tested in the integration test suite, allowing devices with limited input capabilities to obtain access tokens via a secondary device.

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 →