Skip to content

Commit

Permalink
docs(product): add configuration example for Row-Level Security
Browse files Browse the repository at this point in the history
  • Loading branch information
hassankhan committed Aug 8, 2023
1 parent 903b88d commit bab6147
Showing 1 changed file with 108 additions and 3 deletions.
111 changes: 108 additions & 3 deletions docs/docs-new/pages/product/apis-integrations/sql-api/security.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ additional security.

Cube's SQL API can also use the Security Context for [Dynamic data model
creation][ref-dynamic-schemas] or [`queryRewrite`][ref-config-queryrewrite]
property in your [`cube.js` configuration file][ref-config-js].
property in your `cube.js` configuration file.

By default, the SQL API uses the current user's Security Context, but this
behaviour can be modified so that certain users are allowed to switch. To do
Expand All @@ -50,17 +50,122 @@ First, you need to define what user is allowed to change security context:
CUBEJS_SQL_SUPER_USER=admin
```

Then configure the [`contextToAppId()`][ref-config-ctx-to-app-id],
[`queryRewrite()`][ref-config-queryrewrite] and
[`checkSqlAuth()`][ref-config-check-sql-auth] properties in your `cube.js`
configuration file:

```javascript filename="cube.js"
module.exports = {
// Create a new appId for each team, this prevents teams from seeing each
// other's data
// https://cube.dev/docs/reference/configuration/config#contexttoappid
contextToAppId: ({ securityContext }) => {
return securityContext.team;
},

// Security hook which is run before a query is executed
// https://cube.dev/docs/reference/configuration/config#queryrewrite
queryRewrite: (query, { securityContext }) => {
if (!securityContext.team) {
securityContext.team = "public";
}

return query;
},

// Here we create a new security context for each team so that we can
// use it in our data model later
checkSqlAuth: (query, username) => {
const securityContext = {
team: username,
};

return {
password: process.env.CUBEJS_SQL_PASSWORD,
securityContext: securityContext,
};
},
};
```

Now, you can use the `securityContext` in your data model:

```twig filename="model/cubes/users.yml.jinja"
{# Is the current team trusted? #}
{% set trusted_teams = ['cx', 'exec' ] %}
{% set is_trusted_team = COMPILE_CONTEXT.securityContext.team in trusted_teams %}
{# Convenient function to mask values if the current team is not trusted #}
{% macro masked(sql, is_visible) -%}
{{ sql if is_visible else "\"'--- masked ---'\"" }}
{%- endmacro %}
cubes:
- name: users
sql_table: users
public: false
dimensions:
{# This property will be masked unless the requesting user is part of a trusted team #}
- name: first_name
sql: {{ masked('first_name', is_trusted_team) }}
type: string
{# This property will be masked unless the requesting user is part of a trusted team #}
- name: last_name
sql: {{ masked('last_name', is_trusted_team) }}
type: string
- name: state
sql: state
type: string
- name: city
sql: city
type: string
- name: created_at
sql: created_at
type: time
measures:
- name: count
type: count
```

With the above now configured, we can query Cube using SQL with a user that is
part of a trusted team:

```sql
SELECT users_city, users_first_name, users_last_name
FROM users
WHERE __user = 'cx'
```

This pairs well with other security functionality in tools like Preset, which
allows configuring [row-level security to allow
access][preset-docs-rls-inclusive] to data based on the current user's security
context.

If it's not enough for your case, you define your logic for check with
`canSwitchSqlUser` property in your [`cube.js` configuration
file][ref-config-js].
[`canSwitchSqlUser` property][ref-config-can-switch-sql-user] in your `cube.js`
configuration file.

You can change security context for specific query via virtual filter on:

```sql
SELECT * FROM orders WHERE __user = 'anotheruser';
```

[preset-docs-rls-inclusive]:
https://docs.preset.io/docs/row-level-security-rls#define-inclusive-regular-rls-filter
[ref-config-can-switch-sql-user]:
/reference/configuration/config#canswitchsqluser
[ref-config-check-sql-auth]: /reference/configuration/config#checksqlauth
[ref-config-ctx-to-app-id]: /reference/configuration/config#contexttoappid
[ref-config-queryrewrite]: /reference/configuration/config#queryrewrite
[ref-dynamic-schemas]: /schema/dynamic-schema-creation
[ref-config-js]: /reference/configuration/config

0 comments on commit bab6147

Please sign in to comment.