Cómo se comparten archivos en registros (ContentDocumentLink)
El modelo de datos de Salesforce Files: ContentDocument, ContentVersion y ContentDocumentLink, y cómo ShareType y Visibility deciden quién ve un archivo.
Si alguna vez te has preguntado por qué un archivo aparece donde aparece en Salesforce, o has tenido que consultar archivos en Apex o en un informe, necesitas conocer el modelo de datos que hay debajo. Los Salesforce Files modernos son tres objetos relacionados, y dos campos del enlace deciden quién ve qué. Esta es la guía para administradores y desarrolladores que complementa quién puede ver un archivo en Salesforce.
Los tres objetos
| Objeto | Qué es | Cuántos |
|---|---|---|
| ContentDocument | El archivo en sí | Uno por archivo |
| ContentVersion | Una versión concreta del contenido del archivo | Una por subida/revisión |
| ContentDocumentLink | Un enlace que une el archivo a un registro, usuario o grupo | Muchos por archivo |
Cuando subes un archivo creas una ContentVersion, que Salesforce envuelve en un ContentDocument. Cuando adjuntas ese archivo a un registro o lo compartes con alguien, creas un ContentDocumentLink.
El archivo es el ContentDocument. Dónde reside y quién puede verlo está enteramente en sus ContentDocumentLinks.
ContentDocumentLink: el campo que más importa
Una fila de ContentDocumentLink dice “este archivo está enlazado a esa cosa, con este nivel de acceso, para esta audiencia”. Sus campos clave:
LinkedEntityId — aquello a lo que está adjunto el archivo
El ID de aquello con lo que está enlazado el archivo:
- Un registro (Account, Opportunity, Case, objeto personalizado…) → el archivo está “adjunto a” ese registro.
- Un User o Group → el archivo se comparte directamente con esa persona o grupo.
Un mismo archivo puede tener muchos enlaces a la vez: adjunto a dos registros y compartido con un usuario simultáneamente. Cada enlace es una vía independiente para ver el archivo.
ShareType — el nivel de acceso
| Valor | Nivel | Puede hacer |
|---|---|---|
V | Viewer | Abrir y descargar |
C | Collaborator | Ver, editar, subir versiones nuevas, cambiar el uso compartido |
I | Inferred | Nivel de acceso heredado del acceso al registro enlazado |
Inferred (I) es el importante para los archivos adjuntos a registros: el acceso de un usuario al archivo se deriva de su acceso al registro al que está enlazado. Ese es el mecanismo detrás de “cualquiera que pueda ver el registro puede ver sus archivos”.
Visibility — qué audiencia
| Valor | Audiencia |
|---|---|
AllUsers | Usuarios internos y externos (de comunidad) |
InternalUsers | Solo usuarios internos |
SharedUsers | Solo los usuarios con los que se ha compartido explícitamente el archivo |
Este campo es el que rompe sigilosamente el acceso desde Experience Cloud: un archivo adjunto a un registro con Visibility = InternalUsers no se mostrará a los usuarios de comunidad aunque puedan ver el registro. (Más sobre esto en archivos y usuarios invitados / de Experience Cloud.)
Cómo se resuelve realmente el acceso
Juntándolo todo, un usuario puede ver un archivo si alguno de sus ContentDocumentLinks se lo concede:
- Un enlace a un registro al que tiene acceso (ShareType
I): acceso heredado del uso compartido del registro. - Un enlace directo a él o a su grupo (ShareType
V/C). - La pertenencia a una biblioteca, o un enlace público (mecanismos aparte).
…y la Visibility del enlace debe incluir su audiencia. La mayoría de las incidencias de “archivo no visible” se reducen a un enlace que falta o a una Visibility demasiado restringida.
Cómo consultarlo
Como todo son datos, puedes inspeccionarlo directamente; por ejemplo, encontrar cada lugar donde se comparte un archivo:
SELECT ContentDocumentId, LinkedEntityId, ShareType, Visibility
FROM ContentDocumentLink
WHERE ContentDocumentId = '069...'
Cada fila es una audiencia que puede llegar al archivo. Para enumerar a las personas, después expandes la audiencia de uso compartido completa de cada registro LinkedEntityId, que es donde la cosa se hace grande rápido.
De las filas a una respuesta en lenguaje claro
Un archivo adjunto a varios registros hereda la audiencia entera de cada registro (jerarquía de roles, reglas de uso compartido, equipos y todo lo demás), multiplicada por cada ContentDocumentLink. Reconstruir eso a mano a partir de filas en bruto es exactamente el trabajo donde se esconde la exposición accidental. AgentForceAccess recorre los ContentDocumentLinks y el uso compartido del registro que hay detrás de cada uno, y responde “quién puede ver este archivo, y por qué” en lenguaje claro.
Preguntas frecuentes
¿Cuál es la diferencia entre ContentDocument, ContentVersion y ContentDocumentLink?
ContentDocument es el archivo en sí (uno por archivo). ContentVersion es una versión concreta de ese archivo (una por subida o revisión). ContentDocumentLink une un ContentDocument con otra cosa (un registro, usuario o grupo) y lleva el nivel de acceso y la visibilidad de ese enlace.
¿A qué apunta LinkedEntityId?
Es el ID de aquello con lo que está enlazado el archivo. Para un archivo adjunto a un registro es el ID del registro (Account, Opportunity, Case, etc.); para un archivo compartido directamente con una persona o grupo es un ID de User o Group. Un mismo archivo puede tener muchos ContentDocumentLinks a la vez.
¿Qué son los valores V, C e I de ShareType?
V = Viewer (abrir y descargar), C = Collaborator (ver, editar, subir versiones, cambiar el uso compartido), I = Inferred (el nivel de acceso que un usuario obtiene indirectamente a partir del acceso al registro enlazado). Inferred es la forma en que el acceso al registro se propaga a un archivo.
¿Qué hace el campo Visibility?
Visibility establece a quién se expone el enlace: AllUsers (usuarios internos y externos/de comunidad), InternalUsers (solo internos) o SharedUsers (solo los usuarios con los que se ha compartido explícitamente el archivo). Los usuarios de comunidad/Experience Cloud normalmente necesitan AllUsers para ver un archivo adjunto a un registro.
Míralo en tu propia organización
AgentForceAccess explica, en lenguaje claro, por qué cualquier usuario puede ver cualquier registro o archivo, recorriendo todos los mecanismos de colaboración de Salesforce.
Solicitar acceso anticipado