MeetingBaaSにあなたが所有するオブジェクトストレージを指定すれば、録画も文字起こしも音声チャンクもlogも、すべてそちらに保存されます。2つのcredential、実効性のあるアクセス確認、そして引き換えに何を手放すのかの率直な説明。

AAmr El Shimy
··10 min read
Bring Your Own Storage:録画を私たちのインフラに残さない

「録画はどこに保存されるのですか?」——エンタープライズの商談を止めるのは、この質問です。銀行や病院、あるいはデータレジデンシー要件のもとで運用している企業にとって、「当社のバケットに、暗号化して保存しています」はコンプライアンス部門に持っていける答えではありません。

そこで、バケットを私たちに預けられるようにしました。それ以降にbotが生成するすべてのアーティファクト、つまり録画、音声チャンク、文字起こし、スクリーンショット、logは、あなたが所有するストレージに、あなたが発行し、いつでも失効させられるcredentialで書き込まれます。

Bring Your Own Storageは、従量課金制を含むすべてのプランでご利用いただけます。ストレージ機能のアップグレードゲートはありません。

GET    /v2/storage-config          your current configuration, 404 if unset
PUT    /v2/storage-config          set or replace it
POST   /v2/storage-config/test     re-run the access check
DELETE /v2/storage-config          back to MeetingBaaS storage

または、dashboard の「設定」→「ストレージ」からも同じ操作が可能です。セッション認証と同じ4つのハンドラーが使用されます。

2つの認証情報:物理的な保存先による分割

これは私が最も強く主張する設計上の決定ですので、まずここから始めます。

1つではなく、2つのアクセスキーペアを指定します。

権限保存場所
ingestPutObject, PutObjectTagging, AbortMultipartUpload録画 bot に渡されます。ネットワーク外に出ます。
serviceGetObject, ListBucket, PutObject, DeleteObjectAPI サーバーのみ。外部に出ることはありません。

ingest キーは、ミーティングに関わる唯一の認証情報です。ヘッドレスブラウザを実行するポッド上で通話中に使用されますが、これはこのシステム内で認証情報が置かれる最もリスクの高い場所です。オブジェクトの書き込みは可能ですが、読み取り、一覧表示、削除はできません。ポッドが侵害された場合、特定のプレフィックスに不正なデータを追加できる程度に過ぎません。

service キーはそれ以外のすべての処理を担います。署名付きURLを通じた録画の提供、文字起こしの書き込み、保持期間終了時のアーティファクトの削除などです。

ingest キーは bot ポッドに渡され書き込みのみ可能。service キーは API サーバー上に留まり、読み取り・書き込み・削除が可能

ここで正確に述べておきたいことがあります。service キーは読み取り専用ではなく、そのように説明することは誤りです。API が実際に書き込みと削除の両方を行うため、service キーもそれを担います。この分割によって得られるのは、リスクの高い場所に置かれる認証情報が権限の弱いものになるということです。これはブラスト半径の実質的な削減であり、最小権限の原則とは異なります。どちらを得ているかを正確にお伝えしたいと思います。

設定方法

{
  "endpoint": "https://s3.eu-west-3.amazonaws.com",
  "region": "eu-west-3",
  "force_path_style": false,
  "artifacts_bucket": "acme-meeting-artifacts",
  "audio_chunks_bucket": "acme-meeting-audio-chunks",
  "logs_bucket": "acme-meeting-logs",
  "allow_transient_spill": false,
  "ingest_access_key_id": "AKIAIOSFODNN7EXAMPLE",
  "ingest_secret_access_key": "...",
  "service_access_key_id": "AKIAI44QH8DHBEXAMPLE",
  "service_secret_access_key": "..."
}

3つのバケット名はすべて同一のバケットにすることができます。オブジェクトキーにはいずれにしても bot の ID がプレフィックスとして付与されるため、衝突は発生しません。force_path_style は MinIO、Ceph、およびほとんどのセルフホスト型ゲートウェイで必要ですが、AWS と Scaleway では不要です。

