---
title: Payload CMSでパスキーを使えるようにする「payload-passkey」を公開しました
url: https://roboin.io/article/2026/09/16/payload-passkey-brings-passkey-authentication-to-payload-cms/
description: Payload
  CMSでパスキーを使ったパスワードレスログインができるようにする「payload-passkey」を公開しました。この記事では、payload-passkeyの特徴や使い方について紹介します。
publishedDate: 2026-09-16T15:06:04.317Z
modifiedDate: 2026-09-16T15:06:04.317Z
thumbnail: https://roboin.io/api/og/2026/09/16/payload-passkey-brings-passkey-authentication-to-payload-cms/
thumbnailAlt: 記事のサムネイル画像
thumbnailCaption: N/A
---

# Payload CMSでパスキーを使えるようにする「payload-passkey」を公開しました

Payload CMSでパスキーを使ったパスワードレスログインができるようにする「[payload-passkey](https://github.com/Robot-Inventor/payload-passkey/)」を公開しました。この記事では、payload-passkeyの特徴や使い方について紹介します。

[https://github.com/Robot-Inventor/payload-passkey/](https://github.com/Robot-Inventor/payload-passkey/)

## 開発の経緯

Payload CMSは素晴らしいCMSですが、標準ではメールアドレスとパスワードによるログインにしか対応していないため、二要素認証やパスキーなどを利用したい場合はサードパーティのプラグインを利用する必要があります。

筆者はもともと、TOTPの二要素認証を追加する[Payload TOTP](https://github.com/GeorgeHulpoi/payload-totp)というプラグインを利用していました。これは、Payload CMSの標準のログイン画面でメールアドレスとパスワードを入力したあとに、ワンタイムパスワードを入力する画面に遷移するようにするプラグインです。

Payload TOTPは非常によくできておりしばらく使っていたのですが、ログインのたびに認証アプリを開いてワンタイムパスワードを入力することを手間に感じ始めました。

そこで、パスキーの導入を検討し始めました。Payload CMS向けの既存のプラグインではパスキーにフォーカスしたものがなく、基本的にはBetter Authのプラグインを使うことになります。

私が求めていた条件として、次のような条件が挙げられます。

- 互換性とデザインの観点から、Payload CMSの既存の認証戦略を維持する
- Payload TOTPと共存可能
- パスワードはPayload CMSのデフォルトの認証戦略、TOTPはPayload TOTP、パスキーはBetter Authを使う
- (メールアドレス AND パスワード AND TOTP) OR パスキーでログイン可能

Payload CMSでBetter Authを利用できるようにする主要なプラグインとしては次のようなものが挙げられますが、既存のプラグインはどれも私のユースケースに合いませんでした。

- [@delmaredigital/payload-better-auth](https://github.com/delmaredigital/payload-better-auth/)：ログイン画面を丸ごと置き換えてしまう
- [payload-auth](https://github.com/payload-auth/payload-auth)：ドキュメントがない（当時）
- [payload-auth-plugin](https://github.com/UPDOT/payload-auth-plugin)：パスキーを実験的な機能としてサポートしているように見えるが、[実際にはコメントアウトされていて](https://github.com/UPDOT/payload-auth-plugin/blob/3fd277251479bfaa5aa2140634d02d53b0b4f04c/src/client/signin.ts#L12)サポートしていない

このように既存のいずれのプラグインも私の求める条件を満たしていませんでした。

しかし、@delmaredigital/payload-better-authはBetter Authのデータベースアダプターを個別にエクスポートしており、これをラップする形で私の条件に合うプラグインを開発できることが判明しました。そこで開発したのが、payload-passkeyです。

## payload-passkeyの特徴

payload-passkeyは、Payload CMSのデフォルトのログイン画面にパスキーでログインするボタンを追加し、アカウント管理画面からパスキーを管理できるようにします。payload-passkeyには、次のような特徴があります。

- Payload CMSのデフォルトのログイン画面にパスキーでログインするボタンを追加
- アカウントの管理画面にパスキー管理機能を追加
- Payload CMS側の設定で有効な場合、トークンの自動リフレッシュをサポート
- Payload TOTPと併用可能
- [パスキーのオートフィル](https://web.dev/articles/passkey-form-autofill)に対応
- i18nサポート
- Payload CMSのUIコンポーネントを使用しており、ダッシュボードに馴染むデザイン

payload-passkeyを有効化すると、ログイン画面に画像のようにパスキーでログインするボタンが追加されます。

![Payload CMSのログイン画面の下部に［Login with a passkey］ボタンが追加されているようすのスクリーンショット](https://roboin.io/api/media/file/payload-passkey-login-screen.png)

アカウントの管理画面にはパスキーを管理するセクションが追加されます。

![Payload CMSのアカウントの管理画面にパスキーを管理するセクションが追加されているようすのスクリーンショット](https://roboin.io/api/media/file/passkey-management-screen.png)

## payload-passkeyの使い方

payload-passkeyを使うにはまず、パッケージをインストールします。

```bash
pnpm add payload-passkey
```

次に、環境変数`BETTER_AUTH_SECRET`に32に文字以上のランダムな文字列を設定します。

```http
BETTER_AUTH_SECRET=your-secret-key-longer-than-32-characters
```

`payload.config.ts`でpayload-passkeyをプラグインとして追加します。このとき、ユーザーの情報を格納しているコレクションのスラッグをpayload-passkeyの`userCollection`に設定してください。また、`modelName`は`userCollection`から末尾の「s」を取り除いたものに設定します。

```typescript
import { buildConfig } from "payload";
import { payloadPasskey } from "payload-passkey";

const config = buildConfig({
    collections: [
        {
            slug: "users",
            auth: true,
            fields: [...],
        },
    ],
    plugins: [
        payloadPasskey({
            rpID: "your-domain.example.com",
            rpName: "Example App",
            origin: "https://your-domain.example.com",
            modelName: "user",
            userCollection: "users",
            baseURL: "https://your-domain.example.com",
            secret: process.env.BETTER_AUTH_SECRET,
            trustedOrigins: ["https://your-domain.example.com"],
            generateId: "serial",
            firstUserAdmin: true,
            enablePasskeyAutofill: true
        })
    ]
});

export default config;
```

Payload TOTPと併用したい場合は、次のようにします。

```typescript
import { buildConfig } from "payload";
import { payloadPasskey } from "payload-passkey";

const config = buildConfig({
    collections: [
        {
            slug: "users",
            auth: true,
            fields: [...],
        },
    ],
    plugins: [
        payloadPasskey({
            enableTotpCompatibility: true,
            rpID: "your-domain.example.com",
            rpName: "Example App",
            origin: "https://your-domain.example.com",
            modelName: "user",
            userCollection: "users",
            baseURL: "https://your-domain.example.com",
            secret: process.env.BETTER_AUTH_SECRET,
            trustedOrigins: ["https://your-domain.example.com"],
            generateId: "serial",
            firstUserAdmin: true,
            enablePasskeyAutofill: true
        }),
        // `payloadTotp()` must be called after `payloadPasskey()`;
        // otherwise, the collection generated by payload-passkey won't be protected by Payload TOTP.
        payloadTotp({
            collection: "users",
            totp: {
                issuer: "Example App"
            }
        })
    ]
});

export default config;
```

あとは、データベースのマイグレーションを実行すればPayload CMSでパスキーを利用できるようになります。

```bash
npm run payload migrate:create
npm run payload migrate
```

## まとめ

Payload CMSのデフォルトの認証戦略やPayload TOTPとの互換性を維持しつつ、パスキーのサポートを追加できるpayload-passkeyを公開しました。

ソースコードはGitHubで公開しているので、バグなどがありましたらissueやPRをぜひ送ってください！

[https://github.com/Robot-Inventor/payload-passkey/](https://github.com/Robot-Inventor/payload-passkey/)