60_利用制限と運用ポリシー
本章では、filix-shadowwork-api の運用上の利用制限(BAN/凍結、レート制限、悪用対応)と、関連する運用ポリシーを定義する。
本章は「機能仕様」ではなく、サービス運用として守るべきルールと、API実装が満たすべき前提(制御点)を示す。
CORS / Cookie 戦略
全体方針
- フロント(Shadowwork Navigator)と API は別ドメインで運用される(
https://shadowwork-navigator.comとhttps://api.shadowwork-navigator.com)。 - JWT は Cookie で送信するため、CORS で
credentialsを有効化する。 - 認証情報を含むため、許可 Origin は allowlist で明示的に制限する。
許可Origin(CORS Allowlist)
本番環境
https://shadowwork-navigator.com(完全一致のみ)
開発・Preview
- 原則として
*.pages.devは許可しない(セキュリティと Cookie 運用の相性が悪い)。 - どうしても必要な期間だけ、例外として1件だけ allowlist に追加可能(例:
https://shadowwork-navigator-9lt.pages.dev)。 - 追加時も ワイルドカード(
*.pages.dev等)は禁止。 - ドメイン移管時は手動で allowlist を更新する。
独自ドメイン導入時
- 本番 allowlist に新規ドメインを追加し、環境変数で管理する。
CORS Response Headers
すべてのエンドポイントで以下を返す:
Access-Control-Allow-Origin: https://shadowwork-navigator.com(許可Originのみ)
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Max-Age: 86400
Vary: Origin
重要な点:
- Access-Control-Allow-Origin: * は禁止(credentials が使えない)
- Access-Control-Allow-Credentials: true が必須(Cookie 送受信を許可)
- Vary: Origin は必須(キャッシュの重複を防止)
- Origin ヘッダがあるリクエストは allowlist と完全一致で判定し、不一致時は 403 FORBIDDEN を返す。
- ALLOWED_ORIGINS が空の場合は、Origin ヘッダ付きリクエストを許可しない(fail close)。
- Origin ヘッダが無いリクエスト(サーバー間通信/CLI等)は CORS 判定対象外。
クライアント実装
フロントエンドの fetch 呼び出しで credentials: include を指定:
fetch('https://api.shadowwork-navigator.com/api/thread/start', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
credentials: 'include', // ← Cookie の送受信を有効化(重要)
body: JSON.stringify({ /* ... */ })
});
今後の課題
- クロスサイト Cookie(SameSite=None; Secure)の運用
ドメイン統一(Pages 配下への API 移設)またはクロスサイト対応の判断は、ブラウザ仕様の動向を見た上で決定する。 クロスサイトにする場合、CORS の地雷(Preflight, credentials, Third-party Cookie)が増えるため、慎重な設計が必要。
対象と範囲
対象
- APIの利用者(通常ユーザー)
- 管理操作(管理者・運用者)
- 外部サービス(Stripe Webhook 等)
範囲外
- 顧客対応の手順書(問い合わせテンプレート等の詳細)
- 法務文書(利用規約・プライバシーポリシー)
基本方針
-
サービス継続を優先する
悪用や過負荷が発生しても、全体停止ではなく対象を限定して影響を抑える。 -
誤検知を前提とする
制限は「復旧可能」であることを基本とし、永久BANは最終手段とする。 -
透明性と最小限の情報開示
ユーザーに通知する場合も、セキュリティ上不利になる情報(閾値、内部判定ロジック等)は開示しない。 -
監査可能性
重要な制限・解除・管理操作は監査できる形で記録する(PII/本文は含めない)。
利用制限(BAN/凍結/アカウント制限)
目的
- 明確な規約違反や悪用に対する抑止
- 自動化された攻撃・スクレイピング・過負荷の遮断
- サービス品質(他ユーザーへの影響)の維持
制限の粒度
以下の粒度を組み合わせて運用できるようにする。
- ユーザー単位(user_id)
- IP単位(必要な場合)
- トークン単位(認証方式採用後)
- エンドポイント単位(特定APIのみ拒否)
制限の種類(例)
- 凍結(Suspend): 全機能停止(ログイン後のAPIも拒否)
- 部分制限(Restricted): 一部機能のみ拒否(例: LLM系、書き込み系)
- 一時制限(Temporary Block): 一定期間のみ拒否(レート制限強化など)
制限の判定材料(例)
- 過剰なリクエスト頻度(レート制限超過)
- 不正な入力パターン(自動化疑い、反復投稿等)
- 認証失敗の多発(ブルートフォース疑い)
- Webhook を模した不正アクセス(署名検証失敗の反復)
- 管理APIへの不正アクセス
制限理由や閾値は運用上の秘匿情報であり、本章では「類型」までを扱う。
レート制限方針
目的
- 過負荷・DoS・自動化の影響を局所化する
- コスト(LLM等)を制御する
適用単位
- 基本は user_id 単位
- 必要に応じて IP 単位を併用する(匿名アクセス、認証失敗多発など)
制限対象の優先順位(例)
- コストの高い処理(LLM関連:
/api/thread/chat,/api/llm/respond,/api/llm/ping) - 書き込み系(
/api/thread/message,/api/thread/start,/api/run/start等) - 管理API(攻撃対象になりやすい)
レスポンス
- 制限時は 429 を返す。
- エラー形式は
20_API仕様の共通エラー形式に従う。
例:
{
"ok": false,
"error": { "code": "RATE_LIMITED", "message": "リクエストが多すぎます。" }
}
外部APIタイムアウト方針
目的
- 外部依存(OpenAI / Stripe / Memberstack)のハングや遅延時に API を早期復帰させ、ワーカー占有を防ぐ。
方針
- 外部API呼び出しは共通タイムアウトを適用する。
- 環境変数
EXTERNAL_API_TIMEOUT_MSで調整し、未設定または不正値時はデフォルト10000msを使用する。 - タイムアウト時は共通エラー形式で
502を返す。
悪用対応(Abuse Response)
想定する悪用
- 自動化による大量投稿(スパム)
- クローリングによるデータ収集
- 認証情報の総当たり
- 管理APIの探索・攻撃
- Webhook 偽装による状態改ざん
対応の段階(運用)
- 検知: 429/401/403 の急増、特定IP/ユーザーの集中
- 緩和: レート制限強化、特定エンドポイントの一時遮断
- 隔離: 対象ユーザー/IPを一時凍結
- 復旧: 正常化後に段階的に解除
- 恒久対策: 実装改善(認証強化、検証強化、閾値調整)
管理操作の取り扱い
対象
/api/admin/set_paid等の管理系エンドポイント
方針
- 管理操作は原則「例外対応」であり、日常運用で多用しない。
- 管理操作を許可する環境・認証方式は
50_セキュリティと整合させる。 - 管理操作の実行は監査可能とする(誰が・いつ・何を)。
ログと監査
目的
- 障害・不正の切り分け
- 利用制限の妥当性検証
- コストと負荷の把握
ログに残す(例)
- リクエストメタ情報(時刻、エンドポイント、結果コード、レイテンシ)
- 制限の発動/解除(対象、種別、理由カテゴリ)
- 管理操作(操作種別、対象、成功/失敗)
ログに残さない
- ユーザー入力の平文本文(
/api/thread/chat入力、復号後本文等) - Secrets(APIキー、署名秘密)
- 不要な個人情報
ユーザーへの通知(方針)
- 制限が発生した場合、ユーザーへの通知は「最小限の説明」に留める。
- 例: 「不正利用の可能性があるため一時的に制限しています」
- 詳細な判定ロジックや閾値は開示しない。
データ保全と削除(運用観点)
- BAN/凍結は原則として「アクセス制御」であり、即時のデータ削除は行わない。
- 法務/規約/ユーザー要求に応じた削除が必要な場合は、別途運用手順として定義する。
参照
20_API仕様: 共通エラー形式、ステータス40_課金と利用権限: paid 更新の運用(反映遅延等)50_セキュリティ: 認証、Secrets、Webhook 署名検証、管理API保護