KASUGAI Canvas v6.17.0

Cloudflare 認証 — Workers(cloudflare-workers)

← 認証とプラグインへ戻る

4. Cloudflare 認証(cloudflare):Workers

概要

3. Cloudflare 認証 — Pagesの機能(KV の .kasc・R2 秘匿データ配信)に加えて、静的ファイル自体も含めて全リクエストを認証ゲートする方式です。Worker スクリプトが全リクエストを処理し(run_worker_first)、ログイン時に発行される署名トークンの Cookie(HttpOnly・12時間有効)を持たないアクセスには静的ファイルも返しません。

秘匿データがすべて Functions/Worker 経由になる設計では Pages の「静的ファイル無料無制限」の利点が薄いため、静的ファイルまで保護できる本方式が適しています。

control を 4 に設定するとこの方式が選択されます(クライアント実装は cloudflare と共通で、r2:// 書き換えも有効)。

構成

workers/
  wrangler.toml  … assets=../web、KV/R2バインド、run_worker_first=true
  worker.js      … /api/* ルーティング+静的ファイル認証ゲート
functions/
  api/auth.js・api/kasc.js・api/data/  … 認証・保存API(Cloud Run 版と同一契約)
  api/gemini.js                        … 内蔵AI向け Gemini プロキシ(サーバーキー注入)
  api/capabilities.js・health.js       … 能力通知 {tier:"workers"}・起動確認

worker.js は functions/api/*・functions/_lib/* のハンドラをそのまま再利用します。二重実装ではありません。

POST /api/gemini は内蔵AI(ブラウザ)向けの薄いキー隠蔽プロキシで、ブラウザの generateContent リクエストにサーバーキー(wrangler secret put GEMINI_API_KEY)を注入して Gemini へ転送します。推論ループ・地図操作はブラウザの内蔵AIが担うため、サーバー側にエージェント実装はありません。BYO キーがあるユーザーはブラウザから直接 Gemini を呼ぶためプロキシは使いません。ANTIGRAVITY_TOKEN(Bearer 必須化)・GEMINI_MODELS(許可モデル・カンマ区切り)・ANTIGRAVITY_RATE_LIMIT(KV バインド時の IP 毎時間制限)で制御できます。

認証前に公開されるのはログイン画面に必要な最小限のみです(index.html・styles.css・favicon.ico・auth-*.js・auth-methods.json・i18n.js・i18n/・PLUGIN/auth-*/)。それ以外のファイル(app.js・projects/・DATA/ 等)はすべて未認証では 401 になります。

デプロイ手順

以下の手順はリポジトリルートで python run-workers.py を実行すると自動化できます(ログイン確認・KV/R2 バインド記入・secret 確認・control=4 設定・deploy・簡易検証まで。control はデプロイ後に 0 に戻します。未ログイン時の wrangler login とパスワード入力のみ手動です)。

前提:wrangler(Cloudflare の CLI)が使えること。初回のみ wrangler login でブラウザ認証しておきます。

  1. KV / R2 を用意します(Pages ですでに作成済みならこの手順はスキップ。同じものをバインドし直すだけでデータ移行は不要です)。
    cd workers
    wrangler kv namespace create KASUGAI_KV    # → 発行された id を控える
    wrangler r2 bucket create kasugai-data     # → バケット名を控える
    作成済みなら wrangler kv namespace list / wrangler r2 bucket list で id・バケット名を確認できます。
  2. workers/wrangler.toml にバインドを書きます。[[kv_namespaces]] / [[r2_buckets]] のコメントを外して、手順1の id・バケット名を記入します。ユーザーIDを admin から変える場合は [vars] の KASUGAI_AUTH_USER もここで編集します。
  3. パスワードをシークレット登録します(wrangler.toml には書きません)。
    wrangler secret put KASUGAI_AUTH_PASS
    値は引数には書かず、コマンド実行後の対話プロンプトで入力します。
    Enter a secret value:          ← ここでパスワードを打ち込んで Enter
    ✨ Success! Uploaded secret KASUGAI_AUTH_PASS
    • 入力中は画面に何も表示されません(パスワード入力と同じ)。貼り付けも可
    • 対話式なのは、端末の履歴にもファイルにも値を残さないためです
    • 登録済みかは wrangler secret list で確認できます(名前だけ出て値は読み出せません)。間違えたら同じコマンドで上書きします
    • ダッシュボードからも設定できます:Worker → Settings → Variables and Secrets → Add(Type: Secret)
  4. web/auth-methods.json の control を 4 にします(このファイルは静的アセットとして一緒にデプロイされます)。
  5. デプロイします。
    wrangler deploy
    Pages の --project-name や配信ディレクトリのような引数は不要です。wrangler.toml が宣言的な設定ファイルになっており、以下がそこに書かれています。
    Pages のコマンド引数Workers での相当設定
    --project-name <プロジェクト名>wrangler.toml の name = "kasugai-canvas"
    web(配信ディレクトリ)[assets] の directory = "../web"
    functions/(自動検出)main = "worker.js"
    初回 deploy で name の Worker が自動作成され、以降は同名 Worker の更新になります。
  6. 動作確認します。https://kasugai-canvas.<アカウント>.workers.dev を開き、ログイン画面 → ID/PASS でログインできることを確認します。未ログインで app.js 等に直接アクセスして 401 になることも確認すると確実です。

再デプロイの目安:

  • web/・workers/・functions/ のファイルを変更した → wrangler deploy を再実行
  • secret(パスワード)を変えた → wrangler secret put のみ(再デプロイ不要・即反映)
  • KV の中身(.kasc)を更新した → デプロイ不要(インスペクターの「適用」や wrangler kv key put で即反映・伝播は最大60秒)

