diff --git a/docs/pages/guides/recipes/multitenancy/custom-data-model-per-tenant.mdx b/docs/pages/guides/recipes/multitenancy/custom-data-model-per-tenant.mdx index 6c0745196eddf..e9120696c2737 100644 --- a/docs/pages/guides/recipes/multitenancy/custom-data-model-per-tenant.mdx +++ b/docs/pages/guides/recipes/multitenancy/custom-data-model-per-tenant.mdx @@ -67,10 +67,10 @@ module.exports = { ## Data modeling -### Customizing publicity +### Customizing member-level access -The simplest way to customize the data models is by changing the [publicity][ref-publicity] -of data model entities. It works great for use cases when tenants share parts of +The simplest way to customize the data models is by changing the [member-level access][ref-mls] +to data model entities. It works great for use cases when tenants share parts of their data models. By setting the `public` parameter of [cubes][ref-cubes-public], [views][ref-views-public], @@ -168,7 +168,7 @@ cube(`cube_x`, { -For your convenience, [Playground][ref-playground] ignores publicity configration +For your convenience, [Playground][ref-playground] ignores member-level access configration and marks data model entities that are not accessible for querying through [APIs][ref-apis] with the lock icon. @@ -182,8 +182,8 @@ And here's the *perspective* of `Bob`: ### Customizing other parameters -Similarly to [customizing publicity](#customizing-publicity), you can set other -parameters of data model entities for each tenant individually: +Similarly to [customizing member-level access](#customizing-member-level-access), +you can set other parameters of data model entities for each tenant individually: - By setting `sql` or [`sql_table` parameters][ref-cube-sql-table] of cubes, you can ensure that each tenant accesses data from its own tables or database schemas. @@ -364,7 +364,7 @@ code that fetches data model files for each tenant. [ref-scheduled-refresh-contexts]: /reference/configuration/config#scheduled_refresh_contexts [ref-context-to-app-id]: /reference/configuration/config#context_to_app_id [ref-config-files]: /product/configuration#cubepy-and-cubejs-files -[ref-publicity]: /product/data-modeling/concepts/publicity +[ref-mls]: /product/auth/member-level-security [ref-cubes-public]: /reference/data-model/cube#public [ref-views-public]: /reference/data-model/view#public [ref-measures-public]: /reference/data-model/measures#public diff --git a/docs/pages/product/_meta.js b/docs/pages/product/_meta.js index d1326632afc38..072b06720981a 100644 --- a/docs/pages/product/_meta.js +++ b/docs/pages/product/_meta.js @@ -3,8 +3,8 @@ module.exports = { "getting-started": "Getting started", "configuration": "Configuration", "data-modeling": "Data modeling", + "auth": "Access control", "caching": "Caching", - "auth": "Authentication & authorization", "apis-integrations": "APIs & integrations", "workspace": "Workspace", "deployment": "Deployment", diff --git a/docs/pages/product/auth.mdx b/docs/pages/product/auth.mdx index 3825a1bc4e626..71adf50b07238 100644 --- a/docs/pages/product/auth.mdx +++ b/docs/pages/product/auth.mdx @@ -1,9 +1,4 @@ ---- -redirect_from: - - /security ---- - -# Overview +# Access control In Cube, authorization (or access control) is based on the **security context**. The diagram below shows how it works during the request processing in Cube: diff --git a/docs/pages/product/auth/_meta.js b/docs/pages/product/auth/_meta.js index 9f2bfa9f089e5..68c456f8a9cf7 100644 --- a/docs/pages/product/auth/_meta.js +++ b/docs/pages/product/auth/_meta.js @@ -1,3 +1,6 @@ module.exports = { - "context": "Security context" + "context": "Security context", + "member-level-security": "Member-level security", + "row-level-security": "Row-level security", + "data-access-policies": "Data access policies" } \ No newline at end of file diff --git a/docs/pages/product/auth/data-access-policies.mdx b/docs/pages/product/auth/data-access-policies.mdx new file mode 100644 index 0000000000000..50adb22f0d5e4 --- /dev/null +++ b/docs/pages/product/auth/data-access-policies.mdx @@ -0,0 +1,51 @@ +# Data access policies + +TODO + +## Data access roles + +TODO + +## Member-level access + +TODO + + +``` +Привет! Можешь проверить, что я правильно мыслю? Снова access policies. + +Вот есть такие политики. Для пользователя с ролью status_checker_2_3_4 она ожидаемо делает доступным куб и все его мемберы. + access_policy: + - role: "*" + member_level: + includes: [] + + - role: status_checker_2_3_4 + member_level: + includes: '*' + +А вот такие политики (поменял includes на excludes) для пользователя с ролью status_checker_2_3_4 + access_policy: + - role: "*" + member_level: + excludes: '*' + + - role: status_checker_2_3_4 + member_level: + includes: '*' +``` + + + +написать, что public takes preference + + +написать, что вьюшки не наследуют mls от кубов + +When evaluating Cube and View level policies: +- member level policy at the view always wins (you can expose a hidden + member of a Cube on a View) + +## Row-level access + +TODO \ No newline at end of file diff --git a/docs/pages/product/data-modeling/concepts/publicity.mdx b/docs/pages/product/auth/member-level-security.mdx similarity index 98% rename from docs/pages/product/data-modeling/concepts/publicity.mdx rename to docs/pages/product/auth/member-level-security.mdx index 7d5d7f625fba3..7513dfea24f43 100644 --- a/docs/pages/product/data-modeling/concepts/publicity.mdx +++ b/docs/pages/product/auth/member-level-security.mdx @@ -1,4 +1,4 @@ -# Publicity of data model entities +# Member-level security The data model serves as a facade of your data and enables running [queries][ref-queries] via a [rich set of APIs][ref-apis] by referencing data @@ -10,7 +10,7 @@ By default, all cubes, views, measures, dimensions, and segments are *public*, meaning that they can be used in API queries and they are visible during data model introspection. -## Managing publicity +## Managing member-level access You can explicitly make a data model entity public or private by setting its `public` parameter to `true` or `false`. This parameter is available for diff --git a/docs/pages/product/auth/row-level-security.mdx b/docs/pages/product/auth/row-level-security.mdx new file mode 100644 index 0000000000000..4cdd2a58c916a --- /dev/null +++ b/docs/pages/product/auth/row-level-security.mdx @@ -0,0 +1,3 @@ +# Row-level security + +TODO \ No newline at end of file diff --git a/docs/pages/product/configuration.mdx b/docs/pages/product/configuration.mdx index a8a196acae343..990706bee4110 100644 --- a/docs/pages/product/configuration.mdx +++ b/docs/pages/product/configuration.mdx @@ -152,8 +152,7 @@ Cube can be run in an insecure, development mode by setting the mode does the following: - Disables authentication checks. -- Disables access control checks based on the [publicity][ref-data-model-publicity] -of data model entities. +- Disables [member-level access control][ref-mls]. - Enables Cube Store in single instance mode. - Enables background refresh for in-memory cache and [scheduled pre-aggregations][link-scheduled-refresh]. @@ -177,6 +176,6 @@ of data model entities. [ref-dynamic-data-models]: /product/data-modeling/dynamic [ref-custom-docker-image]: /product/deployment/core#extend-the-docker-image [link-docker-env-vars]: https://docs.docker.com/compose/environment-variables/set-environment-variables/ -[ref-data-model-publicity]: /product/data-modeling/concepts/publicity +[ref-mls]: /product/auth/member-level-security [link-current-python-version]: https://github.com/cube-js/cube/blob/master/packages/cubejs-docker/latest.Dockerfile#L13 [link-current-nodejs-version]: https://github.com/cube-js/cube/blob/master/packages/cubejs-docker/latest.Dockerfile#L1 \ No newline at end of file diff --git a/docs/pages/product/data-modeling/concepts.mdx b/docs/pages/product/data-modeling/concepts.mdx index 41710996828a3..acdf13f6f68c5 100644 --- a/docs/pages/product/data-modeling/concepts.mdx +++ b/docs/pages/product/data-modeling/concepts.mdx @@ -34,7 +34,7 @@ We'll use a sample e-commerce database with two tables, `orders` and ## Cubes -A [cube][ref-cubes] represents a dataset in Cube, and is conceptually similar to a [view in +_Cubes_ represent datasets in Cube and are conceptually similar to [views in SQL][wiki-view-sql]. Cubes are usually declared in separate files with one cube per file. Typically, a cube points to a single table in your database using the [`sql_table` property][ref-schema-ref-sql-table]: @@ -82,15 +82,18 @@ cubes: -Within each cube are definitions of [dimensions][self-dimensions], -[measures][self-measures], and [segments](#segments). [Joins](#joins) are used -to define relations between cubes; [pre-aggregations](#pre-aggregations) are -designed to accelerate queries to cubes. +Each cube contains the definitions of its _members_: [dimensions](#dimensions), +[measures](#measures), and [segments](#segments). You can control the access to +cubes and their members by configuring the [member-level security][ref-mls]. + +[Joins](#joins) are used to define relations between cubes. +[Pre-aggregations](#pre-aggregations) are used to accelerate queries to cubes. +Cubes and their members can be further referenced by [views](#views). Note that cubes support [extension][ref-extending-cubes], [polymorphism][ref-polymorphic-cubes], and [data blending][ref-data-blending]. -Also, cubes should not necessarily be defined statically; you can actually build -[dynamic data models][ref-dynamic-data-models]. +Cubes can be defined statically and you can also build [dynamic data +models][ref-dynamic-data-models]. @@ -100,17 +103,23 @@ For massive [multi-tenancy][ref-multitenancy] configurations, e.g., with more th + + +See the reference documentaton for the full list of [cube parameters][ref-cubes]. + + + ## Views -Views sit on top of the data graph of cubes and create a facade of your whole +_Views_ sit on top of the data graph of cubes and create a facade of your whole data model with which data consumers can interact. They are useful for defining metrics, managing governance and data access, and controlling ambiguous join paths. -Views can **not** have their own members. Instead, use the `cubes` or `includes` -parameters to include measures and dimensions from other cubes into the view. +Views do **not** define their own members. Instead, they reference cubes by +specific join paths and include their measures and dimensions. In the example below, we create the `orders` view which includes select members from `base_orders`, `products`, and `users` cubes: @@ -180,12 +189,18 @@ views: Views do **not** define any [pre-aggregations](#pre-aggregations). Instead, they reuse pre-aggregations from underlying cubes. -View may not only be defined statically; you can actually build -[dynamic data models][ref-dynamic-data-models]. +View can be defined statically and you can also build [dynamic data +models][ref-dynamic-data-models]. + + + +See the reference documentaton for the full list of [view parameters][ref-views]. + + ## Dimensions -Dimensions represent the properties of a **single** data point in the cube. +_Dimensions_ represent the properties of a **single** data point in the cube. [The `orders` table](#top) contains only dimensions, so representing them in the `orders` cube is straightforward: @@ -282,13 +297,32 @@ cubes: -Also, [subquery dimensions][ref-subquery-dimensions] can be used to join cubes -implicitly. +[Proxy dimensions][ref-proxy-dimensions] and [subquery dimensions][ref-subquery-dimensions] +can be used for dimension composition and defining implicit [joins](#joins) to other cubes. + + + +See the reference documentaton for the full list of [dimension parameters][ref-dimensions]. + + ### Dimension types -Dimensions can be of different types. See the [dimension type -reference][ref-schema-dimension-types] for details. +Dimensions can be of different types, e.g., `string`, `number`, or `time`. Often, +data types in SQL are mapped to dimension types in the following way: + +| Data type in SQL | Dimension type in Cube | +| --- | --- | +| `timestamp`, `date`, `time` | [`time`](/reference/data-model/types-and-formats#time-1) | +| `text`, `varchar` | [`string`](/reference/data-model/types-and-formats#string-1) | +| `integer`, `bigint`, `decimal` | [`number`](/reference/data-model/types-and-formats#number-1) | +| `boolean` | [`boolean`](/reference/data-model/types-and-formats#boolean-1) | + + + +See the [dimension type reference][ref-ref-dimension-types] for details. + + ### Time dimensions @@ -373,7 +407,7 @@ Time dimensions are essential to enabling performance boosts such as ## Measures -Measures represent the properties of a **set of data points** in the cube. To +_Measures_ represent the properties of a **set of data points** in the cube. To add a measure called `count` to our `orders` cube, for example, we can do the following: @@ -434,12 +468,19 @@ cubes: -### Measure types +[Calculated measures][ref-calculated-measures] and [subquery dimensions][ref-subquery-dimensions] +can be used for measure composition. -Measures can be of different types. See the [measure type -reference][ref-schema-measure-types] for details. + -Often, aggregate functions in SQL are mapped to measure types in the following way: +See the reference documentaton for the full list of [measure parameters][ref-measures]. + + + +### Measure types + +Measures can be of different types, e.g., `count`, `sum`, or `number`. Often, +aggregate functions in SQL are mapped to measure types in the following way: | Aggregate function in SQL | Measure type in Cube | | --- | --- | @@ -455,6 +496,12 @@ Often, aggregate functions in SQL are mapped to measure types in the following w | `SUM` | [`sum`](/reference/data-model/types-and-formats#sum) | | Any function returning a timestamp, e.g., `MAX(time)` | [`time`](/reference/data-model/types-and-formats#time) | + + +See the [measure type reference][ref-ref-measure-types] for details. + + + ### Measure additivity Additivity is a property of measures that detemines whether measure values, @@ -571,7 +618,7 @@ an impact on [pre-aggregation matching][ref-matching-preaggs]. ## Joins -Joins define the relationships between cubes, which then allows accessing and +_Joins_ define the relationships between cubes, which then allows accessing and comparing properties from two or more cubes at the same time. In Cube, all joins are `LEFT JOIN`s. @@ -619,13 +666,20 @@ cubes: There are three [types of join relationships][ref-schema-ref-joins-types] (`one_to_one`, `one_to_many`, and `many_to_one`) and a few [other -concepts][ref-working-with-joins]. +concepts][ref-working-with-joins] such as the direction of joins and trasitive +joins pitfalls. + + + +See the reference documentaton for the full list of [join parameters][ref-joins]. + + ## Segments -Segments are filters that are predefined in the data model instead of [a Cube -query][ref-backend-query-filters]. They allow simplifying Cube queries and make -it easy to re-use common filters across a variety of queries. +_Segments_ are pre-defined filters that are kept within the data model instead of +[a Cube query][ref-backend-query-filters]. They help to simplify queries and make +it easy to reuse common filters across a variety of queries. To add a segment which limits results to completed orders, we can do the following: @@ -656,11 +710,17 @@ cubes: + + +See the reference documentaton for the full list of [segment parameters][ref-segments]. + + + ## Pre-aggregations -Pre-aggregations are a powerful way of caching frequently-used, expensive -queries and keeping the cache up-to-date on a periodic basis. Within a data -model, they are defined under the `pre_aggregations` property: +_Pre-aggregations_ provide a powerful way to accelerate frequently used queries +and keep the cache up-to-date. Within a data model, they are defined using the +`pre_aggregations` property: @@ -699,30 +759,41 @@ cubes: A more thorough introduction can be found in [Getting Started with Pre-Aggregations][ref-caching-preaggs-intro]. + + +See the reference documentaton for the full list of [pre-aggregation +parameters][ref-preaggs]. + + + + [ref-backend-query-filters]: /product/apis-integrations/rest-api/query-format#filters-format [ref-caching-preaggs-intro]: /product/caching/getting-started-pre-aggregations [ref-caching-use-preaggs-partition-time]: /product/caching/using-pre-aggregations#partitioning -[ref-schema-dimension-types]: - /reference/data-model/types-and-formats#dimension-types -[ref-schema-measure-types]: - /reference/data-model/types-and-formats#measure-types -[ref-schema-ref-joins-types]: - /reference/data-model/joins#relationship +[ref-ref-dimension-types]: /reference/data-model/types-and-formats#dimension-types +[ref-ref-measure-types]: /reference/data-model/types-and-formats#measure-types +[ref-schema-ref-joins-types]: /reference/data-model/joins#relationship [ref-schema-ref-sql]: /reference/data-model/cube#sql [ref-schema-ref-sql-table]: /reference/data-model/cube#sql_table [ref-tutorial-incremental-preagg]: /reference/data-model/pre-aggregations#incremental [ref-cubes]: /reference/data-model/cube +[ref-views]: /reference/data-model/view +[ref-dimensions]: /reference/data-model/dimensions +[ref-measures]: /reference/data-model/measures +[ref-joins]: /reference/data-model/joins +[ref-segments]: /reference/data-model/segments +[ref-preaggs]: /reference/data-model/pre-aggregations [ref-extending-cubes]: /product/data-modeling/concepts/code-reusability-extending-cubes [ref-polymorphic-cubes]: /product/data-modeling/concepts/polymorphic-cubes [ref-data-blending]: /product/data-modeling/concepts/data-blending [ref-dynamic-data-models]: /product/data-modeling/dynamic +[ref-proxy-dimensions]: /product/data-modeling/concepts/calculated-members#proxy-dimensions [ref-subquery-dimensions]: /product/data-modeling/concepts/calculated-members#subquery-dimensions +[ref-calculated-measures]: /product/data-modeling/concepts/calculated-members#calculated-measures [ref-working-with-joins]: /product/data-modeling/concepts/working-with-joins -[self-dimensions]: #dimensions -[self-measures]: #measures [wiki-olap]: https://en.wikipedia.org/wiki/Online_analytical_processing [wiki-view-sql]: https://en.wikipedia.org/wiki/View_(SQL) [ref-matching-preaggs]: /product/caching/matching-pre-aggregations @@ -735,4 +806,5 @@ Pre-Aggregations][ref-caching-preaggs-intro]. [ref-ref-dimension-granularities]: /reference/data-model/dimensions#granularities [ref-ref-primary-key]: /reference/data-model/dimensions#primary_key [ref-custom-granularity-recipe]: /guides/recipes/data-modeling/custom-granularity -[ref-proxy-granularity]: /product/data-modeling/concepts/calculated-members#time-dimension-granularity \ No newline at end of file +[ref-proxy-granularity]: /product/data-modeling/concepts/calculated-members#time-dimension-granularity +[ref-mls]: /product/auth/member-level-security \ No newline at end of file diff --git a/docs/pages/product/data-modeling/concepts/_meta.js b/docs/pages/product/data-modeling/concepts/_meta.js index 5ee99fa7eda18..27e102e8ed734 100644 --- a/docs/pages/product/data-modeling/concepts/_meta.js +++ b/docs/pages/product/data-modeling/concepts/_meta.js @@ -1,5 +1,4 @@ module.exports = { - "publicity": "Publicity", "calculated-members": "Calculated members", "code-reusability-extending-cubes": "Extending cubes", "polymorphic-cubes": "Polymorphic cubes", diff --git a/docs/pages/product/data-modeling/dynamic/jinja.mdx b/docs/pages/product/data-modeling/dynamic/jinja.mdx index 135a60b3afb90..be3ae80634422 100644 --- a/docs/pages/product/data-modeling/dynamic/jinja.mdx +++ b/docs/pages/product/data-modeling/dynamic/jinja.mdx @@ -245,6 +245,10 @@ If you'd like to split your Python code into several files, see +### Inline expressions + +TODO + [jinja]: https://jinja.palletsprojects.com/ [jinja-docs]: https://jinja.palletsprojects.com/en/3.1.x/templates/ diff --git a/docs/pages/reference/configuration/config.mdx b/docs/pages/reference/configuration/config.mdx index 4757bd4638ccd..8d100d4b6bbbe 100644 --- a/docs/pages/reference/configuration/config.mdx +++ b/docs/pages/reference/configuration/config.mdx @@ -1280,6 +1280,10 @@ module.exports = { +### `context_to_roles` + +TODO + ## Utility ### `logger` diff --git a/docs/pages/reference/data-model/_meta.js b/docs/pages/reference/data-model/_meta.js index 06cb280f924c8..265fda68b04f7 100644 --- a/docs/pages/reference/data-model/_meta.js +++ b/docs/pages/reference/data-model/_meta.js @@ -6,6 +6,7 @@ module.exports = { "segments": "Segments", "joins": "Joins", "pre-aggregations": "Pre-aggregations", + "data-access-policies": "Data access policies", "types-and-formats": "Types and formats", "context-variables": "Context variables" } \ No newline at end of file diff --git a/docs/pages/reference/data-model/cube.mdx b/docs/pages/reference/data-model/cube.mdx index 17800085be3b0..f4443d6928b08 100644 --- a/docs/pages/reference/data-model/cube.mdx +++ b/docs/pages/reference/data-model/cube.mdx @@ -279,11 +279,11 @@ cube(`extended_order_facts`, { -Prior to v0.33, this property was called `shown`. +Prior to v0.33, this parameter was called `shown`. -The `public` property is used to manage the visibility of a cube. Valid values +The `public` parameter is used to manage the visibility of a cube. Valid values for `public` are `true` and `false`. When set to `false`, this cube **cannot** be queried through the API. Defaults to `true`. @@ -323,7 +323,7 @@ The default values for `refresh_key` are Refresh key of a query is a concatenation of all cubes refresh keys involved in query. For rollup queries pre-aggregation table name is used as a refresh key. -You can set up a custom refresh check SQL by changing `refresh_key` property. +You can set up a custom refresh check SQL by changing `refresh_key` parameter. Often, a `MAX(updated_at_timestamp)` for OLTP data is a viable option, or examining a metadata table for whatever system is managing the data to see when it last ran. timestamp in that case. @@ -379,7 +379,7 @@ cubes: `every` - can be set as an interval with granularities `second`, `minute`, `hour`, `day`, and `week` or accept CRON string with some limitations. If you -set `every` as CRON string, you can use the `timezone` property. +set `every` as CRON string, you can use the `timezone` parameter. For example: @@ -503,15 +503,15 @@ cube(`companies`, { }); ``` -It is recommended to prefer the [`sql_table`](#parameters-sql-table) property -over the `sql` property for all cubes that are supposed to use queries like +It is recommended to prefer the [`sql_table`](#parameters-sql-table) parameter +over the `sql` parameter for all cubes that are supposed to use queries like this: `SELECT * FROM table`. ### `sql_table` -The `sql_table` property is used as a concise way for defining a cube that uses +The `sql_table` parameter is used as a concise way for defining a cube that uses a query like this: `SELECT * FROM table`. Instead of using the -[`sql`](#parameters-sql) property, use `sql_table` with the table name that this +[`sql`](#parameters-sql) parameter, use `sql_table` with the table name that this cube will query. @@ -583,6 +583,10 @@ cubes: +### `access_policy` + +The `access_policy` parameter is used to configure [data access policies][ref-ref-dap]. + [ref-config-driverfactory]: /reference/configuration/config#driverfactory [ref-config-ext-ctx]: /reference/configuration/config#extend_context @@ -602,3 +606,4 @@ cubes: [ref-ref-segments]: /reference/data-model/segments [ref-ref-joins]: /reference/data-model/joins [ref-ref-pre-aggs]: /reference/data-model/pre-aggregations +[ref-ref-dap]: /reference/data-model/data-access-policies \ No newline at end of file diff --git a/docs/pages/reference/data-model/data-access-policies.mdx b/docs/pages/reference/data-model/data-access-policies.mdx new file mode 100644 index 0000000000000..43e57a838a55c --- /dev/null +++ b/docs/pages/reference/data-model/data-access-policies.mdx @@ -0,0 +1,181 @@ +# Data access policies + +You can use the `access_policy` parameter within [cubes][ref-ref-cubes] and [views][ref-ref-views] +to configure [data access policies][ref-dap] for them. + +## Parameters + +The `access_policy` parameter should define a list of access policies. Each policy +can be configured using the following parameters: + +- [`role`](#role) defines which [data access role][ref-dap-roles] a policy applies +to. +- [`conditions`](#conditions) can be optionally used to specify when a policy +takes effect. +- [`member_level`](#member-level) and [`row_level`](#row-level) are used to +configure [member-level][ref-dap-mls] and [row-level][ref-dap-rls] access. + +### `role` + +The `role` parameter defines which [data access role][ref-dap-roles], as defined +by the [`context_to_roles`][ref-context-to-roles] configuration parameter, a +policy applies to. To define a policy that applies to all users regardless of +their roles, use the _any role_ shorthand: `role: "*"`. + +In the following example, three access policies are defined, with the first one +applying to all users and two other applying to users with `marketing` or +`finance` roles, respectively. + +```yaml +cubes: + - name: orders + # ... + + access_policy: + - role: "*" + # ... + + - role: marketing + # ... + + - role: finance + # ... +``` + +### `conditions` + +The optional `conditions` parameter, when present, defines a list of conditions +that should all be `true` in order for a policy to take effect. Each condition is +configured with an `if` parameter that is expected to reference the security +context via an [inline expression][ref-python-inline-expressions]. + +TODO: JavaScript??? Maybe it should be in Syntax, not in Python. + +In the following example, a permissive policy for all roles will only apply to +EMEA-based users, as determined by the `is_EMEA_based` attribute in the security +context: + +```yaml +cubes: + - name: orders + # ... + + access_policy: + - role: "*" + conditions: + - if: "{ securityContext.is_EMEA_based }" + member_level: + includes: "*" +``` + +You can use the `conditions` parameter to define multiple policies for the same +role. + +In the following example, the first policy provides access to a _subset of members_ +to managers who are full-time employees while the other one provides access to +_all members_ to managers who are full-time employees and have also completed a +data privacy training: + + +```yaml +cubes: + - name: orders + # ... + + access_policy: + - role: manager + conditions: + - if: "{ securityContext.is_full_time_employee }" + member_level: + includes: + - status + - count + + - role: manager + conditions: + - if: "{ securityContext.is_full_time_employee }" + - if: "{ securityContext.has_completed_privacy_training }" + member_level: + includes: "*" +``` + +### `member_level` + +The optional `member_level` parameter, when present, configures [member-level +access][ref-dap-mls] for a policy. You can provide the lists of allowed and +disallowed members with `includes` and `excludes` parameters, respectively. +You can also use the _all members_ shorthand with both of these paramaters: +`includes: "*"`, `excludes: "*"`. + +In the following example, member-level access is configured this way: + +| Users | Accessible members | +| --- | --- | +| Users with the `admin` role | All members except for `count` | +| Users with the `manager` role | All members except for `count` | +| Users with the `observer` role | All members except for `count` and `count_7d` | +| Users with the `guest` role | Only the `count_30d` measure | +| All other users | No access to this cube at all | + +```yaml +cubes: + - name: orders + # ... + + measures: + - name: count + type: count + public: false + + - name: count_7d + type: count + rolling_window: + trailing: 7 days + + - name: count_30d + type: count + rolling_window: + trailing: 30 days + + access_policy: + - role: "*" + member_level: + includes: [] + + - role: admin + + - role: manager + member_level: + includes: "*" + + - role: observer + member_level: + excludes: + - count_7d + + - role: guest + member_level: + includes: + - count_30d +``` + +Note that access policies respect [member-level security][ref-mls] restrictions +configured via `public` parameters. See [member-level access][ref-dap-mls] to +learn more about policy evaluation. + +### `row_level` + +TODO: `filters`, `or` + + + + +[ref-ref-cubes]: /reference/data-model/cube +[ref-ref-views]: /reference/data-model/view +[ref-dap]: /product/auth/data-access-policies +[ref-dap-roles]: /product/auth/data-access-policies#data-access-roles +[ref-dap-mls]: /product/auth/data-access-policies#member-level-access +[ref-dap-rls]: /product/auth/data-access-policies#row-level-access +[ref-context-to-roles]: /reference/configuration/config#context_to_roles +[ref-python-inline-expressions]: /product/data-modeling/dynamic/jinja#inline-expressions +[ref-mls]: /product/auth/member-level-security \ No newline at end of file diff --git a/docs/pages/reference/data-model/view.mdx b/docs/pages/reference/data-model/view.mdx index 8841740202a75..75d12fa50dcf3 100644 --- a/docs/pages/reference/data-model/view.mdx +++ b/docs/pages/reference/data-model/view.mdx @@ -174,7 +174,7 @@ above for `base_orders`. The other required parameter inside the `cubes` block is `includes`. Use it to list measures, dimensions, or segments you'd like to include into the view. -To include all members from a cube, use the "includes all" form: `includes: "*"`. +To include all members from a cube, use the _includes all_ shorthand: `includes: "*"`. In that case, you can also use the `excludes` parameter to list members that you'd like to exclude. @@ -254,6 +254,10 @@ To learn more about using `public` to control visibility based on security context, read the [Controlling access to cubes and views recipe][ref-recipe-control-access-cubes-views]. +### `access_policy` + +The `access_policy` parameter is used to configure [data access policies][ref-ref-dap]. + ### `includes` (deprecated) @@ -312,4 +316,5 @@ view query. /product/data-modeling/concepts/working-with-joins#directions-of-joins [ref-naming]: /product/data-modeling/syntax#naming [ref-playground]: /product/workspace/playground -[ref-apis]: /product/apis-integrations \ No newline at end of file +[ref-apis]: /product/apis-integrations +[ref-ref-dap]: /reference/data-model/data-access-policies \ No newline at end of file diff --git a/docs/redirects.json b/docs/redirects.json index 62f19d77c508f..d17711d0eb1d8 100644 --- a/docs/redirects.json +++ b/docs/redirects.json @@ -1,4 +1,9 @@ [ + { + "source": "/product/data-modeling/concepts/publicity", + "destination": "/product/auth/member-level-security", + "permanent": true + }, { "source": "/guides/recipes/data-modeling/fiscal-year-quarter-dimensions", "destination": "/guides/recipes/data-modeling/custom-granularity", diff --git a/docs/theme.config.tsx b/docs/theme.config.tsx index f10a11037a649..99eccdbc41a86 100644 --- a/docs/theme.config.tsx +++ b/docs/theme.config.tsx @@ -15,6 +15,8 @@ const repo = "https://github.com/cube-js/cube"; const branch = "master"; const path = "/docs/"; +const isDevMode = process.env.NODE_ENV === 'development' + const GoogleTagManager = () => ( <>