付録:最小限のデータ構造(マニフェスト/チャンク/状態)

この付録では、「並列チャンク分割 + 再開可能な転送 + 冪等な再試行」のための、最小限のデータ構造の推奨事項を示します。 目標は、複雑なトランザクションを使わずに、高スループットの並行処理と、障害後の確実な復旧を実現することです。

一般原則

  • 大きなオブジェクトと小さな状態:チャンクとマニフェストは大きなオブジェクトとしてオブジェクトストレージに保存し、状態は小さく、ステートストアに保存します。
  • 一意なキーと冪等性:冪等な再送のため、チャンクは(transferId、fileId、chunkIndex)で一意に特定できなければなりません(MUST)。
  • 復旧可能性:復旧時に完了済みの部分をスキップできるよう、状態は「完了済みの集合」を表現しなければなりません(MUST)。
  • 機微な情報を漏らさない:オブジェクトキーや状態には、メールアドレスや元のファイル名などの機微なフィールドを埋め込まないようにするべきです(SHOULD)(これらを暗号化するかどうかは、プライバシーポリシーによります)。

A.1 マニフェストの最小限のフィールド

マニフェストは、受信者がダウンロードと再構成を行う際の「唯一の入り口」です。最小限の推奨事項は次のとおりです。

  • manifestVersion:MUST。互換性を保ったアップグレードに使用します(例:1)。
  • transferId:MUST。転送セッションの一意の識別子。
  • createdAt / expiresAt:SHOULD。ライフサイクルの管理とUIでの表示に使用します。
  • policy:SHOULD。ポリシーの概要(ダウンロード回数の上限、パスワードの要否、完了前の共有を許可するかどうかなど)。
  • files[]:MUST。ファイル一覧の記述(最低限、ファイルサイズとチャンクの範囲)。
  • chunking:MUST。chunkSizeとchunkCountの算出方法、またはファイルごとのchunkCountを含めます。
  • objectKeyRule:MUST。オブジェクトキーを(transferId、fileId、chunkIndex)から導出するか、明示的な対応表を用意します。

A.1.1 files[] の最小限のフィールド

  • fileId:MUST。ファイルの一意の識別子(ファイル名を一意のキーとして使わないでください)。
  • size:MUST。バイト単位のサイズ。
  • mime:MAY。表示やダウンロード時の案内に使用します。
  • name:MAY。厳密なゼロナレッジや情報漏えいの最小化を求める場合は、nameを省略するか、暗号化した名前を保存します。
  • chunkCount:MUST。このファイルのチャンク数。
  • chunkOffset:MAY。複数のファイルでグローバルなchunkIndexを共有する場合はオフセットが必要です。そうでなければ省略できます。

A.1.2 完全性と検証のフィールド(任意ですが推奨)

  • chunkHashes[]:SHOULD。チャンクごとの検証(ハッシュ、長さ、etagのいずれか、またはその組み合わせ)。
  • fileHash:MAY。ファイル全体のチェックサム(ダウンロード後に検証)。
  • ciphertextLength:MAY。暗号文レベルでの長さの整合性チェック(平文は不要です)。

A.2 チャンクオブジェクト:最小限の制約

  • 一意のアドレス指定:チャンクは、(transferId、fileId、chunkIndex)で一意に特定できなければなりません(MUST)。
  • 冪等なアップロード:同じチャンクを再アップロードしても、最終的な状態が壊れてはなりません(MUST NOT)(上書きしても拒否してもかまいませんが、挙動は一貫している必要があります)。
  • 最小限のメタデータ:サーバーは、可観測性とトラブルシューティングのために、暗号文の長さ、書き込み時刻、etag/バージョンなどだけを記録してもかまいません(MAY)。

A.2.1 オブジェクトキーの規則(例)

  • /transfers/{transferId}/chunks/{fileId}/{chunkIndex}
  • /transfers/{transferId}/manifest

制約:オブジェクトキーは、transferIdのプレフィックスによる一括クリーンアップに対応していなければなりません(MUST)。また、業務上の機微な情報を含めないようにするべきです(SHOULD)。

A.3 状態レコード:最小限のフィールド

状態は「アップロード/ダウンロードの進捗と復旧」を表します。小さく、読み書きが速いものにする必要があります。

  • transferId:MUST。
  • status:MUST。推奨される値:UPLOADING / READY / DELETED / EXPIRED。
  • uploadedSet:MUST。完了済みチャンクの集合。ビットマップやレンジセットで圧縮するべきです(SHOULD)。
  • uploadedBytes:SHOULD。進捗の表示とクォータの確認に使用します(チャンクから導出することもできますが、保持しておくほうが高速です)。
  • downloadCount:MAY。ダウンロード回数の上限を適用する場合は、記録してアトミックに更新する必要があります(詳細はストレージによって異なります)。
  • expiresAt:SHOULD。有効期限の適用とバックグラウンドでのクリーンアップに使用します。

A.3.1 復旧APIの最小限の出力

再開可能な転送では、サーバーは次の情報を返せるべきです(SHOULD)。

  • 転送のステータス(UPLOADING/READY/DELETED/EXPIRED)
  • uploadedSet(完了済みチャンクの集合)
  • ポリシーの概要(例:クォータ超過、期限切れ、アップロードの続行が許可されているかどうか)

補足:セキュリティとプライバシーのホワイトペーパーとの役割分担

  • この付録では、転送と保存に必要な「構造と制約」のみを説明します。
  • 暗号化に関するフィールド、鍵素材の受け渡しや導出の方法、認証失敗時のフェールクローズの挙動については、セキュリティとプライバシーのホワイトペーパーを参照してください。