プロンプトとコンテキスト
このシステムデザインの質問では、一時的なクレデンシャルのライフサイクルと認可境界がテストされます。課題は、単にオブジェクトストレージの署名APIをラップすることではありません。情報漏洩、失効、キーローテーション、およびマルチリージョンアクセスが発生しても、リンクの権限を限定し、制御可能な状態に保つことです。
面接官が評価するポイント
- 署名付きURLがテナント、オブジェクト、メソッド、バージョン、レンジ、有効期限にバインドされているか。
- 署名、リアルタイム認可、失効、およびストレージ権限が明確に区別されているか。
- キーローテーション、短いキャッシング、CDN配信、レート制限、および監査フローが設計されているか。
- 漏洩、リプレイ、クロックスキュー、リージョン障害、および失効遅延のトレードオフが説明されているか。
確認すべき明確化の質問
ダウンロードとアップロードの違い、単一オブジェクトとバッチ、Rangeおよびマルチパートの要件、最大有効期間、秒単位の失効、およびCDNの関与を確認します。また、テナントの分離、監査ログの保持期間、キー管理、マルチリージョン復旧、およびオブジェクトバージョンのセマンティクスについても質問します。
30秒の回答フレームワーク
認可サービスはまず呼び出し元を検証し、次にテナント、オブジェクトバージョン、操作、条件、および短い有効期限にバインドされたURLに署名します。署名は正規化されたリクエストとキーバージョンを対象とし、ストレージまたはエッジがそれを検証します。高リスクな失効には、短いTTL、拒否リスト、またはバージョン失効マーカーを使用します。URLは必要な権限のみを付与し、イミュータブルな監査イベント、リプレイ検出、レート制限、およびキーローテーションによってリスクを封じ込めます。
ステップバイステップの詳細解説
1. クレデンシャルと権限モデルの定義
テナント、オブジェクトキーまたは推測不可能なID、バージョン、許可されたメソッド、バイトレンジ、content-typeの制約、発行者、有効期限、およびキーバージョンを含めます。アップロードURLには、サイズ、チェックサム、および宛先プレフィックスの制限も設定します。サーバーは署名前にライブでオブジェクトの認可を実行し、クライアントがパラメータを編集して権限を拡大できないようにします。
2. 署名および検証パスの選択
メソッド、パス、クエリパラメータ、重要なヘッダー、および有効期限をカバーする、ストレージ互換のHMACまたは非対称署名を使用します。空白、エンコーディング、およびパラメータの順序を正規化(Canonicalize)します。検証側は、時間枠、キーバージョン、署名、および条件をチェックします。すべての認可判断を自己完結型のURLに詰め込むのではなく、機密性の高い操作には引き続きリアルタイムのチェックを使用します。
3. 失効、ローテーション、およびリプレイ防御の設計
短い有効期限により、漏洩時の影響を抑えます。価値の高いリンクについては、RedisまたはエッジルールでトークンID、オブジェクトバージョンの失効、またはテナントの拒否リストを保持できます。キーローテーション中は、最も長いURLの有効期間が終了するまで古いバージョンを保持し、その後に削除します。1回限りのアップロードにはノンス、オブジェクト状態、および完了マーカーを要求できます。繰り返しのダウンロードは明示的なビジネスロジックに従います。
4. ストレージ、CDN、および障害のスケール
発行はステートレスに保ち、メタデータと失効情報は高可用性ストレージに配置します。アプリケーションサーバーを経由させず、オブジェクトのバイトをストレージまたはCDN経由で直接送信します。CDNポリシーには署名と権限の境界を含める必要があり、あるテナントのプライベートなレスポンスが別のテナントによって再利用されないようにします。キー管理または失効ストレージが利用できない場合は、新規発行および高リスクアクセスに対してフェイルクローズ(fail closed)にし、すでに発行済みの低リスクリンクは文書化されたTTLに従って処理します。
5. 監視、レート制限、およびセキュリティ検証
完全なURLクエリをログに記録することなく、発行者、テナント、オブジェクト、メソッド、結果、リージョン、クライアントフィンガープリントのサマリー、および失効理由を監査します。テナント、ユーザー、オブジェクト、およびIPごとに発行レート、合計バイト数、および同時実行数を制限し、異常な再利用を検出します。パラメータの改ざん、有効期限、クロックスキュー、ローテーション、失効遅延、テナント間アクセス、CDNヒット、およびリージョン障害をテストします。
優れた回答例
呼び出し元を検証した後、認可サービスはテナント、不変のオブジェクトバージョン、メソッド、条件、および短い有効期限にバインドされたURLを発行します。署名は正規化されたパス、クエリ、および重要なヘッダーをカバーし、ストレージまたはCDNがそれを検証するため、アプリケーションが大容量ファイルをプロキシすることはありません。高リスクなリンクは、短いTTL、拒否リスト、またはバージョンマーカーによる失効をサポートします。最も長いリンクが期限切れになるまで古いキーを保持します。完全なURLを含めずに発行およびアクセスの結果を監査し、テナントおよびオブジェクトごとにレート制限を行い、改ざん、リプレイ、スキュー、ローテーション、失効、テナント間アクセス、およびCDNの分離をテストします。
よくある間違い
- テナント、メソッド、バージョン、またはアップロード条件を含めず、オブジェクトパスのみに署名すること。
- 恒久的なURLを失効メカニズムとして扱い、漏洩時の封じ込め策を持たないこと。
- ローテーション中に古いキーを即座に削除し、有効なリンクを破損させること。
- CDNでパスのみによってプライベートコンテンツをキャッシュし、署名やテナントを無視すること。
- ログ、アナリティクス、またはエラーメッセージに完全な署名付きURLを書き込むこと。
- 署名の有効性のみをテストし、改ざん、リプレイ、クロックスキュー、および失効遅延のテストを省略すること。
フォローアップの質問と回答
なぜすべての認可をJWTに入れないのですか?
署名付きURLは条件をリソースリクエストにバインドし、ストレージが大容量バイトをプロキシすることなく検証できるようにしますが、リアルタイムの失効システムではありません。高リスクな権限には、依然として短いTTL、バージョン失効、またはリアルタイムチェックが必要です。
失効を数秒以内に有効にするにはどうすればよいですか?
エッジまたは検証側で、非常に短いキャッシュTTLを持つ高優先度の拒否リスト、オブジェクトバージョンマーカー、またはテナント状態をチェックさせます。これにより読み取りと整合性の負荷が高まるため、リスク階層に応じて適用します。
アップロードURLで別のオブジェクトの上書きを防ぐにはどうすればよいですか?
不変キーまたは1回限りのアップロードID、If-None-Match、サイズ、およびチェックサムにバインドします。完了時にテナントとオブジェクトの状態を再チェックし、パスの置き換えや重複した完了を拒否します。
CDNは署名付きURLをキャッシュすべきですか?
キー、ヘッダー、およびTTLによってプライベートなレスポンスが権限境界を越えないようにできる場合にのみ、バイトをキャッシュできます。高リスクまたは非常に短寿命のリソースは共有キャッシュをバイパスし、ヒット率を犠牲にして分離性と制御可能な失効を優先できます。