# Customizing Logto: 8 Core Entry Points for Extending Authentication Behavior

> Explore 8 core entry points to customize Logto's authentication behavior. Extend flows and UI without altering Logto's source code. Learn more at logto-io/logto.

- Repository: [Logto/logto](https://github.com/logto-io/logto)
- Tags: how-to-guide
- Published: 2026-07-06

---

**Logto provides eight officially supported extension points—Inline Hooks, Custom JWT Workers, custom sign-in UI assets, CSP configuration, custom data fields, tenant IDs, custom domains, and connector metadata—that let developers modify authentication flows, token payloads, and user interfaces without modifying core source code.**

Customizing Logto behavior centers on its declarative extension architecture rather than code forks. The platform exposes TypeScript-validated guards, Management API endpoints, and CLI tooling that let you inject custom logic at specific lifecycle stages. Whether you need to run JavaScript after user verification, rewrite JWTs via Cloudflare Workers, or serve a completely custom sign-in experience, these entry points provide safe, upgradeable hooks into the authentication pipeline.

## Authentication Flow Extensions: Inline Hooks

**Inline Hooks** allow you to execute custom JavaScript during critical authentication transitions. The system supports two primary hook types defined in [`packages/schemas/src/types/logto-config/inline-hook.ts`](https://github.com/logto-io/logto/blob/main/packages/schemas/src/types/logto-config/inline-hook.ts) (lines 8‑22): `PostFirstFactorVerification` and `PostSignIn`.

These hooks accept a script string, environment variables, and an execution error policy. When enabled, Logto sandboxes and executes your code immediately after the specified event fires.

```ts
import { LogtoInlineHookKey } from 'logto/schemas';

const hookPayload = {
  script: 'module.exports = async ({ user }) => { console.log("User signed in:", user.id); };',
  enabled: true,
  onExecutionError: 'allow',
};

await fetch(`${endpoint}/api/hook`, {
  method: 'POST',
  headers: { Authorization: `Bearer ${token}` },
  body: JSON.stringify({
    hookType: LogtoInlineHookKey.PostSignIn,
    ...hookPayload,
  }),
});

```

The `inlineHookGuard` validates all payloads against the schema defined in the source file, ensuring type safety for hook configurations.

## Token Customization

Logto offers two distinct mechanisms for customizing JWT contents: Cloudflare Worker integration for global token transformation, and interaction-level JWT customizers for targeted payload modifications.

### Cloudflare Worker JWT Rewriting

The **Custom JWT** extension point delegates token generation to a Cloudflare Worker URL you specify. Configuration is validated by `customJwtWorkerConfigGuard` in [`packages/schemas/src/types/system.ts`](https://github.com/logto-io/logto/blob/main/packages/schemas/src/types/system.ts) (lines 188‑202).

```ts
import { customJwtWorkerConfigGuard } from 'logto/schemas';

const config = {
  cloudflareWorkerUrl: 'https://my-worker.example.com',
  secret: 'super‑secret',
};

customJwtWorkerConfigGuard.parse(config); // validates shape before saving

```

This approach intercepts the JWT before it reaches the client, allowing you to rewrite claims or augment payload data using external business logic.

### Interaction-Level JWT Customizer

For per-interaction modifications (such as adding organization-specific claims), use the JWT customizer validated by `customJwtFetcherGuard` in [`packages/schemas/src/types/logto-config/jwt-customizer.ts`](https://github.com/logto-io/logto/blob/main/packages/schemas/src/types/logto-config/jwt-customizer.ts) (lines 180‑214). This entry point receives the full interaction context and returns modified token payloads.

## User Interface Customization

### Custom Sign-In UI Assets

You can replace Logto's default sign-in interface by uploading a zip archive of your own HTML, CSS, and JavaScript assets. The `logto tunnel deploy` CLI command handles packaging and deployment, implemented in [`packages/tunnel/src/commands/deploy/index.ts`](https://github.com/logto-io/logto/blob/main/packages/tunnel/src/commands/deploy/index.ts) (lines 13‑34) with upload utilities in [`packages/tunnel/src/commands/deploy/utils.ts`](https://github.com/logto-io/logto/blob/main/packages/tunnel/src/commands/deploy/utils.ts) (lines 104‑179).

```bash
logto tunnel deploy \
  --endpoint https://api.logto.io \
  --access-token $TOKEN \
  --folder ./my-custom-ui

```

The CLI posts the archive to `/api/sign-in-exp/default/custom-ui-assets` and records the returned `customUiAssetId` for your tenant configuration.

### Custom Content Security Policy (CSP)

When serving custom UI assets, you must whitelist external script and connection sources via the **Custom CSP** configuration. The `customUiCsp` object is defined and guarded in [`packages/toolkit/core-kit/src/custom-ui-csp.ts`](https://github.com/logto-io/logto/blob/main/packages/toolkit/core-kit/src/custom-ui-csp.ts) (lines 3‑12).

```ts
import { customUiCspGuard } from '@logto/toolkit';

const csp = {
  scriptSrc: ['https://cdn.jsdelivr.net'],
  connectSrc: ['https://api.logto.io'],
};

customUiCspGuard.parse(csp); // ensures only allowed directives pass validation

```

This prevents browser security errors while loading external resources in your custom interface.

## Data Model Extensions

### Custom Data Fields

Logto allows arbitrary JSON storage on users and applications through the `customData` field. The user schema in [`packages/schemas/src/types/user.ts`](https://github.com/logto-io/logto/blob/main/packages/schemas/src/types/user.ts) (line 18) defines this field, which persists through the entire authentication lifecycle and appears in hook contexts.

```ts
await fetch(`${endpoint}/api/users/${userId}`, {
  method: 'PATCH',
  headers: { Authorization: `Bearer ${token}` },
  body: JSON.stringify({
    customData: {
      favoriteColor: 'blue',
      subscriptionPlan: 'pro',
    },
  }),
});

```

### Custom Profile Fields

Beyond `customData`, you can define structured profile extensions via `customProfileFields` and `customProfileFieldCatalog`, configured in [`packages/schemas/src/types/sign-in-experience.ts`](https://github.com/logto-io/logto/blob/main/packages/schemas/src/types/sign-in-experience.ts) (lines 57‑74). These fields appear in the admin console and can be validated against custom schemas.

## Deployment Configuration

### Custom Tenant IDs

For private-cloud deployments, Logto supports custom tenant identifiers using lowercase letters, numbers, and hyphens up to 21 characters. Validation uses `customTenantIdRegEx` and `customTenantIdMaxLength` from [`packages/toolkit/core-kit/src/regex.ts`](https://github.com/logto-io/logto/blob/main/packages/toolkit/core-kit/src/regex.ts) (lines 23‑30).

```ts
import { customTenantIdRegEx, customTenantIdMaxLength } from '@logto/toolkit';

function isValidTenantId(id: string) {
  return id.length <= customTenantIdMaxLength && customTenantIdRegEx.test(id);
}

```

### Multiple Custom Domains

Enterprise deployments can enable multiple custom domains per tenant. The feature toggle and URL resolution logic reside in [`packages/shared/src/node/env/UrlSet.ts`](https://github.com/logto-io/logto/blob/main/packages/shared/src/node/env/UrlSet.ts) (lines 4‑18) and [`packages/shared/src/node/env/GlobalValues.ts`](https://github.com/logto-io/logto/blob/main/packages/shared/src/node/env/GlobalValues.ts) (lines 157‑162).

```ts
import { GlobalValues } from '@logto/shared/node/env';

if (GlobalValues.isMultipleCustomDomainsEnabled) {
  // Logic to register additional hostnames per tenant
}

```

This allows organizations to serve authentication experiences from branded domains while maintaining a single Logto tenant backend.

## Connector Customization

**Connectors** (OIDC, OAuth2, SAML, etc.) expose extension points for custom metadata, email templates, and internationalization strings. The metadata schema in [`packages/toolkit/connector-kit/src/types/metadata.ts`](https://github.com/logto-io/logto/blob/main/packages/toolkit/connector-kit/src/types/metadata.ts) (lines 56‑92) supports a `customData` field for connector-specific branding and configuration.

```ts
const myConnector = {
  id: 'my-oidc',
  type: 'oidc',
  metadata: {
    customData: { branding: 'dark', region: 'eu-west' },
  },
};

```

This lets connector developers embed arbitrary configuration data that the core Logto platform preserves and passes through during authentication flows.

## Summary

- **Inline Hooks** (`PostFirstFactorVerification`, `PostSignIn`) execute custom JavaScript at specific authentication lifecycle stages, defined in [`packages/schemas/src/types/logto-config/inline-hook.ts`](https://github.com/logto-io/logto/blob/main/packages/schemas/src/types/logto-config/inline-hook.ts).
- **Custom JWT** configurations support Cloudflare Worker integration (validated by `customJwtWorkerConfigGuard` in [`system.ts`](https://github.com/logto-io/logto/blob/main/system.ts)) and interaction-level customization (validated by `customJwtFetcherGuard` in [`jwt-customizer.ts`](https://github.com/logto-io/logto/blob/main/jwt-customizer.ts)).
- **Custom UI Assets** deploy via the `logto tunnel deploy` CLI, with CSP whitelisting managed through `customUiCspGuard` in [`custom-ui-csp.ts`](https://github.com/logto-io/logto/blob/main/custom-ui-csp.ts).
- **Custom Data Fields** store arbitrary JSON on users ([`user.ts`](https://github.com/logto-io/logto/blob/main/user.ts) line 18) and applications, while structured profile extensions use `customProfileFields` in [`sign-in-experience.ts`](https://github.com/logto-io/logto/blob/main/sign-in-experience.ts).
- **Custom Tenant IDs** follow regex patterns defined in [`regex.ts`](https://github.com/logto-io/logto/blob/main/regex.ts) (lines 23‑30), supporting up to 21 characters.
- **Custom Domains** rely on `GlobalValues.isMultipleCustomDomainsEnabled` and `UrlSet` configuration for enterprise multi-domain deployments.
- **Connector Metadata** accepts custom data objects defined in [`metadata.ts`](https://github.com/logto-io/logto/blob/main/metadata.ts) (lines 56‑92) for template and branding customization.

## Frequently Asked Questions

### What is the difference between Inline Hooks and JWT Customizers?

**Inline Hooks** execute arbitrary JavaScript after specific authentication events (like `PostSignIn`) and are ideal for triggering external workflows or logging. **JWT Customizers** specifically modify token payloads either globally via Cloudflare Workers or per-interaction via the customizer guard, making them suited for claim augmentation. Hooks focus on side effects; customizers focus on token content.

### How do I validate custom data before saving it to Logto?

Logto provides TypeScript guards for all extension points. Import `customUiCspGuard` for CSP validation, `customJwtWorkerConfigGuard` for JWT configuration, and `inlineHookGuard` for hook payloads. These guards are exported from their respective schema files (e.g., [`packages/toolkit/core-kit/src/custom-ui-csp.ts`](https://github.com/logto-io/logto/blob/main/packages/toolkit/core-kit/src/custom-ui-csp.ts)) and ensure data conforms to expected shapes before hitting the Management API.

### Can I deploy a custom UI without modifying Logto's core code?

Yes. The `logto tunnel deploy` CLI command (source in [`packages/tunnel/src/commands/deploy/index.ts`](https://github.com/logto-io/logto/blob/main/packages/tunnel/src/commands/deploy/index.ts)) uploads your static assets as a zip archive to Logto's cloud or your private instance. Logto serves these files instead of its default UI, and you configure CSP rules separately through the `customUiCsp` object—no core code changes required.

### What are the limitations for custom tenant IDs?

Custom tenant IDs must match the regex pattern defined in [`packages/toolkit/core-kit/src/regex.ts`](https://github.com/logto-io/logto/blob/main/packages/toolkit/core-kit/src/regex.ts) (lines 23‑30), which restricts identifiers to lowercase letters, numbers, and hyphens with a maximum length of 21 characters. This ensures compatibility with Logto's internal routing and database naming conventions.