endpoint は公開 HTTPS である必要があり、認証情報や query string を含めてはなりません。アーティファクトは短期間有効の署名付きURLを通じて提供されるため、バケットはプライベートにすべきですが、インターネットからアクセスできる必要があります。文字起こしプロバイダーは、プロキシを経由せず署名付きURLからオーディオを直接取得するためです。

アーティファクトバケットに対して、dashboard のオリジンを許可してください。dashboard はアーティファクトを取得してトランスクリプトのJSONを読み込むため、endpoint に対するクロスオリジンの読み取りが発生します。CORSルールがない場合、ブラウザはレスポンスを破棄し、何もレンダリングされません。dashboard のオリジンに対して GETHEAD を許可するのがルールの全体です。PutBucketCors は service キーが持つオブジェクト権限より上位のレイヤーにあるため、オーナーレベルの認証情報が必要です。service キーが Forbidden を返すのは、スコープが正しく機能している証拠であり、バグではありません。

設定を読み返すと、両方のアクセスキーIDが確認できるため、どの認証情報が使用されているかを把握できます。シークレットは一切表示されません。設定を置き換える場合は両方のシークレットを再入力する必要があります。既存の内容を表示することができないためです。

アクセスチェックについて、そしてそれが形式的なものでない理由

PUT は保存前に設定を検証します。単に ListBuckets を呼び出して終わりにするのではありません。

ingest キーは各バケットにマーカーオブジェクトを書き込みます。次に service キーがそのオブジェクトを読み取り、書き込み、削除します。

各操作は実際に本番環境でそれを行う認証情報によってテストされるため、プローブは本番環境と同様に失敗します。4つすべてが重要です。ingest のアップロードは録画の到達方法、service のアップロードは文字起こしの書き込み方法、読み取りはアーティファクトの提供方法、削除は保持期間の満了処理にそれぞれ対応しています。

特に有用なのは、書き込みと読み取りを分離している点です。マーカーは一方の認証情報によって書き込まれ、もう一方によって発見される必要があります。これにより、誰もテストしない種類の障害を検出できます。それぞれが完全に有効な2つのキーペアが、異なるバケットまたは異なるアカウントを指している場合です。世界中の単一認証情報によるヘルスチェックはすべてそのような設定でもパスし、その結果、録画が失われることになります。

これがなければ、バケット名の誤記に最初に気づくのは、ポッドのローカルディスクが消去された後の実際のミーティング終了時のアップロード失敗です。チェックが失敗した場合、汎用エラーではなくプロバイダー自身のメッセージをそのまま表示します。「ingest キーがアーティファクトバケットに書き込めない」という情報がこのチェックを実行する価値のすべてだからです。

POST /v2/storage-config/test を使っていつでも再実行できます。キーのローテーションやバケットポリシーの変更後に使用するのに適しています。

このチェックが意図的に検出できないものが1つあります。CORSです。プローブはCORSが適用されないサーバー側から実行されるため、バケットはすべての操作をパスしながら、ブラウザへの録画の提供を拒否することがあります。このギャップは私たちが対処すべき課題であり、それが解決されるまでは、dashboard のオリジンを許可する注意書きが、緑のチェックマークと何も表示されない dashboard の間に立つものです。

その他すべてが従う不変条件

bot は常に書き込まれたストレージを参照します。チームが現在設定しているものを参照することはありません。

bot がディスパッチされると、その時点で有効なストレージ設定が bot レコードにスタンプされます。その bot に対するすべての読み取り、署名付きURL、削除はチームではなくスタンプを通じて解決されます。

これは実装の詳細のように聞こえるかもしれませんが、この機能を安全に有効化できる理由であり、4つの重要な結果が直接導かれます。

