Claude Files APIのfile_idセキュリティリスクと対策
Files APIのファイルは、同じワークスペースの全APIキーからfile_id経由でアクセスできます。ユーザー入力のfile_idをそのまま受け取ると他者のファイルを読ませる失敗パターンと、防ぎ方を扱います。
Files APIでアップロードしたファイルは、アップロードしたAPIキーだけでなく、同じワークスペースに属するすべてのAPIキーからfile_id経由でアクセスできます。ユーザーから受け取ったfile_idをそのままAPIに渡す実装は、他のユーザーのファイルを読ませてしまう典型的な脆弱性になります。
Files APIの隔離まわりの数字
隔離の単位
ワークスペース
Message BatchesとSkillsも同じ単位
ワークスペース上限
100個/組織
増枠はアカウント担当に問い合わせ
自動失効の設定幅
1時間〜90日
expires_in_secondsは3,600〜7,776,000秒
1ファイルの上限
500 MB
組織全体では1 TB
Files APIのfile_idはどこまで共有されるか
Files APIとは、ファイルを一度アップロードしてfile_idで繰り返し参照できるAnthropicの仕組みです。アップロードしたファイルは、エンドユーザー・会話・セッションのいずれにも紐づきません。紐づく単位はワークスペースです。ファイル以外では、Message BatchesとSkillsも同じ単位でスコープされます。
同じワークスペースへのアクセス権を持つAPIキーなら、どのキーもそのワークスペースのファイルをfile_idで参照できます。組織のロールでAPIアクセスが許可されているユーザーとサービスアカウントは、割り当てられたワークスペースに加えてDefault Workspaceも使えます。Default Workspaceにアップロードしたファイルは、意図せず広い範囲から見えている可能性があります。
APIキーには単一ワークスペースキーと複数ワークスペースキーの2種類があります。単一ワークスペースキーは、作成時に選んだワークスペースの中でだけ動作し、他のワークスペースのfile_idを渡してもアクセスできません。複数ワークスペースキーは、リクエストごとにanthropic-workspace-idヘッダーで対象ワークスペースを指定して使い回せます。
file_idをそのまま受け取るとどうなるか
マルチテナントのアプリケーションを想定します。ユーザーAが資料をアップロードし、アプリはAnthropicから返ったfile_idをそのままクライアントへ渡す実装です。
他ユーザーのファイルが読まれる流れ
- 1
ユーザーAがアップロードする
アプリがFiles APIに資料を送り、返ってきた
file_...のIDをレスポンスにそのまま載せてクライアントへ返します。 - 2
ユーザーBがfile_idを手に入れる
ログ、共有された画面、共有ドキュメントに貼られたAPIレスポンスなど、経路は問いません。
- 3
Bが自分のリクエストにfile_idを入れて送る
バックエンドは持ち主を確かめず、受け取った値をAnthropic APIの
file_idにそのまま渡します。 - 4
リクエストが成功する
ワークスペースが同じなので、Anthropic側から見て拒否する理由がありません。Aの資料がBへの回答の材料になります。
file_idは、ユーザーとファイルの対応関係を保証しません。対応関係は自分のアプリケーション側で管理する責任があります。「持っていれば正当な所有者」という前提でfile_idを扱った瞬間に、この失敗が成立します。
公式ドキュメントは、file_idをエンドユーザーなど信頼できない入力から受け取らないよう明示的に注意しています。file_idはサーバー側の参照として扱います。
file_idの扱い方の違い
危ない実装
クライアントが送ってきたfile_idをそのままMessages APIへ渡します。レスポンスにもAnthropicのfile_idを載せて返します。
対応表を持つ実装
クライアントにはアプリ独自のファイルIDだけを見せます。受信したIDはDBでログイン中のユーザーと突き合わせ、一致したときだけ対応するfile_idをサーバーが取り出して使います。
file_idを知らなくても起きること — 一覧取得と照会
file_idを秘密にしておけば守れる、という見方にも限界があります。Files APIには、ワークスペースのファイルを一覧するGET /v1/filesがあり、1回で最大1,000件(既定は20件)を新しい順に返します。同じワークスペースのキーを持つ別のサービスや開発者は、IDを教えられなくても自分でIDを列挙できます。
照会用にids[]クエリパラメーターもあります。最大100件のIDを渡すと、そのワークスペースで解決できるファイルだけがdataに返ります。解決できないIDはエラーにならず黙って除外されます。つまり「存在しないID」と「別のワークスペースに属するID」は、この応答だけでは区別がつきません。
この挙動は、境界がどこにあるかを示しています。ワークスペースの内側では、IDの推測しにくさに頼った防御は十分とは言えません。境界はワークスペースの分割と、アプリ側の対応表の2つです。
マルチテナントでの防ぎ方 — 運用規模別の早見表
対策は運用規模によって変わります。
| 運用規模 | 対策 | 補足 |
|---|---|---|
| 単一テナント・社内ツール | 対策file_idをクライアントに渡さず、ユーザーIDとfile_idの対応をアプリ側のDBで管理する | 補足ワークスペースは1つのままで足りる |
| マルチテナントSaaS | 対策テナントごとに専用ワークスペースを作成し、テナント専用のAPIキーを発行する | 補足組織あたり既定で最大100ワークスペース |
| 監査ログが必要な組織 | 対策Compliance APIを有効化し、Activity Feedでアップロード・ダウンロード・削除を追跡する | 補足無効な期間の操作は記録されず、後から復元できない |
テナントごとにワークスペースを分け、そのワークスペースに限定したAPIキー(単一ワークスペースキー)を発行すれば、あるテナントのfile_idを別のテナントのキーで参照することはできません。複数ワークスペースキーを使う場合、ヘッダーの指定ミスがそのまま越境アクセスにつながります。
ファイルの隔離を確実にしたいなら、テナントや用途ごとに単一ワークスペースキーを分ける構成のほうが、ヘッダー指定ミスの余地が小さくなります。
漏れたIDの被害を時間で区切る方法もあります。アップロード時にexpires_in_secondsを指定すると、そのファイルは期限後にAPIから使えなくなります。期限切れのファイルを参照したMessagesリクエストは、推論の前に失敗します。一方で期限は設定後に変えられず、公式ドキュメントも「確実な削除手段ではない」と位置づけています。即座に消したいときはDELETE /v1/files/{file_id}を使います。
リクエストがどのワークスペースで動いているか確認する方法
確認には、file_idを使うリクエストのレスポンスヘッダーを見ます。Claude APIのレスポンスにはanthropic-workspace-idヘッダーが含まれ、そのキーが解決したワークスペースのID(wrkspc_で始まる)が分かります。別のワークスペースのfile_idは解決されません。
curl -sS -D - -o /dev/null https://api.anthropic.com/v1/files \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" | grep -i '^anthropic-workspace-id'この値がDefault Workspaceのものかどうかは、Admin APIのGet WorkspaceエンドポイントにAdminキーでIDを渡すと分かります。Default Workspaceは"name": "Default"で返ります。
注意点が2つあります。List Workspacesはinclude_default=trueを付けないとDefault Workspaceを返さないので、一覧にないことは「Defaultではない」ことを意味しません。また、Default Workspaceに属するAPIキーや使用量レポートではworkspace_idがnullになります。複数ワークスペースキーでもnullになるため、nullだけではDefaultと判断できません。キーのscopeフィールドを見ると、本物のIDが分かります。
テナントとワークスペースIDの対応表をアプリ側に持ち、file_idの発行時にワークスペースIDも記録しておくと、事故のときの切り分けが早くなります。
file_idの扱いでよくあるつまずき
アップロードしたファイルは取り出せないと思い込む
アップロードしたファイルのメタデータでは"downloadable": falseが返り、内容のダウンロードは400エラーになります。ダウンロードできるのは、スキルやコード実行ツールが生成したファイルだけです。しかしこれは安全の保証になりません。アップロードしたファイルの中身は、file_idをMessagesリクエストに入れれば、Claudeの回答を通して読めます。ダウンロード不可を理由に、file_idの検証を省くことはできません。
削除直後に「もう見えない」と思い込む
削除したファイルはAPIから間もなくアクセスできなくなりますが、進行中のMessages API呼び出しや関連するツール呼び出しには残ることがあります。削除は取り消せませんが、即座の消去を保証するものではありません。
監査ログが最初から有効だと思い込む
Compliance APIは、有効化(セットアップ)するまで操作を記録しません。有効化する前の操作は記録されず、後から遡って調べることもできません。
有効にしていても、記録されるのはアップロード(platform_file_uploaded)、内容のダウンロード(platform_file_content_downloaded)、削除(platform_file_deleted)の3種です。一覧取得とメタデータ取得は記録されません。ファイルの列挙や照会は、監査ログからは追えないことになります。
file_idがユーザー単位でない設計をどう受け止めるか
file_idがワークスペース単位で共有されるのは、仕様どおりの動きです。Files APIだけでなくMessage BatchesやSkillsも同じ単位でスコープされ、これらの資源で共通の隔離単位になっています。ユーザーやセッションといったアプリケーション固有の概念は、API側にありません。
この仕様では、ユーザーとファイルの対応関係をアプリケーション側で持つ前提になります。ワークスペースより細かい粒度の隔離が必要なら、テナントごとにワークスペースを分けるという1段上の設計判断が要ります。
仮にfile_idがユーザー単位でスコープされる設計だったとすると、別の負担が生まれると考えられます。ユーザーが退職・削除されたときにファイルをどう引き継ぐか、複数ユーザーで同じファイルをどう共有するかといった論点が、API側の仕様として固定されるためです。ワークスペースという粗い単位の内側で、割り当てをアプリ側の裁量に残す形は、ユースケースの幅を狭めにくい面もあると考えられます。
Files APIの容量上限や削除・失効までのライフサイクルはClaude Files APIの容量上限とファイルライフサイクルにまとめています。Anthropic API全体の料金・モデル選びはAnthropic API完全ガイドを参照してください。
まとめ
file_idは「持っていれば使える参照」であり、アクセス制御ではありません。
次の一手は、発行済みのfile_idの棚卸しです。GET /v1/filesで一覧を取り、アプリのDBの対応表にないファイルと、Default Workspaceに置いたファイルを洗い出せます。Compliance APIは有効にしてから記録が始まるので、運用を始める前に有効化しておきます。