# Seguridad de datos

{% hint style="info" %}

#### Seguridad de datos

**Mondrian utiliza un modelo de seguridad basado en roles** para restringir el acceso a los datos. Los usuarios se asignan a roles, y cada rol define qué datos pueden ver dentro del cubo OLAP. Esto permite que una única base de datos analítica atienda a múltiples tipos de usuarios mostrando a cada usuario únicamente los datos autorizados.
{% endhint %}

<figure><img src="https://content.gitbook.com/content/VLCJbSi5xQoetAvNtGiu/blobs/zpDkAY8O13t24mw1cOSw/image.png" alt=""><figcaption><p>RBAC</p></figcaption></figure>

{% tabs %}
{% tab title="Roles" %}
{% hint style="info" %}

#### Roles

**Mondrian utiliza un modelo de seguridad basado en roles** para restringir el acceso a los datos. Los usuarios se asignan a roles, y cada rol define qué datos pueden ver dentro del cubo ROLAP. Considere un rol de gerente de ventas:

las personas en esta posición necesitan visibilidad de las métricas de rendimiento de su equipo, cifras de ventas por producto y cuentas clave de clientes. Para cumplir estas responsabilidades, el gerente de ventas requiere acceso a datos que abarcan productos, transacciones de ventas, información de clientes y dimensiones relacionadas.

Dentro de Mondrian, los roles deben definirse explícitamente en el esquema donde se aplicarán. Crear un rol es sencillo: simplemente declare un elemento Role y especifique su atributo name para identificarlo.
{% endhint %}

{% code expandable="true" %}

```xml
<!-- Rol de gerente de inventario -->
<Role name="Inventory Manager">
  <grants>...</grants>
</Role>

<!-- Rol de gerente de producto -->
<Role name="Product Manager">
  <grants>...</grants>
</Role>

<!-- Rol de gerente de ventas de EE. UU. -->
<Role name="US Sales Manager">
  <grants>...</grants>
</Role>

<!-- Rol de gerente de ventas del estado WA -->
<Role name="WA Sales Manager">
  <grants>...</grants>
</Role>

<!-- Rol de gerente de ventas del estado OR -->
<Role name="OR Sales Manager">
  <grants>...</grants>
</Role>

<!-- Rol de gerente de ventas del estado ID -->
<Role name="ID Sales Manager">
  <grants>...</grants>
</Role>

<!-- Rol de unión que combina General Sales Manager y Product Manager -->
<Role name="Product and Sales Manager">
  <Union>
    <RoleUsage roleName="General Sales Manager"/>
    <RoleUsage roleName="Product Manager"/>
  </Union>
</Role>
```

{% endcode %}

{% hint style="info" %}
La configuración de roles en Pentaho Mondrian requiere establecer una conexión entre el sistema de autenticación de Pentaho y la capa de seguridad de Mondrian. Esto se logra mediante un componente mapeador de roles.

**Ubicación de la configuración:**

* Archivo: `pentahoObjects.spring.xml`
* Ruta: `pentaho-solutions/system` directorio
* ID del bean: `Mondrian-UserRoleMapper`

El mapeador de roles traduce los roles de usuario de Pentaho en roles correspondientes de Mondrian, permitiendo a Mondrian aplicar las concesiones de seguridad apropiadas definidas en su esquema.
{% endhint %}

{% hint style="danger" %}
**Advertencia de seguridad:** Sin un mapeador de roles configurado, Mondrian por defecto permite acceso sin restricciones: todos los usuarios pueden ver todos los datos independientemente de sus roles en Pentaho. Siempre configure un mapeador de roles para garantizar la seguridad adecuada de los datos.
{% endhint %}

Pentaho incluye tres tipos de mapeadores de roles incorporados para adaptarse a diferentes requisitos de seguridad y estructuras organizativas:

{% tabs %}
{% tab title="Uno a uno" %}
{% hint style="info" %}

#### Mapeador de roles uno a uno

El mapeador uno a uno es el enfoque de mapeo más sencillo. Pasa directamente los roles de usuario de Pentaho a Mondrian sin ninguna transformación. Por ejemplo, si un usuario tiene el rol "Sales Manager" en Pentaho, Mondrian recibe exactamente ese mismo rol "Sales Manager".

Este mapeador es ampliamente utilizado porque funciona sin problemas con las estructuras de roles organizacionales existentes: no es necesario crear nombres de roles separados ni mantener lógica de mapeo compleja entre Pentaho y Mondrian.

**Parámetro de seguridad: failOnEmptyRoleList**

Este mapeador incluye un importante parámetro de seguridad que controla el comportamiento cuando un usuario no tiene roles de Mondrian coincidentes:

* **Valor predeterminado (recomendado):** El mapeador lanza una excepción si no se encuentra ningún mapeo de roles, evitando el acceso no autorizado. Esta es la configuración segura.
* **Configuración alternativa:** Si se establece en false, a los usuarios sin roles coincidentes se les concederán permisos completos sobre todos los datos—efectivamente lo mismo que no tener seguridad configurada. Esta configuración debe evitarse en entornos de producción.

**Mejor práctica:** Mantenga el comportamiento predeterminado habilitado para asegurar que solo los usuarios con roles definidos explícitamente puedan acceder a sus datos de Mondrian.
{% endhint %}

```xml
<bean id="Mondrian-UserRoleMapper"
name="Mondrian-One-To-One-UserRoleMapper"
class="org.pentaho.platform.plugin.action.mondrian.mapper.MondrianOneToOneUserRoleListMapper"
scope="singleton" />
...
```

{% endtab %}

{% tab title="Búsqueda" %}
{% hint style="info" %}

#### Búsqueda

El mapeador lookup-map proporciona una capa de traducción entre el espacio de nombres de roles de Pentaho y las definiciones de roles de Mondrian. Este mapeador es esencial cuando la nomenclatura de roles difiere entre sistemas o al consolidar múltiples organizaciones con convenciones de nombres de roles distintas en un esquema Mondrian unificado.

**Configuración:** Defina mapeos como pares clave-valor donde la clave representa el identificador del rol de Pentaho y el valor representa el rol de Mondrian objetivo. Durante el establecimiento de la conexión, Pentaho resuelve los roles del usuario a través de esta tabla de búsqueda y transmite los nombres de roles mapeados al motor de seguridad de Mondrian.

Este enfoque le permite mantener convenciones de nombres de roles separadas en Pentaho mientras estandariza las definiciones de roles dentro de sus esquemas Mondrian.
{% endhint %}

```xml
<!-- Este mapeador de ejemplo asume que se necesita un traductor (en forma de Map) para mapear un rol de la plataforma a un rol de Mondrian.
Nota- Key = rol de la plataforma, value = rol de Mondrian -->

<bean id="Mondrian-UserRoleMapper"
name="Mondrian-SampleLookupMap-UserRoleMapper"
class="org.pentaho.platform.plugin.action.mondrian.mapper.MondrianLookupMapUserRoleListMapper"
scope="singleton">
<property name="lookupMap">
     <map>
       <entry key="Power User" value="Power user" />
     </map>
   </property>
 </bean>
...
```

{% endtab %}

{% tab title="Sesión de usuario" %}
{% hint style="info" %}

#### Sesión de usuario

El mapeador user-session recupera las asignaciones de roles de Mondrian dinámicamente desde un atributo de sesión del usuario. Este enfoque permite que las definiciones de roles se determinen en tiempo de ejecución en lugar de mediante configuración estática.

**Cómo funciona:**

Cuando Pentaho establece una conexión con Mondrian, el mapeador realiza la siguiente secuencia:

1. Accede a la sesión activa del usuario
2. Recupera el atributo de sesión especificado
3. Extrae el/los valor(es) de rol de ese atributo
4. Pasa esos roles a Mondrian para la aplicación de la seguridad

Este enfoque dinámico es particularmente útil cuando los roles deben calcularse o recuperarse de sistemas externos durante el proceso de inicio de sesión.

**Configuración:**

La única configuración requerida es especificar qué atributo de sesión contiene la información de roles. Por ejemplo, si su atributo de sesión se llama `MondrianUserRoles`, configuraría el mapeador para leer ese atributo. El mapeador entonces extraerá y aplicará automáticamente los valores de rol almacenados allí.
{% endhint %}

```xml
<!-- Este mapeador de ejemplo asume que cada usuario tiene sus roles de mondrian en su sesión bajo la variable de sesión nombrada. -->
<bean id="Mondrian-UserRoleMapper" 
name="Mondrian-SampleUserSession-UserRoleMapper" 
class="org.pentaho.platform.plugin.action.mondrian.mapper.MondrianUserSessionUserRoleListMapper" 
scope="singleton">
<property name="sessionProperty" value="MondrianUserRoles" />
  </bean>
...
```

{% endtab %}
{% endtabs %}
{% endtab %}

{% tab title="Concesiones de seguridad" %}
{% hint style="info" %}

#### Concesiones de seguridad

Suponga que solo quiere que el gerente de producto vea el estado, el artículo y la cantidad comprada. A continuación, quiere que el gerente de ventas del estado vea todos los mismos datos que el gerente de ventas de EE. UU., pero solo para ese estado. Las concesiones de seguridad de Mondrian pueden considerarse como un conjunto de filtros sobre los datos, y el rol solo puede ver lo que sus filtros permiten. En cada nivel del esquema, el usuario puede tener datos explícitamente restringidos o mostrados.
{% endhint %}

<figure><img src="https://content.gitbook.com/content/VLCJbSi5xQoetAvNtGiu/blobs/PWWH6GSz3MQsZFq1reqJ/image.png" alt="" width="478"><figcaption></figcaption></figure>

| Nivel                               | Ámbito                   | Propósito                          |
| ----------------------------------- | ------------------------ | ---------------------------------- |
| **SchemaGrant**                     | Esquema completo         | Control de acceso a nivel superior |
| **CubeGrant**                       | Cubos individuales       | Restricciones específicas del cubo |
| **DimensionGrant / HierarchyGrant** | Dimensiones y jerarquías | Filtrado dimensional               |
| **MemberGrant**                     | Miembros específicos     | Acceso fino a miembros             |

{% hint style="warning" %}
**Nota:** que cuando a un rol se le concede acceso a algo, implícitamente se le da acceso al elemento padre. Esto significa que si usa un tipo de acceso none para un esquema y luego concede acceso a un cubo, el rol ahora también tiene acceso al esquema. En este caso, un tipo de acceso none es un atajo para quitar el acceso a todos los demás cubos excepto al/los especificado(s).
{% endhint %}

{% tabs %}
{% tab title="Esquema" %}
{% hint style="info" %}

#### SchemaGrant

El SchemaGrant es el primer y más alto nivel de control de seguridad en Mondrian. Tiene un único atributo llamado `access` que determina si los usuarios pueden ver el esquema en absoluto.

Hay tres opciones de acceso disponibles: `all`, `none`, y `all_dimensions`. Sin embargo, solo `all` y `none` se utilizan comúnmente en la práctica. La `all_dimensions` opción se comporta idénticamente a `none` y está programada para ser eliminada en versiones futuras, por lo que puede ignorarse de forma segura.
{% endhint %}

{% hint style="info" %}

#### **SchemaGrant all**

Da al rol acceso a todos los cubos y dimensiones en el esquema, pero más adelante puede limitar el acceso a la totalidad o partes de los datos usando concesiones más detalladas. Otras concesiones se anidan dentro del schema grant.
{% endhint %}

```xml
<Role name="Product Manager">
  <SchemaGrant access="all">
    <!-- Concesiones adicionales pueden restringir más -->
  </SchemaGrant>
</Role>
```

{% hint style="info" %}

#### **SchemaGrant none**

Esta opción se usa cuando desea restringir completamente a un usuario de ver el esquema. Por ejemplo, quizá tenga un esquema completamente dedicado a Recursos Humanos y quiera limitarlo a todos excepto RR. HH.
{% endhint %}

```xml
<Role name="Product Manager">
  <SchemaGrant access="none">
  </SchemaGrant>
</Role>
```

{% endtab %}

{% tab title="Cubo" %}
{% hint style="info" %}

#### CubeGrant

El CubeGrant toma dos atributos: el nombre del cubo al que se aplica la concesión y el control de acceso para la concesión. Solo hay dos opciones para el acceso de las concesiones de cubo: all o none. Ambas funcionan de forma similar al schema grant, pero a nivel de cubo.
{% endhint %}

{% hint style="info" %}

#### CubeGrant all

La opción all da al rol acceso al cubo. Si un usuario no tiene acceso al esquema, esto da acceso al cubo en particular pero a ninguno de los otros.
{% endhint %}

```xml
<Role name="Product Manager">
  <SchemaGrant access="none">
    <CubeGrant cube="Product Sales" access="all">
      <!-- El usuario ve el cubo Product Sales pero no otros -->
    </CubeGrant>"/>
  </SchemaGrant>
</Role>
```

{% hint style="info" %}

#### CubeGrant none

Un CubeGrant de none significa que a un usuario que esté en el rol dado no se le otorga acceso al cubo. A diferencia del schema grant, una vez que se quita el acceso al cubo, el usuario no puede ver ninguno de los datos del cubo.
{% endhint %}

```xml
<Role name="Product Manager">
  <SchemaGrant access="all">
  <!-- El usuario ve todos los esquemas -->
    <CubeGrant cube="Human Resources" access="none">
      <!-- El usuario no tiene acceso al cubo de RR. HH. -->
    </CubeGrant>
  </SchemaGrant>
</Role>
```

{% endtab %}

{% tab title="Dimensión" %}
{% hint style="info" %}

#### DimensionGrant

El Dimension Grant tiene dos atributos obligatorios: dimension, el nombre de la dimensión, y access, que puede ser all o none. Un acceso de all no suele aportar mucho valor, porque es el predeterminado, por lo que normalmente solo usará none. Los dimension grants tampoco pueden tener hijos. Si desea un control más detallado sobre el contenido de una dimensión, necesitará usar un hierarchy grant.
{% endhint %}

```xml
<Role name="Product Manager">
  <SchemaGrant access="none">
  <!-- Denegar acceso a todos los esquemas -->
    
    <CubeGrant cube="Product Sales" access="all">
    <!-- El usuario ahora tiene acceso al cubo Product Sales -->
          
       <DimensionGrant dimension="[Location]" access="all">
       <!-- Permitir acceso a la dimensión Location -->
       <DimensionGrant dimension="[Customer]" access="none">
       <!-- Denegar acceso a la dimensión Customer -->
       
    </CubeGrant>    
  </SchemaGrant>
</Role>
```

{% endtab %}

{% tab title="Jerarquía" %}
{% hint style="info" %}

#### HierarchyGrant

El HierarchyGrant tiene dos atributos obligatorios: hierarchy, el nombre de la jerarquía, y access. El nombre de la jerarquía puede ser el nombre completo de la jerarquía o, si el nombre de la jerarquía sigue las convenciones de Mondrian y solo hay una, solo el nombre de la dimensión.&#x20;

Por ejemplo, si la dimensión se llama \[Product] y la jerarquía se llama \[Products], es suficiente con establecer el nombre de la jerarquía en \[Product]. Pero si tiene múltiples jerarquías, como \[Org Structure.Financial] y \[Org Structure.Reporting], necesitará especificar el nombre completo de la jerarquía que desea usar.
{% endhint %}

{% hint style="info" %}

#### HierarchyGrant all

All se usa cuando desea conceder acceso a toda la jerarquía y a todos sus miembros. All es el valor predeterminado para las jerarquías, por lo que rara vez se establece explícitamente.
{% endhint %}

```xml
<Role name="Product Manager">
  <SchemaGrant access="none">
  <!-- Denegar acceso a todos los esquemas -->
    
    <CubeGrant cube="Product Sales" access="all">
    <!-- El usuario ahora tiene acceso al cubo Product Sales -->
          
       <HierarchyGrant hierarchy = "[Product].[Products]" access="all">
       <!-- Permitir acceso a la jerarquía Product -->
       
    </CubeGrant>    
  </SchemaGrant>
</Role>
```

{% hint style="info" %}

#### HierarchyGrant none

El acceso de jerarquía none restringe a un usuario de ver una jerarquía, incluidos cualquiera de los niveles o miembros en la jerarquía.
{% endhint %}

```xml
<Role name="Product Manager">
  <SchemaGrant access="none">
  <!-- Denegar acceso a todos los esquemas -->
    
    <CubeGrant cube="Product Sales" access="all">
    <!-- El usuario ahora tiene acceso al cubo Product Sales -->
          
       <HierarchyGrant hierarchy="[Product].[Products]" access="none">
       <!-- Denegar acceso a la jerarquía Product -->
       
    </CubeGrant>    
  </SchemaGrant>
</Role>
```

***

{% hint style="info" %}

#### Atributos opcionales - Top & Bottom

HierarchyGrant incluye dos atributos opcionales - `topLevel` y `bottomLevel -` que crean límites de acceso dentro de una jerarquía. Ambos requieren `access="custom"` para funcionar.

**topLevel: Ocultar niveles superiores**

Evita que los usuarios vean datos por encima de un nivel especificado.

* **Propósito:** Bloquear el acceso a resúmenes excesivamente agregados o a nivel organizacional

**Ejemplo:** Restringir a los gerentes al nivel de unidad de negocio, ocultando totales a nivel empresarial

**bottomLevel: Ocultar niveles inferiores**

Evita que los usuarios vean datos por debajo de un nivel especificado.

* **Propósito:** Mostrar tendencias y resúmenes mientras se ocultan detalles granulares

**Ejemplo:** Permitir que los vendedores vean el rendimiento regional pero ocultar métricas de vendedores individuales

**Resultado: Rango de visualización controlado**

Juntos, estos atributos definen qué niveles de la jerarquía son visibles—todo lo que esté por encima `topLevel` y por debajo `bottomLevel` permanece oculto.
{% endhint %}

```xml
<HierarchyGrant hierarchy="[Location]" 
                access="custom"
                topLevel="[Location].[Country]"
                bottomLevel="[Location].[City]">
  <!-- El usuario solo puede ver niveles de Country a City -->
</HierarchyGrant>
```

<figure><img src="https://content.gitbook.com/content/VLCJbSi5xQoetAvNtGiu/blobs/ppYfyhsjFklBPCXwdqds/image.png" alt=""><figcaption><p>Top &#x26; Bottom</p></figcaption></figure>
{% endtab %}

{% tab title="Miembro" %}
{% hint style="info" %}

#### MemberGrant

Los member grants proporcionan un control más fino sobre las dimensiones que los hierarchy grants. El rol tiene acceso a la dimensión pero solo puede ver los miembros específicos a los que se le da acceso.
{% endhint %}

```xml
<Role name="Sales Manager - WA">
  <SchemaGrant access="none">
  <!-- Denegar acceso a todos los esquemas -->
    
    <CubeGrant cube="Product Sales" access="all">
    <!-- El usuario ahora tiene acceso al cubo Product Sales -->
       <HierarchyGrant hierarchy="[Location]" access="custom">
          
         <MemberGrant member="[Location].[Country].[USA]" access="none">1((mg_no_usa_access))>
         <!-- Denegar acceso a USA -->
         <MemberGrant member="[Location].[State].[WA]" access="all">
         <!-- Conceder acceso al estado WA -->
       
    </CubeGrant>    
  </SchemaGrant>
</Role>
```

{% hint style="warning" %}

#### &#x20;**Reglas de concesión por miembro (¡el orden importa!)**

1. **Las concesiones dependen del orden:** Si concede acceso a un hijo y luego deniega al padre, el hijo se vuelve inaccesible. Por ejemplo, si crea un acceso de miembro que puede ver \[USA].\[CA] y luego deniega el acceso a \[USA], el rol ya no podrá ver \[USA].\[CA].
2. **Las concesiones heredan:** Denegar \[USA] también niega todos los estados dentro de USA. Por ejemplo, si niega el acceso a \[USA], todos los miembros hijo también tienen el acceso denegado porque el acceso a los hijos requiere acceso al padre. Pero el acceso a los hijos puede concederse más tarde. Esto le permite bloquear el acceso a un conjunto de miembros y luego devolver el acceso solo a unos pocos limitados.
3. **Los padres se conceden acceso implícitamente:** Conceder \[WA] también concede acceso al padre \[USA]. Esto sigue la regla de herencia. Para llegar a \[USA].\[WA], por ejemplo, primero necesita acceder a \[USA].&#x20;
4. **Los member grants no anulan los atributos topLevel y bottomLevel:** a nivel de hierarchy grant. Esto significa que incluso si concede acceso a una tienda individual en un estado, pero establece un bottom level en la ciudad en la que se encuentra la tienda, aún solo verá hasta el nivel de ciudad.
5. **Resultado del ejemplo anterior:** El usuario puede ver USA y WA, pero ningún otro estado
   {% endhint %}

A continuación hay una tabla que describe las posibles combinaciones de derechos de acceso que determinan el conjunto de datos mostrado en el informe.

| Acceso a \[USA] | Acceso a \[WA]  | Miembros del estado       |
| --------------- | --------------- | ------------------------- |
| none            | No especificado | {}                        |
| all             | No especificado | {\[CA],\[ID],\[OR],\[WA]} |
| none            | all             | {\[WA]}                   |
| none            | none            | {}                        |
| all             | none            | {}                        |
| all             | all             | {\[WA]}                   |
| {% endtab %}    |                 |                           |

{% tab title="Política de acumulación (Rollup Policy)" %}
{% hint style="info" %}

#### Política de acumulación (Rollup Policy)

**El problema:** ¿Qué sucede con los totales de los padres cuando un rol solo puede ver algunos de los hijos?

Una política de acumulación controla cómo Mondrian calcula los valores agregados cuando el rol de un usuario restringe el acceso a ciertos miembros hijos. Esto se vuelve crítico cuando desea evitar que los usuarios deduzcan datos ocultos mediante inferencia matemática.
{% endhint %}

{% hint style="info" %}

#### Escenario del mundo real

**Configuración:**

* El rol de Hugo le permite ver los datos de ventas de California y Oregon
* Hugo no puede ver los datos de ventas de Washington
* Hugo consulta las ventas totales de USA y sus estados

**La pregunta:** ¿Debería el total de USA incluir las ventas de Washington (que Hugo no puede ver)?
{% endhint %}

Para remediar esto, un rol puede aplicar una política de acumulación diferente a una jerarquía. La política describe cómo se calcula un total para un miembro particular si el rol actual solo puede ver algunos de los hijos de ese miembro:

| Política    | El total del padre incluye           | ¿Puede deducir valores ocultos? | Mejor para                                         |
| ----------- | ------------------------------------ | ------------------------------- | -------------------------------------------------- |
| **full**    | Todos los hijos (visibles + ocultos) | Sí                              | Escenarios de baja seguridad con muchos hijos      |
| **partial** | Solo hijos visibles                  | No                              | Caso de uso más común; intuitivo para los usuarios |
| **hidden**  | Nada (total oculto)                  | No                              | Escenarios de alta seguridad; agregados sensibles  |

{% tabs %}
{% tab title="Full" %}
{% hint style="info" %}

#### Política Full - Predeterminada

El total para ese miembro incluye todos los hijos. Esta es la política predeterminada si no especifica el atributo rollupPolicy.
{% endhint %}

```
Tienda                Ventas unitarias
[USA]                266.773      ← Incluye las ventas ocultas de WA (124.366)
  [USA].[CA]         74.748       ← Visible
  [USA].[OR]         67.659       ← Visible
  [USA].[WA]         (oculto)     ← No mostrado
```

{% hint style="info" %}
**Resultados de la consulta de Hugo:**

