Edge Functions セキュリティ モデル
関数、そのコード、およびその秘密を非公開に保つルール、および責任を負う場所。
1. キーと役割
| 役割 | キー | できる |
|---|---|---|
anon | 公開キー、ブラウザ内で安全 | 関数を呼び出す |
authenticated | 公開キーとサインインしているユーザーの JWT | ユーザーの ID を使用して関数を呼び出します |
service_role | 秘密鍵、サーバーのみ | すべて: デプロイ、コードとシークレットの読み取り、ジョブ、cron、アラート |
admin | Studio でのコンソール セッション | すべてはスタジオから |
役割はキーとトークンから得られ、プラットフォームが検証します。クライアントはそれを選択できません。公開キーとヘッダー x-aura-role: service_role を使用した呼び出しは、 anonとして関数に到達します。
すべてのルートとその役割は、 HTTP API リファレンスにリストされています。
2. なぜ呼び出しのみが公開されるのか
公開キーは Web またはモバイル アプリで公開されるため、誰でも読み取ることができます。許可されるものは何でも、誰もが許可されます。関数の呼び出しは、そのために設計された 1 つの操作です。呼び出し元が何を実行できるかはコードによって決まります。
関数の 定義 の読み取りは異なります。これには、ソース コードと環境変数が含まれており、多くの場合、これらには秘密が含まれています。ジョブとアラートをリストすると、データが表示されます。ジョブをキューに入れると、クォータに従ってコードが実行されます。これらはどれもパブリックにすることができず、プラットフォームは service_role以外のキーに対して 403 を使用して拒否します。
同じ分割が他の場所にも存在します。 Supabase は、エッジ関数がデフォルトで実行される前にユーザーの JWT を検証し (verify_jwt = true)、その CLI とプラットフォームを通じて関数をデプロイします (docs)。 Firebase は、IAM 権限 (docs) を使用して、Admin SDK を通じて信頼されたサーバー環境からタスクをキューに入れます。 Cloudflare では、ワーカーのみがバインディングを通じてキューに送信できます (docs)。
サービスの以前のバージョンは、任意のキーに対して GET /v1/functions および GET /v1/functions/{name} を応答しました。この修正よりも前のデプロイメントでプロジェクトが実行されていた場合は、関数のコードと変数を公開されたものとして扱い、それらに含まれるシークレットをローテーションしてください。 0.6 へのアップグレードを参照してください。
3. アイデンティティは偽造できない
関数は、 x-aura-role、 x-aura-user-id 、 x-aura-project-idから呼び出し元を読み取ります。プラットフォームはキーとトークンを検証した後にそれらを設定します。
- 呼び出し元はそれらを提供できません。プラットフォームは、ケースに関係なく、呼び出しの
headersで送信されたauthorization、apikey、x-request-id、およびすべてのx-aura-*ヘッダーを破棄します。実際のテストでは、x-aura-role: service_roleと偽造されたauthorizationを使用した呼び出しは、authorizationのないrole: "anon"として関数に到達しました。 - 他のカスタム ヘッダーはそのまま通過します。それらをユーザー入力として扱います。
- ジョブと cron の起動は、ID ヘッダーなしで関数に到達します。これらはユーザーではなくプラットフォームによってトリガーされます。
したがって、本文の値ではなく、 x-aura-role および x-aura-user-idに対して認可します。
4. サンドボックス
プラットフォームが提供するもの:
- 各呼び出しは独自の V8 分離で実行され、独自のメモリ制限と実時間のタイムアウトが設定されます。 1 つの呼び出しでクラッシュまたは無限ループが発生しても、他の呼び出しには影響しません。
- ホストの環境変数は非表示です。実際の実行では
Deno.env.get('PATH')がundefinedを返しました。関数の変数とプラットフォームのAURABASE_*変数のみが存在します。 - あるプロジェクトのコードを別のプロジェクトで読み取ることはできません。そのプロジェクトを提供するサービスには内部トークンが必要です。
- スクリプトを実行できる応答はサンドボックス コンテンツ セキュリティ ポリシーで提供され、関数からの
Set-Cookieおよび CORS ヘッダーはドロップされます。 応答を参照してください。
得られないもの:
- 制限しない限り、送信ネットワークは開いています。
permissions.allow_netが 1 つ以上のホストを列挙している場合、ランタイムはそれ以外のホストへのfetchを拒否します(Requires net access to "host:443")。既定の空のリストは何も制限しません。関数が必要とするホストをすべて列挙してください。プラットフォームを呼び出す場合はプロジェクトの URL も含めます。リストがあっても、ユーザー入力から得た URL は必ず検証してください。 - ログ内の自分自身の秘密は保護されません。 関数が
console.logで書き込むものはすべてランタイムのログに記録されます。 - ユーザーごとの制限はありません。 呼び出しレート制限はクライアント IP ごとに異なります。 1 人のユーザーが関数を数回以上呼び出してはいけない場合は、独自のチェックを追加します。
5. チェックリスト
service_roleキーはサーバーと CI シークレット内にのみ存在します。- ブラウザ バンドルには公開キーのみが含まれています。 SDK は、デフォルトでブラウザーの
service_roleキーを拒否します。 - すべての関数は、機密性の高い処理を行う前に
x-aura-roleをチェックします。 - シークレットは関数の変数であり、
index.tsには決して含まれません。 - 外部 URL を呼び出す関数は宛先を検証します。
- キーをローテーションするには、Studio で新しいキーを作成し、それをシークレットとしてデプロイし、古いキーを取り消します。