.kasc の登録・R2 データ・r2:// 記法は 3 のページと同じです。

Pages(方式3)との設定の違い

クライアント側(web/・認証プラグイン・API 呼び出し)は方式3と完全に共通で、違いはサーバー側のデプロイ・設定方法だけです。functions/api/* のハンドラも worker.js が import して再利用するため、API 実装の二重管理はありません。

項目Pages(方式3)Workers(方式4)
デプロイ先 Pages プロジェクト
wrangler pages deploy web(ルートで実行・functions/ を自動検出)
Workers プロジェクト
cd workers && wrangler deploy
KV/R2 バインド Pages → Settings → Bindings → Functions で GUI 設定 workers/wrangler.toml の [[kv_namespaces]] / [[r2_buckets]]
環境変数・シークレット Pages → Settings → Environment variables(Production/Preview 別) 非秘密は wrangler.toml の [vars]、パスワード系は wrangler secret put
静的ファイル 認証なしで公開(無料・無制限) run_worker_first = true で全リクエスト認証ゲート(Worker のリクエスト枠を消費)
セッション 署名トークンのみ(?token= / Bearer) HttpOnly Cookie(kasugai_session)+署名トークン
デフォルトドメイン *.pages.dev *.workers.dev
control 値 3 4(同じ auth-cloudflare プラグインを使用)

Pages からの移行手順

KV 名前空間・R2 バケットはアカウント配下のリソースなので、データ移行は不要です。同じものを Worker にバインドし直すだけです。

  1. Pages プロジェクトの Settings → Bindings で KV 名前空間 ID・R2 バケット名を確認し、workers/wrangler.toml の [[kv_namespaces]] / [[r2_buckets]] に転記します(wrangler kv namespace list / wrangler r2 bucket list でも確認可)。
  2. シークレットを再登録します。値は Pages から読み出せないため再入力です(忘れた場合は新しいパスワードを登録すればよく、既存トークンが無効化されるだけです)。
cd workers
wrangler secret put KASUGAI_AUTH_PASS
wrangler secret put KASUGAI_TOKEN_SECRET   # Pages で設定していた場合のみ
wrangler deploy
  1. https://kasugai-canvas.<アカウント>.workers.dev でログイン・/api/data/* の動作を確認します。
  2. web/auth-methods.json の control を 4 にして再デプロイします。
  3. カスタムドメインを Pages に付けている場合は Worker の Settings → Domains & Routes で付け替えます(同時に1箇所にしか向けられません)。動作確認が済むまで Pages プロジェクトは残しておけば切り戻し可能です。

無料枠の消費

  • 全リクエストが Worker 呼び出しとして無料枠(10万回/日)を消費します — 静的ファイル・ログイン画面も含む
  • 起動時に数十ファイルを読む構成のため、少人数利用なら十分ですが不特定多数への公開には向きません
  • KV/R2 のオペレーション枠は別途あり(R2 読み出し 1,000万回/月 等)

資産ごとの秘匿状況

資産未ログインの第三者ログイン済みユーザー
ID/PASS ✅ 秘匿 ✅ 秘匿
環境変数(secret)にのみ存在し、照合は Worker 内で実施。ブラウザには合否とトークンしか返りません。ただし推測可能な値は総当たり・推測でログインされ得ます。
.kasc 設定(KV) ✅ 秘匿
/api/kasc の認証ゲート内
❌ 全量が見える
ログイン時に全プロジェクト分を一括取得
HTML/JS/CSS(アプリ本体) ✅ 秘匿
未ログインは 401
❌ 見える
未ログインで公開されるのはログイン画面に必要な最小限のみ(index.html・styles.css・auth-*.js・i18n.js・i18n/・PLUGIN/auth-*/)。app.js・projects/・DATA/ 等はすべて 401 です。
データ(web/)
URL が公開情報から分かる
✅ 秘匿
未ログインは 401
❌ 見える
データ(web/)
URL が非公開・推測困難
✅ 秘匿
未ログインは 401
❌ 見える
方式3 との違いはここです。Worker が全リクエストを検査するため、URL が公開・推測可能かどうかに関係なく、未ログインでは静的ファイルは一切取得できません(obscurity に依存しない実際の認証ゲート)。
データ(R2・r2:// 経由) ✅ 秘匿
署名トークン必須
◐ 取得可
セッション Cookie / トークン付き /api/data/* 経由
セッションは HttpOnly Cookie(kasugai_session・SameSite=Strict・12時間)で管理され JS からは読み取れません。ただし r2:// の書き換えにより /api/data/...?token=… の URL にトークンが現れるため、ログイン済みブラウザのデベロッパーツールからは読み取り得ます。

✅ 秘匿 ◐ 条件付き ❌ 公開 ——「ログインした人」からは .kasc・データ・アプリ本体はすべて見えます。秘匿が効くのは未ログインの第三者に対してです。

セキュリティ上の注意

  • 保護できるもの:静的ファイルすべて(HTML/JS/CSS/DATA/ 等)、.kasc、R2 内の秘匿データ
  • 保護できないもの:公開許可リストのファイル(ログイン画面系)、PLUGIN/auth-*/ の内容(ID/PASS を直書きするプラグインの中身は見えます — 本番では cloudflare 系のみ使用してください)
  • セッションは HttpOnly Cookie(kasugai_session・SameSite=Strict・12時間)で管理され、JS から読み取れません
  • Cloud Run で同様の全ゲート構成を取る場合は 6. Cloud Run 認証 — cloudrun-gate(control: 6)、組織アカウント運用ができる場合は control: 7(Cloud IAP)があります