**Problema:** Hugo puede calcular el valor oculto: 266.773 - 74.748 - 67.659 = 124.366

**Cuándo usar:** Cuando ocultar datos no sea crítico, o cuando haya demasiados hijos para deducir valores ocultos.
{% endhint %}
{% endtab %}

{% tab title="Partial" %}
{% hint style="info" %}

#### Política Partial

El total del padre incluye SOLO los hijos a los que el usuario puede acceder.
{% endhint %}

```
Tienda                Ventas unitarias
[USA]                142.407      ← Solo CA + OR (74.748 + 67.659)
  [USA].[CA]         74.748       ← Visible
  [USA].[OR]         67.659       ← Visible
  [USA].[WA]         (oculto)     ← No mostrado
```

{% hint style="info" %}
**Resultados de la consulta de Hugo:**

**Beneficio:** Hugo no puede deducir las ventas de Washington. El total de USA refleja con precisión solo lo que puede ver.

**Cuándo usar:** Cuando los usuarios solo deben ver agregados de sus datos autorizados. Lo más intuitivo para los usuarios finales.
{% endhint %}
{% endtab %}

{% tab title="Hidden" %}
{% hint style="info" %}

#### Hidden

El total del padre está completamente oculto si ALGUNO de los hijos es inaccesible.
{% endhint %}

```
Tienda                Ventas unitarias
[USA]                -            ← Oculto porque WA es inaccesible
  [USA].[CA]         74.748       ← Visible
  [USA].[OR]         67.659       ← Visible
  [USA].[WA]         (oculto)     ← No mostrado
```

{% hint style="info" %}
**Resultados de la consulta de Hugo:**

**Beneficio:** Seguridad máxima—Fred no puede deducir nada sobre los datos ocultos.

**Cuándo usar:** Cuando los valores agregados en sí mismos son sensibles, o cuando desea ocultar por completo la existencia de datos restringidos.
{% endhint %}
{% endtab %}

{% tab title="Política de acumulación (Rollup Policy) " %}
{% hint style="info" %}

#### Política de acumulación - Ejemplo

Las políticas de acumulación se establecen por jerarquía dentro de cada rol. Diferentes jerarquías pueden tener políticas distintas.
{% endhint %}

{% code expandable="true" %}

```xml
<Role name="Regional Sales Manager">
  <SchemaGrant access="none">
    <CubeGrant cube="Sales" access="all">
      
      <!-- Jerarquía Store: política de acumulación parcial -->
      <HierarchyGrant hierarchy="[Store]" 
                      access="custom" 
                      rollupPolicy="partial"
                      topLevel="[Store].[Store Country]">
        <MemberGrant member="[Store].[USA].[CA]" access="all"/>
        <MemberGrant member="[Store].[USA].[CA].[Los Angeles]" access="none"/>
      </HierarchyGrant>
      
      <!-- Jerarquía Customers: política de acumulación completa -->
      <HierarchyGrant hierarchy="[Customers]" 
                      access="custom" 
                      rollupPolicy="full"
                      topLevel="[Customers].[State Province]"
                      bottomLevel="[Customers].[City]">
        <MemberGrant member="[Customers].[USA].[CA]" access="all"/>
        <MemberGrant member="[Customers].[USA].[CA].[Los Angeles]" access="none"/>
      </HierarchyGrant>
      
      <!-- Jerarquía Gender: completamente oculta -->
      <HierarchyGrant hierarchy="[Gender]" access="none"/>
      
    </CubeGrant>
  </SchemaGrant>
</Role>
```

{% endcode %}

{% hint style="info" %}
**Resultado:**

* Los totales de tienda muestran solo los hijos accesibles (parcial)
* Los totales de clientes incluyen todos los hijos (completo)
* La dimensión Gender es completamente invisible
* Ambas jerarquías respetan las restricciones topLevel/bottomLevel
  {% endhint %}
  {% endtab %}
  {% endtabs %}
  {% endtab %}
  {% endtabs %}
  {% endtab %}
  {% endtabs %}
