認証
EmDashは、プライマリのログイン方法としてパスキー認証を使用します。パスキーはフィッシング耐性があり、パスワードを必要とせず、ブラウザやパスワードマネージャーを通じてデバイス間で動作します。
Cloudflareデプロイメントでは、オプションでCloudflare Accessを代替認証プロバイダーとして使用できます。
パスキーは、Web標準であるWebAuthnを使用し、デバイスに保存されるかパスワードマネージャーを通じて同期される公開鍵認証情報を作成します。ログイン時、デバイスはネットワーク上にパスワードを送信することなく、認証情報の所有を証明します。
パスキー認証の利点:
- 記憶または漏洩するパスワードがない
- フィッシング耐性 — 認証情報はサイトのドメインに紐付けられます
- クロスデバイス同期 — iCloudキーチェーン、Googleパスワードマネージャー、1Passwordなどで動作します
- 高速ログイン — 生体認証またはPINでワンタップ
初回ユーザーセットアップ
Section titled “初回ユーザーセットアップ”初めて管理パネルにアクセスする際、セットアップウィザードが管理者アカウント作成を案内します。
-
セットアップウィザードにリダイレクトされます。以下を入力します:
- サイトタイトル — サイトの名前
- タグライン — 短い説明
- 管理者メール — メールアドレス
-
サイトを作成をクリックしてパスキーを登録します
-
ブラウザがパスキー作成を促します:
- macOS: Touch ID、デバイスパスワード、またはセキュリティキー
- Windows: Windows Helloまたはセキュリティキー
- モバイル: Face ID、指紋、またはPIN
-
パスキーが登録されると、ログイン状態になり管理ダッシュボードにリダイレクトされます。
セットアップ後、管理パネルに戻るとパスキー認証がトリガーされます:
-
/_emdash/adminにアクセスします -
ログインしていない場合、ログインページが表示されます
-
サインインをクリックして認証します
-
ブラウザがパスキー(生体認証、PIN、またはセキュリティキー)を要求します
-
検証後、管理ダッシュボードにリダイレクトされます
マジックリンク代替手段
Section titled “マジックリンク代替手段”パスキーが使用できない場合(例: デバイス紛失)、マジックリンクが代替手段を提供します。これにはメール設定が必要です。
-
ログインページでメールでサインインをクリックします
-
メールアドレスを入力します
-
受信トレイでログインリンクを確認します
-
リンクをクリックして認証します(15分間有効)
OAuthログイン
Section titled “OAuthログイン”EmDashは設定時にGitHubおよびGoogleでのOAuthログインをサポートします。ユーザーは初期パスキーセットアップ後にアカウントをリンクできます。
セットアップ手順については設定ガイドを参照してください。
ユーザーロール
Section titled “ユーザーロール”EmDashは5つのレベルでロールベースのアクセス制御を使用します:
| ロール | レベル | 説明 |
|---|---|---|
| 購読者 | 10 | 閲覧専用アクセス |
| 投稿者 | 20 | コンテンツ作成(承認が必要) |
| 作成者 | 30 | 自身のコンテンツの作成/編集/公開 |
| 編集者 | 40 | すべてのコンテンツ管理 |
| 管理者 | 50 | 設定を含む完全アクセス |
各ロールは下位レベルのすべての権限を継承します。最初のユーザーは常に管理者として作成されます。
ユーザー招待
Section titled “ユーザー招待”管理者は管理パネルから新しいユーザーを招待できます:
-
設定 > ユーザーに移動します
-
ユーザーを招待をクリックします
-
ユーザーのメールアドレスを入力し、ロールを選択します
-
招待を送信をクリックします
-
ユーザーは招待リンクを含むメールを受信します
-
リンクをクリックし、パスキーを登録します
招待は7日間有効です。管理者はユーザーページから招待を再送信または取り消すことができます。
パスキー管理
Section titled “パスキー管理”ユーザーはアカウント設定からパスキーを管理できます:
- パスキー追加 — バックアップや他のデバイス用に追加のパスキーを登録します
- パスキー削除 — 使用しなくなったパスキーを削除します
- パスキー名変更 — パスキーに説明的な名前を付けます
各ユーザーは最大10個のパスキーを登録できます。
セルフサインアップ
Section titled “セルフサインアップ”チームサイトでは、特定のメールドメインに対してセルフサインアップを有効にできます:
import { defineConfig } from "astro/config";import emdash from "emdash/astro";
export default defineConfig({ integrations: [ emdash({ auth: { selfSignup: { domains: ["example.com"], defaultRole: "contributor", }, }, }), ],});一致するメールドメインを持つユーザーは招待なしでサインアップできます。確認メールを受信し、パスキーを登録してサインアップを完了します。
セッション設定
Section titled “セッション設定”セッションは安全なHttpOnlyクッキーを使用し、適切なデフォルト値を設定しています:
js title="astro.config.mjs"emdash({ auth: { session: { maxAge: 30 * 24 * 60 * 60, // 30 days (default) sliding: true, // Reset expiry on activity }, },});セキュリティに関する注意
Section titled “セキュリティに関する注意”- パスキーは公開鍵として保存されます — 秘密鍵はデバイスから離れません
- チャレンジ検証によりリプレイ攻撃を防止します
- レート制限によりブルートフォース攻撃から保護します(5回/分/IP)
- セッションはHttpOnly、Secure、SameSite=Laxでクッキーセキュリティを確保します
- マジックリンクトークンはSHA-256ハッシュ化されます — 生のトークンは保存されません
トラブルシューティング
Section titled “トラブルシューティング”「登録されたパスキーがありません」
Section titled “「登録されたパスキーがありません」”ログイン時にこのエラーが表示される場合、パスワードマネージャーからパスキーが削除された可能性があります。管理者にマジックリンクまたは新しい招待を送信するよう依頼してください。
「パスキー認証に失敗しました」
Section titled “「パスキー認証に失敗しました」”これは通常、パスキーが異なるドメイン用に作成されたことを意味します。パスキーはドメインに紐付けられます — localhost:4321用のパスキーはexample.comでは動作しません。各ドメイン用に新しいパスキーを登録してください。
「セッションが期限切れです」
Section titled “「セッションが期限切れです」”セッションはデフォルトで30日間持続し、スライディング有効期限があります。予期せずログアウトした場合は、クッキーをクリアして再度ログインしてください。
すべてのパスキーを紛失
Section titled “すべてのパスキーを紛失”登録したすべてのパスキーへのアクセスを失った場合:
- 別の管理者にマジックリンクを送信するよう依頼します(メール設定が必要)
- マジックリンクを使用してログインします
- アカウント設定で新しいパスキーを登録します
唯一の管理者でメールが設定されていない場合、データベースを通じてサイトの認証をリセットする必要があります。
Cloudflare Access
Section titled “Cloudflare Access”Cloudflareにデプロイする場合、パスキーの代わりにCloudflare Accessを認証プロバイダーとして使用できます。Accessは既存のアイデンティティプロバイダーを使用してエッジで認証を処理します。
Cloudflare Accessを使用する理由
Section titled “Cloudflare Accessを使用する理由”- シングルサインオン — ユーザーは会社のIdPで認証します
- 一元化されたアクセス制御 — Cloudflareダッシュボードで管理者にアクセスできるユーザーを管理できます
- パスキー管理不要 — パスキーの登録や管理は不要です
- グループベースのロール — IdPグループをEmDashロールに自動的にマッピングします
セットアップ
Section titled “セットアップ”- EmDashサイト用のCloudflare Accessアプリケーションを作成します
- アプリケーション設定からApplication Audience (AUD) Tagをメモします
- EmDashがAccessを使用するように設定します:
js title="astro.config.mjs"import { defineConfig } from "astro/config";import cloudflare from "@astrojs/cloudflare";import emdash from "emdash/astro";import { d1, access } from "@emdash-cms/cloudflare";
export default defineConfig({ output: "server", adapter: cloudflare(), integrations: [ emdash({ database: d1({ binding: "DB" }), auth: access({ teamDomain: "myteam.cloudflareaccess.com", audience: "abc123def456...", // From Access app settings }), }), ],});設定オプション
Section titled “設定オプション”| オプション | タイプ | デフォルト | 説明 |
|---|---|---|---|
teamDomain | string | 必須 | あなたのAccessチームドメイン (例: myteam.cloudflareaccess.com) |
audience | string | 必須 | Access設定からのApplication Audience (AUD) タグ |
autoProvision | boolean | true | 初回Accessログイン時にEmDashユーザーを作成します |
defaultRole | number | 30 | どのグループにも一致しないユーザーのロール (30 = 著者) |
syncRoles | boolean | false | IdPグループに基づいて各ログイン時にロールを更新します |
roleMapping | object | — | IdPグループ名をロールレベルにマッピングします |
audienceEnvVar | string | "CF_ACCESS_AUDIENCE" | オーディエンストークンの環境変数名 (ハードコーディングの代替) |
ロールマッピング
Section titled “ロールマッピング”IdPグループをEmDashロールにマッピングします:
js title="astro.config.mjs"emdash({ auth: access({ teamDomain: "myteam.cloudflareaccess.com", audience: "abc123...", roleMapping: { Admins: 50, // Admin "Content Editors": 40, // Editor Writers: 30, // Author }, defaultRole: 20, // Contributor for users not in any group }),});ユーザーが複数のグループに所属する場合、最初に一致したグループが優先されます。サイトにアクセスする最初のユーザーは、グループに関係なく常に管理者になります。
ロール同期の動作
Section titled “ロール同期の動作”デフォルト (syncRoles: false) では、ユーザーのロールは初回ログイン時に設定され、その後は変更されません。これにより、管理者はEmDash内で手動でロールを調整できます。
IdPグループを権威あるものにしたい場合(ユーザーのロールが現在のグループに基づいて毎回のログイン時に更新されるようにする場合)は、syncRoles: true を設定します。
- ユーザーが
/_emdash/adminにアクセスします - Cloudflare Accessがリクエストをインターセプトし、IdPにリダイレクトします
- ユーザーが認証します(SSO、MFAなど)
- Accessがリクエストに署名付きJWTを設定します
- EmDashがJWTを検証し、ユーザーを作成/認証します
無効化される機能
Section titled “無効化される機能”Accessが有効になると、以下の機能は利用できなくなります:
- ログインページ (
/_emdash/admin/login) - パスキーの登録と管理
- OAuthログイン
- マジックリンクログイン
- セルフサインアップ
- ユーザー招待
ユーザー管理は、Cloudflare Accessポリシーを通じて完全に行われます。
トラブルシューティング
Section titled “トラブルシューティング””No Access JWT present”
Section titled “”No Access JWT present””リクエストがAccess JWTなしでEmDashに到達しました。これは以下を意味します:
- Accessがアプリケーションを保護するように設定されていない
- Accessポリシーが管理者ルートに一致していない
Accessアプリケーションが /_emdash/admin/* をカバーしていることを確認してください。
“JWT audience mismatch”
Section titled ““JWT audience mismatch””設定の audience がJWTと一致しません。Accessアプリケーション設定のApplication Audience Tagを再確認してください。
“User not authorized”
Section titled ““User not authorized””ユーザーはAccess経由で認証されましたが、autoProvision が false で、EmDashにユーザーが存在しません。以下のいずれかを行ってください:
autoProvision: trueを設定する、または- ユーザーがログインする前に手動でユーザーを作成する