設定を変更すると新しい行が挿入され、古い行は無効化されます。 既存の行は決して上書きされません。行を変更すると、既存のすべての bot のアーティファクトが存在しないバケットにサイレントにリダイレクトされてしまいます。

DELETE /v2/storage-config はフラグを切り替えるだけです。 どちらの側でも何も削除されません。ハードデリートを行うと、古い bot がまだ必要としている認証情報が失われ、アカウント内のすべての録画が孤立します。

解決は設定が有効かどうかを意図的に無視します。 無効化すると新しいアーティファクトがバケットに送られなくなります。既にそこにあるものが孤立してはなりません。

スタンプされた設定が見つからない場合は、私たちのバケットにフォールバックするのではなくエラーを返します。 フォールバックするとアーティファクトが存在しないと報告され、保持削除の際に成功を報告しながらデータをサイレントに残したままにします。大きな失敗が正しい動作です。

実用的な説明をすると、設定の追加・変更・削除はいつでも可能です。古い録画はその間も機能し続けます。古いアーティファクトが読み取れなくなる唯一の原因は、あなた側で私たちのアクセスを取り消すことであり、それはあなたが判断することで、期待通りに動作します。

実際に行うトレードオフ

allow_transient_spill は、独自ストレージを使用するチームではデフォルトで false になっており、これはプラットフォームのデフォルトとは逆です。これが意味することを完全に説明します。この機能にはコストが伴う唯一の箇所だからです。

通常、アップロードが失敗した場合、アーティファクトは私たちのネットワークボリュームにミラーリングされ、後で調整ジョブによってプッシュされます。このパスはミーティング全体をコピーします。動画、音声、話者分離の出力、すべてのチャンクが私たちのインフラ、私たちのアカウントにコピーされます。

これはまさに、データレジデンシーの要件を持つお客様が避けようとしているものです。さらに悪いことに、レジデンシーのお客様はプラットフォームのお客様よりもこのパスをより多く踏むことになります。バケットが私たちのネットワーク外にあり、多くの場合、まったく異なるプロバイダーにあるためです。

そのため、allow_transient_spill: false を設定すると、すべての bot タイプとコンシューマーでフォールバックが無効化されます。リトライを使い切ったアップロードは失敗として報告され、アーティファクトは失われます。

これがトレードオフです。耐久性と引き換えにデータレジデンシーを得ます。SDKのデフォルトの3回ではなく6回のアップロード試行を bot のアップロードクライアントに与えることで部分的に緩和していますが、バケットへの持続的な障害は録画を失うことになります。

録画を保持することを優先する場合は true に設定してください。dashboard には、フリップ時に何を諦めるかを正確に説明する警告が表示されます。無意識にチェックを入れてしまうようなものであってはならないためです。

録画が失われ、バケットで障害が発生していた場合は、まずここを確認してください。

できないこと

後から発見することのないよう、4つの事項を最初に明記します。

既に録画されたものは移動されません。 移行機能はありません。すべての bot は書き込まれた場所を参照し続けます。これによりこの機能を安全に有効化できますが、履歴は私たちのバケットに残ることになります。

バケットごとのプレフィックス設定はありません。 キーは <bot_uuid>/… に固定されています。

これだけでデータレジデンシーを完全に保証することはできません。 bot ポッドはミーティング中、ローカルディスクに録画を保持します。これが閉じるのは、録画が共有 MeetingBaaS インフラ上に保存されるパスのみです。

Dashboard のアセットは私たちのバケットに残ります。 ロゴ、ユーザーアバター、サポートの添付ファイルはミーティングデータではなく、対象外です。

ロールバック

DELETE /v2/storage-config はいつでも安全に実行できます。新しい bot はすぐに私たちのストレージに戻ります。既存の bot は引き続きあなたのバケットを参照し、正常に動作します。

居住要件に関する作業を進めており、どのコンポーネントが何に関わっているかを正確に知りたい場合は、お問い合わせください。ここでお伝えした内容と同様の回答をいたします。

関連ブログstorage