Skip to content

View includes: '*' does not inherit public: false and shown: false from underlying cube members #11228

Description

@siddharth-atri-infoblox

Describe the bug
When a cube defines members with public: false or shown: false, a View built on top of that cube using includes: '*' silently re-exposes those members as public and shown. The View does not inherit the visibility flags from the underlying cube. This can lead to unintended data exposure, especially for fields hidden for security reasons (e.g., internal tenant identifiers).

Additionally, attempting to override visibility at the View level using object-form includes (e.g., { name: 'fieldName', public: false }) results in a validation error: "cubes[0].includes" does not match any of the allowed types. So there is currently no way to replicate the source cube's visibility behaviour in a View.

To Reproduce
Steps to reproduce the behaviour:

  1. Define a cube with a measure set to public: false and another dimension set to shown: false
  2. Create a View on top of that cube using includes: '*'
  3. Query /v1/meta - observe that both hidden members appear as public and shown in the View
  4. Attempt to use object-form includes to restore visibility control (e.g., { name: 'internalCount', public: false }) - observe validation error: "cubes[0].includes" does not match any of the allowed types

Expected behavior

  • includes: '*' should inherit public: false and shown: false from the underlying cube members. A wildcard include should mean "everything, as the cube defines it," not "everything, overridden to public."
  • Alternatively, object-form includes (e.g., { name: 'toRemove', public: false }) should be supported to allow per-member visibility control at the View level.

Screenshots
N/A

Minimally reproducible Cube Schema

cube(`OrdersV1`, {
  sql: `
  select 1 as id, 100 as amount, 'new' as status, 'tenant_001' as tenant_id
  UNION ALL
  select 2 as id, 200 as amount, 'new' as status, 'tenant_001' as tenant_id
  UNION ALL
  select 3 as id, 300 as amount, 'processed' as status, 'tenant_002' as tenant_id
  UNION ALL
  select 4 as id, 500 as amount, 'processed' as status, 'tenant_002' as tenant_id
  UNION ALL
  select 5 as id, 600 as amount, 'shipped' as status, 'tenant_001' as tenant_id
  `,
  measures: {
    count: {
      type: `count`,
    },
    totalAmount: {
      sql: `amount`,
      type: `sum`,
    },
    internalCount: {
      type: `count`,
      public: false,
    },
  },
  dimensions: {
    id: {
      sql: `id`,
      type: `number`,
      primaryKey: true,
      public: false,
    },
    status: {
      sql: `status`,
      type: `string`,
    },
    tenantId: {
      sql: `tenant_id`,
      type: `string`,
      shown: false,
    },
  },
});

// View using includes: '*' — hidden members get re-exposed
view(`Orders`, {
  description: `Compatibility view for OrdersV1`,
  cubes: [
    {
      join_path: OrdersV1,
      includes: `*`,
    },
  ],
});

Version:
1.6.57

Additional context

  • internalCount (measure marked public: false on the cube) appears as public through the View in /v1/meta
  • id (dimension marked public: false on the cube) appears as public through the View in /v1/meta
  • tenantId (dimension marked shown: false on the cube) appears as shown through the View in /v1/meta
  • Object-form includes like { name: 'internalCount', public: false } fail validation with: "cubes[0].includes" does not match any of the allowed types
  • This makes Views unsuitable as backward-compatible aliases for cubes that use visibility flags for access control, forcing the use of extends as a workaround

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions