レコードのファイル共有の仕組み(ContentDocumentLink)
Salesforce Files を支えるデータモデル、ContentDocument・ContentVersion・ContentDocumentLink と、ShareType と Visibility が誰にファイルを見せるかを決める仕組みを解説します。
Salesforce でファイルがなぜその場所に表示されるのか疑問に思ったことがある方、あるいは Apex やレポートでファイルをクエリする必要があった方には、その土台にあるデータモデルの理解が欠かせません。最近の Salesforce Files は 3 つの関連オブジェクトで構成され、リンク上の 2 つのフィールドが誰に何を見せるかを決めています。この記事は、Salesforce で誰がファイルを見られるかの管理者/開発者向けの姉妹編です。
3 つのオブジェクト
| オブジェクト | 何であるか | 数 |
|---|---|---|
| ContentDocument | ファイルそのもの | ファイル 1 つにつき 1 件 |
| ContentVersion | ファイル内容の特定のバージョン | アップロード/改訂ごとに 1 件 |
| ContentDocumentLink | ファイルをレコード・ユーザー・グループに結びつけるリンク | ファイル 1 つにつき多数 |
ファイルをアップロードすると ContentVersion が作成され、Salesforce がそれを ContentDocument で包みます。そのファイルをレコードに添付したり誰かに共有したりすると、ContentDocumentLink が作成されます。
ファイルは ContentDocument です。どこに存在し誰が見られるかは、すべてその ContentDocumentLink の中にあります。
ContentDocumentLink:最も重要なフィールド
ContentDocumentLink の 1 行は、「このファイルはあの対象に、このアクセスレベルで、この対象者向けにリンクされている」ということを表します。主なフィールドは次のとおりです。
LinkedEntityId — ファイルが添付されている対象
ファイルがリンクされている対象の ID です。
- レコード(Account、Opportunity、Case、カスタムオブジェクトなど)→ ファイルはそのレコードに「添付」されています。
- User または Group → ファイルはその人やグループに直接共有されています。
1 つのファイルが同時に多数のリンクを持つこともあります。2 つのレコードに添付されつつ、同時に 1 人のユーザーに共有されている、といった具合です。各リンクは、それぞれが独立したファイルへの到達経路です。
ShareType — アクセスレベル
| 値 | レベル | できること |
|---|---|---|
V | Viewer | 開く・ダウンロード |
C | Collaborator | 表示、編集、新しいバージョンのアップロード、共有設定の変更 |
I | Inferred | リンク先レコードへのアクセスから継承されるアクセスレベル |
レコードに添付されたファイルにとって重要なのが Inferred(I) です。ファイルへのユーザーのアクセスは、リンク先のレコードへのアクセスから導き出されます。これが「レコードを見られる人は誰でもそのファイルを見られる」という仕組みの正体です。
Visibility — どの対象者か
| 値 | 対象者 |
|---|---|
AllUsers | 社内および社外(コミュニティ)ユーザー |
InternalUsers | 社内ユーザーのみ |
SharedUsers | 明示的にファイルを共有されたユーザーのみ |
このフィールドは、Experience Cloud のアクセスをひそかに壊す犯人です。Visibility = InternalUsers のレコード添付ファイルは、コミュニティユーザーがレコードを見られても表示されません。(詳しくはファイルとゲスト/Experience Cloud ユーザーへの露出を参照してください。)
アクセスが実際にどう解決されるか
まとめると、ユーザーは ContentDocumentLink のいずれかがアクセスを許可していれば、そのファイルを見ることができます。
- アクセスできるレコードへのリンク(ShareType
I)— レコードの共有から継承されたアクセス。 - 本人またはそのグループへの直接のリンク(ShareType
V/C)。 - ライブラリのメンバーシップ、または公開リンク(これらは別の仕組みです)。
…そして、リンクの Visibility がそのユーザーの対象者を含んでいる必要があります。「ファイルが表示されない」という問い合わせの大半は、リンクの不足か、狭すぎる Visibility に行き着きます。
クエリで調べる
すべてがデータなので、直接調べることができます。たとえば、あるファイルが共有されているすべての場所を探すには次のようにします。
SELECT ContentDocumentId, LinkedEntityId, ShareType, Visibility
FROM ContentDocumentLink
WHERE ContentDocumentId = '069...'
各行は、ファイルに到達できる 1 つの対象者です。個々の人を列挙するには、さらに各 LinkedEntityId レコードの共有対象者全体を展開する必要があり、ここから一気に規模が膨らみます。
行から平易な答えへ
複数のレコードに添付されたファイルは、それぞれのレコードの対象者全体(ロール階層、共有ルール、チームなどすべて)を継承し、それが ContentDocumentLink ごとに掛け合わさります。生の行から手作業でこれを再構築する作業こそが、意図しない露出が隠れる場所そのものです。AgentForceAccess は ContentDocumentLink と、その背後にある各レコードの共有をたどり、「このファイルを誰が、なぜ見られるのか」を平易な言葉で答えます。
よくある質問
ContentDocument、ContentVersion、ContentDocumentLink の違いは何ですか?
ContentDocument はファイルそのものです(ファイル 1 つにつき 1 件)。ContentVersion はそのファイルの特定のバージョンです(アップロード/改訂ごとに 1 件)。ContentDocumentLink は ContentDocument を他のもの(レコード、ユーザー、グループ)に結びつけ、そのリンクに対するアクセスレベルと公開範囲(Visibility)を保持します。
LinkedEntityId は何を指していますか?
ファイルがリンクされている対象の ID です。レコードに添付されたファイルであればレコード ID(Account、Opportunity、Case など)であり、人やグループに直接共有されたファイルであれば User または Group の ID です。1 つのファイルが同時に多数の ContentDocumentLink を持つこともあります。
ShareType の値 V、C、I は何を意味しますか?
V = Viewer(開く・ダウンロード)、C = Collaborator(表示、編集、バージョンのアップロード、共有設定の変更)、I = Inferred(リンク先レコードへのアクセスから間接的に得られるアクセスレベル)です。Inferred は、レコードへのアクセスがファイルに伝播する仕組みです。
Visibility フィールドは何をしますか?
Visibility はリンクの公開対象を設定します。AllUsers(社内および社外/コミュニティのユーザー)、InternalUsers(社内のみ)、SharedUsers(明示的にファイルを共有されたユーザーのみ)です。コミュニティ/Experience Cloud のユーザーは、レコードに添付されたファイルを見るために通常 AllUsers が必要です。
あなたの組織で試してみる
AgentForceAccessは、あらゆるユーザーがあらゆるレコードやファイルを見られる理由を、Salesforceのすべての共有の仕組みを横断して、わかりやすい言葉で説明します。
先行アクセスを申し込む