diff --git a/docs/pages/product/apis-integrations.mdx b/docs/pages/product/apis-integrations.mdx index 22abec4f2cf90..e0fdfb05f8e14 100644 --- a/docs/pages/product/apis-integrations.mdx +++ b/docs/pages/product/apis-integrations.mdx @@ -65,8 +65,9 @@ tools][ref-viz-tools]: | Method | βœ… Supported in | | --- | --- | | [User name and password][ref-auth-user-pass] | [DAX API][ref-dax-api]
[MDX API][ref-mdx-api]
[Semantic Layer Sync][ref-sls]
[SQL API][ref-sql-api] | +| [Kerberos][ref-auth-kerberos] and [NTLM][ref-auth-ntlm] | [DAX API][ref-dax-api]
[MDX API][ref-mdx-api] | | [Identity provider][ref-auth-idp] | [Cube Cloud for Excel][ref-cube-cloud-for-excel]
[Cube Cloud for Sheets][ref-cube-cloud-for-sheets] | -| [Access token][ref-auth-tokens] | [REST API][ref-rest-api]
[GraphQL API][ref-graphql-api]
[AI API][ref-ai-api] | +| [JSON Web Token][ref-auth-jwt] | [REST API][ref-rest-api]
[GraphQL API][ref-graphql-api]
[AI API][ref-ai-api] | ## Management APIs @@ -96,6 +97,8 @@ API][ref-orchestration-api]. [ref-excel]: /product/configuration/visualization-tools/excel [ref-sheets]: /product/configuration/visualization-tools/google-sheets [ref-tableau]: /product/configuration/visualization-tools/tableau -[ref-auth-user-pass]: /product/auth#user-name-and-password -[ref-auth-idp]: /product/auth#identity-provider -[ref-auth-tokens]: /product/auth#access-token \ No newline at end of file +[ref-auth-user-pass]: /product/auth/methods/name-password +[ref-auth-idp]: /product/auth/methods/identity-provider +[ref-auth-jwt]: /product/auth/methods/jwt +[ref-auth-kerberos]: /product/auth/methods/kerberos +[ref-auth-ntlm]: /product/auth/methods/ntlm diff --git a/docs/pages/product/apis-integrations/dax-api.mdx b/docs/pages/product/apis-integrations/dax-api.mdx index c4709ae2676bd..4504f2110f98f 100644 --- a/docs/pages/product/apis-integrations/dax-api.mdx +++ b/docs/pages/product/apis-integrations/dax-api.mdx @@ -49,38 +49,27 @@ variable to `false` to disable this behavior. ## Authentication -The DAX API supports the user name and password authentication method. +The DAX API supports [Kerberos][ref-kerberos] and [NTLM][ref-ntlm] authentication +methods. -## Using DAX API with Power BI +While NTLM can be used for testing purposes, we strongly recommend configuring +Kerberos for production environments. + +## Data modeling -The DAX API works only with [views][ref-views], not cubes. +The DAX API only exposes [views][ref-views], not cubes. -### Connection methods - -Power BI provides [three methods][link-powerbi-connection] to connect to data -sources: _live connection_, _DirectQuery_, and _import mode_. - -| | Live connection | DirectQuery | Import mode | -| --- | --- | --- | --- | -| Data location | 🟒 Data source | 🟒 Data source | 🟑 Power BI | -| Data freshness | 🟒 Real-time data | 🟒 Real-time data | 🟑 Stale copy | -| Semantic model | 🟒 Up-to-date model | 🟑 Stale copy | 🟑 Stale copy | -| Queries | 🟒 Composed in UI
πŸ”΄ No custom queries | 🟒 Composed in UI
🟒 Custom queries | 🟒 Composed in UI
🟒 Custom queries | - -__It's recommended to use a _live connection_ whenever possible.__ Use _DirectQuery_ -if you need to write your own DAX queries, but be aware that you must manually -synchronize semantic models as they evolve. _Import mode_ is not recommended, as -it removes the benefits of using a semantic layer. - [ref-powerbi]: /product/configuration/visualization-tools/powerbi [link-dax]: https://learn.microsoft.com/en-us/dax/ [ref-sql-api]: /product/apis-integrations/sql-api [ref-ref-dax-api]: /product/apis-integrations/dax-api/reference [ref-views]: /product/data-modeling/concepts#views -[link-powerbi-connection]: https://learn.microsoft.com/en-us/power-bi/connect-data/service-live-connect-dq-datasets -[ref-time-dimensions]: /product/data-modeling/concepts#time-dimensions \ No newline at end of file +[ref-time-dimensions]: /product/data-modeling/concepts#time-dimensions +[ref-kerberos]: /product/auth/methods/kerberos +[ref-ntlm]: /product/auth/methods/ntlm +[ref-power-bi]: /product/configuration/visualization-tools/powerbi#connecting-from-power-bi \ No newline at end of file diff --git a/docs/pages/product/apis-integrations/javascript-sdk/reference/cubejs-client-core.mdx b/docs/pages/product/apis-integrations/javascript-sdk/reference/cubejs-client-core.mdx index 86b1ed068e191..bac73a16870d6 100644 --- a/docs/pages/product/apis-integrations/javascript-sdk/reference/cubejs-client-core.mdx +++ b/docs/pages/product/apis-integrations/javascript-sdk/reference/cubejs-client-core.mdx @@ -287,7 +287,7 @@ to give each series a unique prefix. This is useful for `blending queries` which { member: 'Stores.read', operator: 'equals', - value: ['true'], + values: ['true'], }, ], }, diff --git a/docs/pages/product/auth.mdx b/docs/pages/product/auth.mdx index be27c6d3313f4..af4655b3c26d0 100644 --- a/docs/pages/product/auth.mdx +++ b/docs/pages/product/auth.mdx @@ -1,323 +1,20 @@ # Access control -Cube supports a few methods to authenticates requests to [APIs & integrations][ref-apis]. -Usually, an API supports authentication via [one of these methods][ref-apis-methods]: +Access control in Cube involves _authentication_ and _authorization_. -* [User name and password](#user-name-and-password) (e.g., used by the [SQL API][ref-sql-api]). -* [Identity provider](#identity-provider) (e.g., used by the [Cube Cloud for Sheets][ref-cube-cloud-sheets]). -* [Access token](#access-token) (e.g., used by the [REST API][ref-rest-api]). +During authentication, Cube verifies the user's identity via one of the [supported +methods][ref-auth-methods]. Then, it assigns a [security context][ref-sec-ctx] to the +request, optionally [enriching][ref-sec-ctx-enrich] the security context with additional +attributes, e.g., via the [authentication integration][ref-auth-integration]. -Regardless of the method, the authentication flow includes the following steps: +During authorization, Cube uses the security context to enforce [member-level +security][ref-mls], [row-level security][ref-rls], and [data access policies][ref-dap]. -* User identity information (e.g., password or access token) is passed to Cube. -* Cube validates the identity information or trusts the identity provider. -* User identity information is optionally enriched with additional attributes, -such the user's role, via [authentication integration](#authentication-integration). -* Finally, the API request is associated with a [security context][ref-sec-ctx]. -It is then used to configure [member-level security][ref-mls] -and [row-level security][ref-rls] as well as set [data access policies][ref-dap]. -## User name and password - -Some visualization tools (e.g., BI tools) can pass user name and, sometimes, password to Cube. - -### Configuration - -Relevant configuration options: [`check_sql_auth`][ref-config-check-sql-auth] and [`can_switch_sql_user`][ref-config-can-switch-sql-user]. - -Relevant environment variables: `CUBEJS_SQL_USER`, `CUBEJS_SQL_PASSWORD`, `CUBEJS_SQL_SUPER_USER`. - -## Identity provider - -Some visualization tools (e.g., [Cube Cloud for Sheets][ref-cube-cloud-sheets]) implement -an OAuth 2.0 flow to authenticate users. - - - -OAuth 2.0 flow is available in Cube Cloud on [Premium and above](https://cube.dev/pricing) product tiers. - - - -During this flow, users are redirected to a login page of an identity provider (e.g., Google) -where they enter their credentials. Then, the identity provider passes the user identity -information to Cube Cloud. - -This method does not require any configuration. - -## Access token - -Some visualization tools (e.g., custom front-end applications) can pass access tokens based -on the [JSON Web Token][wiki-jwt] (JWT) standard to Cube. These tokens can be either generated -by these applications or obtained from an identity provider. Cube then validates these tokens. - -The diagram below shows how it works during the request processing in Cube: - -
- -
- -### Configuration - -Relevant configuration options: [`check_auth`][ref-config-check-auth] and [`jwt`][ref-config-jwt]. - -Relevant environment variables: `CUBEJS_API_SECRET`, `CUBEJS_JWT_KEY`, `CUBEJS_JWK_URL`, -`CUBEJS_JWT_AUDIENCE`, `CUBEJS_JWT_ISSUER`, `CUBEJS_JWT_SUBJECT`, `CUBEJS_JWT_CLAIMS_NAMESPACE`. - -### Custom authentication - -Cube allows you to provide your own JWT verification logic. You can use the -[`check_auth`][ref-config-check-auth] configuration option to verify a JWT and set the security context. - -For example, if you needed to retrieve user information from an LDAP server, -you might do the following: - -```javascript -module.exports = { - checkAuth: async (req, auth) => { - try { - const userInfo = await getUserFromLDAP(req.get("X-LDAP-User-ID")) - return { security_context: userInfo } - } - catch { - throw new Error("Could not authenticate user from LDAP") - } - } -} -``` - -A typical use case would be: - -1. A web server serves a page which needs to communicate with the Cube API. -2. The web server generates a JWT. The - server includes the token in the page or provides the token to - the frontend via an XHR request. The token is then stored in the local storage or - a cookie. -3. The token is used for calls to the Cube API. -4. The token is received by Cube, and verified using any available JWKS (if configured) -5. Once decoded, the token claims are injected into the [security - context][ref-sec-ctx]. - - - -**In development mode, the token is not required for authorization**, but you -can still use it to [pass a security context][ref-sec-ctx]. - - - -### Generating JSON Web Tokens - -Authentication tokens are generated based on your API secret. Cube CLI generates -an API Secret when a project is scaffolded and saves this value in the `.env` -file as `CUBEJS_API_SECRET`. - -You can generate two types of tokens: - -- Without security context, which will mean that all users will have the same - data access permissions. -- With security context, which will allow you to implement role-based security - models where users will have different levels of access to data. - - - -It is considered best practice to use an `exp` expiration claim to limit the -lifetime of your public tokens. [Learn more in the JWT docs][link-jwt-docs]. - - - -You can find a library to generate JWTs for your programming language -[here][link-jwt-libs]. - -In Node.js, the following code shows how to generate a token which will expire -in 30 days. We recommend using the `jsonwebtoken` package for this. - -```javascript -const jwt = require("jsonwebtoken"); -const CUBE_API_SECRET = "secret"; - -const cubeToken = jwt.sign({}, CUBE_API_SECRET, { expiresIn: "30d" }); -``` - -Then, in a web server or cloud function, create a route which generates and -returns a token. In general, you will want to protect the URL that generates -your token using your own user authentication and authorization: - -```javascript -app.use((req, res, next) => { - if (!req.user) { - res.redirect("/login"); - return; - } - next(); -}); - -app.get("/auth/cubejs-token", (req, res) => { - res.json({ - // Take note: Cube expects the JWT payload to contain an object! - token: jwt.sign(req.user, process.env.CUBEJS_API_SECRET, { - expiresIn: "1d", - }), - }); -}); -``` - -Then, on the client side, (assuming the user is signed in), fetch a token from -the web server: - -```javascript -let apiTokenPromise; - -const cubeApi = cube( - () => { - if (!apiTokenPromise) { - apiTokenPromise = fetch(`${API_URL}/auth/cubejs-token`) - .then((res) => res.json()) - .then((r) => r.token); - } - return apiTokenPromise; - }, - { - apiUrl: `${API_URL}/cubejs-api/v1`, - } -); -``` - -You can optionally store this token in local storage or in a cookie, so that you -can then use it to query the Cube API. - -### Using JSON Web Key Sets - - - -Looking for a guide on how to connect a specific identity provider? Check out -our recipes for using [Auth0][ref-recipe-auth0] or [AWS -Cognito][ref-recipe-cognito] with Cube. - - - -As mentioned previously, Cube supports verifying JWTs using industry-standard -JWKS. The JWKS can be provided either from a URL, or as a JSON object conforming -to [JWK specification RFC 7517 Section 4][link-jwk-ref], encoded as a string. - -#### Using a key as a JSON string - -Add the following to your `cube.js` configuration file: - -```javascript -module.exports = { - jwt: { - key: "", - }, -}; -``` - -Or configure the same using environment variables: - -```dotenv -CUBEJS_JWT_KEY='' -``` - -#### Using a key from a URL - - - -When using a URL to fetch the JWKS, Cube will automatically cache the response, -re-use it and update if a key rotation has occurred. - - - -Add the following to your `cube.js` configuration file: - -```javascript -module.exports = { - jwt: { - jwkUrl: "", - }, -}; -``` - -Or configure the same using environment variables: - -```dotenv -CUBEJS_JWK_URL='' -``` - -#### Verifying claims - -Cube can also verify the audience, subject and issuer claims in JWTs. Similarly -to JWK configuration, these can also be configured in the `cube.js` -configuration file: - -```javascript -module.exports = { - jwt: { - audience: "", - issuer: [""], - subject: "", - }, -}; -``` - -Using environment variables: - -```dotenv -CUBEJS_JWT_AUDIENCE='' -CUBEJS_JWT_ISSUER='' -CUBEJS_JWT_SUBJECT='' -``` - -#### Custom claims namespace - -Cube can also extract claims defined in custom namespaces. Simply specify the -namespace in your `cube.js` configuration file: - -```javascript -module.exports = { - jwt: { - claimsNamespace: "my-custom-namespace", - }, -}; -``` - -## Authentication integration - -When using Cube Cloud, you can enrich the security context with information about -an authenticated user, obtained during their authentication or loaded via an -[LDAP integration][ref-ldap-integration]. - - - -Authentication integration is available in Cube Cloud on [all product tiers](https://cube.dev/pricing). - - - -You can enable the authentication integration by navigating to the Settings β†’ Configuration -of your Cube Cloud deployment and using the Enable Cloud Auth Integration toggle. - - -[wiki-jwt]: https://en.wikipedia.org/wiki/JSON_Web_Token -[link-jwt-docs]: https://github.com/auth0/node-jsonwebtoken#token-expiration-exp-claim -[link-jwt-libs]: https://jwt.io/#libraries-io -[link-jwk-ref]: https://tools.ietf.org/html/rfc7517#section-4 -[ref-config-check-auth]: /reference/configuration/config#check_auth -[ref-config-jwt]: /reference/configuration/config#jwt -[ref-config-check-sql-auth]: /reference/configuration/config#check_sql_auth -[ref-config-can-switch-sql-user]: /reference/configuration/config#can_switch_sql_user -[ref-config-migrate-cube]: - /product/configuration#migration-from-express-to-docker-template -[ref-recipe-auth0]: /guides/recipes/auth/auth0-guide -[ref-recipe-cognito]: /guides/recipes/auth/aws-cognito +[ref-auth-methods]: /product/auth/methods [ref-sec-ctx]: /product/auth/context -[ref-apis]: /product/apis-integrations -[ref-apis-methods]: /product/apis-integrations#authentication-methods -[ref-rest-api]: /product/apis-integrations/rest-api -[ref-sql-api]: /product/apis-integrations/sql-api +[ref-sec-ctx-enrich]: /product/auth/context#enriching-the-security-context +[ref-auth-integration]: /product/auth/context#authentication-integration [ref-dap]: /product/auth/data-access-policies [ref-mls]: /product/auth/member-level-security -[ref-rls]: /product/auth/row-level-security -[ref-auth-sso]: /product/workspace/sso -[ref-ldap-integration]: /product/workspace/sso#ldap-integration -[ref-cube-cloud-sheets]: /product/apis-integrations/google-sheets \ No newline at end of file +[ref-rls]: /product/auth/row-level-security \ No newline at end of file diff --git a/docs/pages/product/auth/_meta.js b/docs/pages/product/auth/_meta.js index 68c456f8a9cf7..0285fb2eb41ea 100644 --- a/docs/pages/product/auth/_meta.js +++ b/docs/pages/product/auth/_meta.js @@ -1,4 +1,5 @@ module.exports = { + "methods": "Authentication", "context": "Security context", "member-level-security": "Member-level security", "row-level-security": "Row-level security", diff --git a/docs/pages/product/auth/context.mdx b/docs/pages/product/auth/context.mdx index 0bd1de4905d2a..8a2b0e86c8869 100644 --- a/docs/pages/product/auth/context.mdx +++ b/docs/pages/product/auth/context.mdx @@ -260,6 +260,32 @@ to test access control rules. The [Developer Playground][ref-devtools-playground] allows you to set your own JWTs, or you can build one from a JSON object. +## Enriching the security context + +Sometimes it is convenient to enrich the security context with additional attributes +before it is used to evaluate access control rules. + +### Extending the security context + +You can use the [`extend_context`][ref-extend-context] configuration option to +enrich the security context with additional attributes. + +### Authentication integration + +When using Cube Cloud, you can enrich the security context with information about +an authenticated user, obtained during their authentication or loaded via an +[LDAP integration][ref-ldap-integration]. + + + +Authentication integration is available in Cube Cloud on [all product tiers](https://cube.dev/pricing). + + + +You can enable the authentication integration by navigating to the Settings β†’ Configuration +of your Cube Cloud deployment and using the Enable Cloud Auth Integration toggle. + + [link-auth0-jwks]: https://auth0.com/docs/tokens/json-web-tokens/json-web-key-sets [link-multitenancy]: /product/configuration/advanced/multitenancy @@ -273,3 +299,4 @@ build one from a JSON object. /product/workspace/playground#editing-the-security-context [ref-auth-integration]: /product/auth#authentication-integration [ref-ldap-integration]: /product/workspace/sso#ldap-integration +[ref-extend-context]: /reference/configuration/config#extend_context \ No newline at end of file diff --git a/docs/pages/product/auth/methods.mdx b/docs/pages/product/auth/methods.mdx new file mode 100644 index 0000000000000..32bfcec90cc42 --- /dev/null +++ b/docs/pages/product/auth/methods.mdx @@ -0,0 +1,37 @@ +# Authentication methods + +Cube supports the following methods to authenticate requests to [APIs & integrations][ref-apis]. +Usually, an API supports authentication via [one of these methods][ref-apis-methods]: + +* [User name and password][ref-name-password] (e.g., used by the [SQL API][ref-sql-api]). +* [Kerberos][ref-kerberos] and [NTLM][ref-ntlm] (e.g., used by the [DAX API][ref-dax-api] and [MDX API][ref-mdx-api]). +* [Identity provider][ref-identity-provider] (e.g., used by the [Cube Cloud for Sheets][ref-cube-cloud-sheets]). +* [JSON Web Token][ref-jwt] (e.g., used by the [REST API][ref-rest-api]). + +## Authentication flow + +Regardless of the method, the authentication flow includes the following steps: + +* User identity information (e.g., password or access token) is passed to Cube. +* Cube validates the identity information. +* Cube associates the API request with a [security context][ref-sec-ctx]. +* The security context is used to configure [member-level security][ref-mls] +and [row-level security][ref-rls] as well as set [data access policies][ref-dap]. + + +[ref-apis]: /product/apis-integrations +[ref-apis-methods]: /product/apis-integrations#authentication-methods +[ref-rest-api]: /product/apis-integrations/rest-api +[ref-sql-api]: /product/apis-integrations/sql-api +[ref-dax-api]: /product/apis-integrations/dax-api +[ref-mdx-api]: /product/apis-integrations/mdx-api +[ref-cube-cloud-sheets]: /product/apis-integrations/google-sheets +[ref-name-password]: /product/auth/methods/name-password +[ref-kerberos]: /product/auth/methods/kerberos +[ref-ntlm]: /product/auth/methods/ntlm +[ref-identity-provider]: /product/auth/methods/identity-provider +[ref-jwt]: /product/auth/methods/jwt +[ref-sec-ctx]: /product/auth/context +[ref-dap]: /product/auth/data-access-policies +[ref-mls]: /product/auth/member-level-security +[ref-rls]: /product/auth/row-level-security \ No newline at end of file diff --git a/docs/pages/product/auth/methods/_meta.js b/docs/pages/product/auth/methods/_meta.js new file mode 100644 index 0000000000000..3904893959cc2 --- /dev/null +++ b/docs/pages/product/auth/methods/_meta.js @@ -0,0 +1,7 @@ +module.exports = { + "name-password": "Name and password", + "kerberos": "Kerberos", + "ntlm": "NTLM", + "identity-provider": "Identity provider", + "jwt": "JSON Web Token" +} \ No newline at end of file diff --git a/docs/pages/product/auth/methods/identity-provider.mdx b/docs/pages/product/auth/methods/identity-provider.mdx new file mode 100644 index 0000000000000..7ea04967126e6 --- /dev/null +++ b/docs/pages/product/auth/methods/identity-provider.mdx @@ -0,0 +1,21 @@ +# Identity provider + +Some visualization tools (e.g., [Cube Cloud for Sheets][ref-cube-cloud-sheets]) implement +an OAuth 2.0 flow to authenticate users. + + + +OAuth 2.0 flow is available in Cube Cloud on [Premium and above](https://cube.dev/pricing) product tiers. + + + +During this flow, users are redirected to a login page of an identity provider (e.g., Google) +where they enter their credentials. Then, the identity provider passes the user identity +information to Cube Cloud. + +## Configuration + +This method does not require any configuration. + + +[ref-cube-cloud-sheets]: /product/apis-integrations/google-sheets \ No newline at end of file diff --git a/docs/pages/product/auth/methods/jwt.mdx b/docs/pages/product/auth/methods/jwt.mdx new file mode 100644 index 0000000000000..24f3c4839da71 --- /dev/null +++ b/docs/pages/product/auth/methods/jwt.mdx @@ -0,0 +1,248 @@ +# JSON Web Token authentication + +Some visualization tools (e.g., custom front-end applications) can pass access tokens based +on the [JSON Web Token][wiki-jwt] (JWT) standard to Cube. These tokens can be either generated +by these applications or obtained from an identity provider. Cube then validates these tokens. + +The diagram below shows how it works during the request processing in Cube: + +
+ +
+ +## Configuration + +Relevant configuration options: [`check_auth`][ref-config-check-auth] and [`jwt`][ref-config-jwt]. + +Relevant environment variables: `CUBEJS_API_SECRET`, `CUBEJS_JWT_KEY`, `CUBEJS_JWK_URL`, +`CUBEJS_JWT_AUDIENCE`, `CUBEJS_JWT_ISSUER`, `CUBEJS_JWT_SUBJECT`, `CUBEJS_JWT_CLAIMS_NAMESPACE`. + +## Custom authentication + +Cube allows you to provide your own JWT verification logic. You can use the +[`check_auth`][ref-config-check-auth] configuration option to verify a JWT and set the security context. + +For example, if you needed to retrieve user information from an LDAP server, +you might do the following: + +```javascript +module.exports = { + checkAuth: async (req, auth) => { + try { + const userInfo = await getUserFromLDAP(req.get("X-LDAP-User-ID")) + return { security_context: userInfo } + } + catch { + throw new Error("Could not authenticate user from LDAP") + } + } +} +``` + +A typical use case would be: + +1. A web server serves a page which needs to communicate with the Cube API. +2. The web server generates a JWT. The + server includes the token in the page or provides the token to + the frontend via an XHR request. The token is then stored in the local storage or + a cookie. +3. The token is used for calls to the Cube API. +4. The token is received by Cube, and verified using any available JWKS (if configured) +5. Once decoded, the token claims are injected into the [security + context][ref-sec-ctx]. + + + +**In development mode, the token is not required for authorization**, but you +can still use it to [pass a security context][ref-sec-ctx]. + + + +## Generating JSON Web Tokens + +Authentication tokens are generated based on your API secret. Cube CLI generates +an API Secret when a project is scaffolded and saves this value in the `.env` +file as `CUBEJS_API_SECRET`. + +You can generate two types of tokens: + +- Without security context, which will mean that all users will have the same + data access permissions. +- With security context, which will allow you to implement role-based security + models where users will have different levels of access to data. + + + +It is considered best practice to use an `exp` expiration claim to limit the +lifetime of your public tokens. [Learn more in the JWT docs][link-jwt-docs]. + + + +You can find a library to generate JWTs for your programming language +[here][link-jwt-libs]. + +In Node.js, the following code shows how to generate a token which will expire +in 30 days. We recommend using the `jsonwebtoken` package for this. + +```javascript +const jwt = require("jsonwebtoken"); +const CUBE_API_SECRET = "secret"; + +const cubeToken = jwt.sign({}, CUBE_API_SECRET, { expiresIn: "30d" }); +``` + +Then, in a web server or cloud function, create a route which generates and +returns a token. In general, you will want to protect the URL that generates +your token using your own user authentication and authorization: + +```javascript +app.use((req, res, next) => { + if (!req.user) { + res.redirect("/login"); + return; + } + next(); +}); + +app.get("/auth/cubejs-token", (req, res) => { + res.json({ + // Take note: Cube expects the JWT payload to contain an object! + token: jwt.sign(req.user, process.env.CUBEJS_API_SECRET, { + expiresIn: "1d", + }), + }); +}); +``` + +Then, on the client side, (assuming the user is signed in), fetch a token from +the web server: + +```javascript +let apiTokenPromise; + +const cubeApi = cube( + () => { + if (!apiTokenPromise) { + apiTokenPromise = fetch(`${API_URL}/auth/cubejs-token`) + .then((res) => res.json()) + .then((r) => r.token); + } + return apiTokenPromise; + }, + { + apiUrl: `${API_URL}/cubejs-api/v1`, + } +); +``` + +You can optionally store this token in local storage or in a cookie, so that you +can then use it to query the Cube API. + +## Using JSON Web Key Sets + + + +Looking for a guide on how to connect a specific identity provider? Check out +our recipes for using [Auth0][ref-recipe-auth0] or [AWS +Cognito][ref-recipe-cognito] with Cube. + + + +As mentioned previously, Cube supports verifying JWTs using industry-standard +JWKS. The JWKS can be provided either from a URL, or as a JSON object conforming +to [JWK specification RFC 7517 Section 4][link-jwk-ref], encoded as a string. + +### Using a key as a JSON string + +Add the following to your `cube.js` configuration file: + +```javascript +module.exports = { + jwt: { + key: "", + }, +}; +``` + +Or configure the same using environment variables: + +```dotenv +CUBEJS_JWT_KEY='' +``` + +### Using a key from a URL + + + +When using a URL to fetch the JWKS, Cube will automatically cache the response, +re-use it and update if a key rotation has occurred. + + + +Add the following to your `cube.js` configuration file: + +```javascript +module.exports = { + jwt: { + jwkUrl: "", + }, +}; +``` + +Or configure the same using environment variables: + +```dotenv +CUBEJS_JWK_URL='' +``` + +### Verifying claims + +Cube can also verify the audience, subject and issuer claims in JWTs. Similarly +to JWK configuration, these can also be configured in the `cube.js` +configuration file: + +```javascript +module.exports = { + jwt: { + audience: "", + issuer: [""], + subject: "", + }, +}; +``` + +Using environment variables: + +```dotenv +CUBEJS_JWT_AUDIENCE='' +CUBEJS_JWT_ISSUER='' +CUBEJS_JWT_SUBJECT='' +``` + +### Custom claims namespace + +Cube can also extract claims defined in custom namespaces. Simply specify the +namespace in your `cube.js` configuration file: + +```javascript +module.exports = { + jwt: { + claimsNamespace: "my-custom-namespace", + }, +}; +``` + + +[wiki-jwt]: https://en.wikipedia.org/wiki/JSON_Web_Token +[link-jwt-docs]: https://github.com/auth0/node-jsonwebtoken#token-expiration-exp-claim +[link-jwt-libs]: https://jwt.io/#libraries-io +[link-jwk-ref]: https://tools.ietf.org/html/rfc7517#section-4 +[ref-config-check-auth]: /reference/configuration/config#check_auth +[ref-config-jwt]: /reference/configuration/config#jwt +[ref-recipe-auth0]: /guides/recipes/auth/auth0-guide +[ref-recipe-cognito]: /guides/recipes/auth/aws-cognito +[ref-sec-ctx]: /product/auth/context \ No newline at end of file diff --git a/docs/pages/product/auth/methods/kerberos.mdx b/docs/pages/product/auth/methods/kerberos.mdx new file mode 100644 index 0000000000000..2f8994023fe73 --- /dev/null +++ b/docs/pages/product/auth/methods/kerberos.mdx @@ -0,0 +1,134 @@ +# Kerberos authentication + +[Kerberos][link-kerberos] is the most common authentication method for Windows environments. +It can be used to authenticate requests to [DAX API][ref-dax-api] and [MDX API][ref-mdx-api]. + + + +DAX API and MDX API are available in Cube Cloud on [Enterprise and above](https://cube.dev/pricing) product tiers. +They also require the M [deployment tier](/product/deployment/cloud/pricing#deployment-tiers). + + + +On the diagram below, Kerberos is used to authenticate requests from Power BI Desktop (step 2): + +![](https://ucarecdn.com/a1928cd7-51b5-4d0c-b6b3-7f97eb94b41e/) + +## Authentication flow + +__Kerberos is the recommended method to authenticate Power BI Desktop requests.__ + + +It works as follows: + +* Power BI Desktop is launched normally, under the Windows domain account of the user. +* When connecting the DAX API, Windows verifies whether its [service principal +name](#registering-the-spn) is registered in the domain. +* Once verified, the Key Distribution Center issues a Kerberos ticket for the user. +* This ticket is transmitted to the DAX API in the request authorization header. +* The DAX API [decrypts and verifies](#configuring-the-deployment) the Kerberos ticket. +* Finally, the user principal name is passed for [further verification](#verifying-the-credentials). + +## Configuration + +Configuring Kerberos authentication includes the following steps: + +* [Obtain a Windows Server machine](#obtaining-a-windows-machine) to use during the next steps. +* [Register the service principal name](#registering-the-spn). +* [Generate a keytab](#generating-the-keytab). +* [Configure the deployment](#configuring-the-deployment) to verify Kerberos tickets. +* Optionally, [customize the authentication](#verifying-the-credentials). + +### Obtaining a Windows machine + +To perform the next steps, you need a Windows Server virtual machine: + +* It should be joined to the same domain as the organization’s users. +* It should have the [RSAT][link-rsat] feature enabled. +* It should be able to reach the [Key Distribution Center][link-kdc] (KDC). For example, +on Azure, this virtual machine can be created in the `aadds-vnet` subnet. + +You should log in to this Windows Server machine using the account that has +[AAD DC Administrators][link-aad-dc-admins] group membership. + +It is also recommended to create a custom organizational unit (OU) and a new user +in this OU that will act as the service account. + +On the screenshot below, the `mdax-api-svc-account` user is created in the +`MyCustomOU` OU in the `CUBE` domain: + + + +### Registering the SPN + +A [service principal name][link-spn] (SPN) is a unique identifier of a service instance. +Kerberos authentication uses SPNs to associate a service instance with a service sign-in account. + +First, obtain your Cube Cloud deployment’s domain by going to Settings β†’ General +and copying the value in the Custom domain section. + +Then, use the [`setspn` command][link-setspn] to register the Service Principal Name +for the DAX API. + +In the following example, the web service (`HTTP`) SPN on the +`redundant-brohman.gcp-us-central1.cubecloudapp.dev` domain is registered for the +`mdax-api-svc-account` user in the `CUBE` domain: + +``` +setspn -S HTTP/redundant-brohman.gcp-us-central1.cubecloudapp.dev CUBE\mdax-api-svc-account +``` + +### Generating the keytab + +The [keytab][link-keytab-file] file contains information needed to decrypt the Kerberos +token. + +First, use the [`ktpass` command][link-ktpass] to generate the keytab file. You will be +prompted to enter the password for the specified user: + +``` +ktpass /out kerberos.keytab /princ HTTP/redundant-brohman.gcp-us-central1.cubecloudapp.dev@CUBE.DEV /mapuser mdax-api-svc-account /crypto All /ptype KRB5_NT_PRINCIPAL /pass * +``` + +Then, convert the keytab to a Base64-encoded string. For example, the following PowerShell +script will do the conversion and put the result in the clipboard: + +```ps +$Path = "C:\kerberos.keytab" +[Convert]::ToBase64String([System.IO.File]::ReadAllBytes($Path)) | Set-Clipboard +``` + +### Configuring the deployment + +Go to Settings β†’ Environment Variables of your Cube Cloud deployment and set +the following environment variables to facilitate the verification of Kerberos tickets: + +| Environment variable | Value | +| --- | --- | +| `CUBE_XMLA_KRB5_KEYTAB_B64` | Base64-encoded keytab | +| `CUBE_XMLA_SPN` | `HTTP` | +| `KRB5_KTNAME` | `/cube/conf/kerberos.keytab` | + +### Verifying the credentials + +By default, `CUBEJS_SQL_USER` and `CUBEJS_SQL_PASSWORD` environment variables are used +to verify the passed credentials. You can also customize the authentication by using the +[`check_sql_auth` configuration option][ref-config-check-sql-auth]. + +Once the deployment is ready, you can test the Kerberos authentication by [connecting +from Power BI][ref-power-bi] to the DAX API. + + +[ref-check-sql-auth]: /reference/configuration/config#check_sql_auth +[link-rsat]: https://learn.microsoft.com/en-us/troubleshoot/windows-server/system-management-components/remote-server-administration-tools +[link-kdc]: https://learn.microsoft.com/en-us/windows/win32/secauthn/key-distribution-center +[link-aad-dc-admins]: https://learn.microsoft.com/en-us/entra/identity/domain-services/tutorial-create-instance-advanced#configure-an-administrative-group +[link-spn]: https://learn.microsoft.com/en-us/windows/win32/ad/service-principal-names +[link-setspn]: https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-r2-and-2012/cc731241(v=ws.11) +[link-keytab-file]: https://web.mit.edu/Kerberos/krb5-1.16/doc/basic/keytab_def.html +[link-ktpass]: https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/ktpass +[ref-power-bi]: /product/configuration/visualization-tools/powerbi#connecting-from-power-bi +[link-kerberos]: https://en.wikipedia.org/wiki/Kerberos_(protocol)#Microsoft_Windows +[ref-dax-api]: /product/apis-integrations/dax-api +[ref-mdx-api]: /product/apis-integrations/mdx-api +[ref-config-check-sql-auth]: /reference/configuration/config#check_sql_auth \ No newline at end of file diff --git a/docs/pages/product/auth/methods/name-password.mdx b/docs/pages/product/auth/methods/name-password.mdx new file mode 100644 index 0000000000000..fcb3cbe669586 --- /dev/null +++ b/docs/pages/product/auth/methods/name-password.mdx @@ -0,0 +1,18 @@ +# User name and password + +Some visualization tools (e.g., BI tools) can pass user name and, sometimes, password +to Cube. + +## Configuration + +By default, `CUBEJS_SQL_USER` and `CUBEJS_SQL_PASSWORD` environment variables are used +to verify the credentials. You can also customize the authentication by using the +[`check_sql_auth` configuration option][ref-config-check-sql-auth]. + +Also, the `CUBEJS_SQL_SUPER_USER` environment variable or the [`can_switch_sql_user` +configuration option][ref-config-can-switch-sql-user] can be used to ensure that the +user name can be changed after the initial authentication. + + +[ref-config-check-sql-auth]: /reference/configuration/config#check_sql_auth +[ref-config-can-switch-sql-user]: /reference/configuration/config#can_switch_sql_user \ No newline at end of file diff --git a/docs/pages/product/auth/methods/ntlm.mdx b/docs/pages/product/auth/methods/ntlm.mdx new file mode 100644 index 0000000000000..447d6d920126a --- /dev/null +++ b/docs/pages/product/auth/methods/ntlm.mdx @@ -0,0 +1,98 @@ +# NTLM authentication + +[NTLM][link-ntlm] is an authentication method developed by Microsoft that can be used to +authenticate requests to [DAX API][ref-dax-api] and [MDX API][ref-mdx-api]. + + + +DAX API and MDX API are available in Cube Cloud on [Enterprise and above](https://cube.dev/pricing) product tiers. +They also require the M [deployment tier](/product/deployment/cloud/pricing#deployment-tiers). + + + +On the diagram below, NTLM is used to authenticate requests from Power BI Service that +come through the [on-premises data gateway][link-power-bi-opdg] (step 6): + +![](https://ucarecdn.com/a1928cd7-51b5-4d0c-b6b3-7f97eb94b41e/) + +## Authentication flow + +The NTLM authentication can be used with Power BI Desktop or with Power BI Service and +the [on-premises data gateway][link-power-bi-opdg]. + +### Power BI Desktop + +Initiated by Power BI Desktop, NTLM authentication works as follows: + +* Power BI Desktop is launched under a specific user account via the `runas` command. +* Power BI Desktop performs an NTLM challenge-response authentication and passes the +credentials of that account to the Cube Cloud deployment. +* The Cube Cloud deployment [verifies the credentials](#verifying-the-credentials). + +In the following example, Power BI Desktop is launched under the `cube` user: + +```bash +# Run Power BI Desktop as the `cube` user +runas /user:cube "C:\Program Files\Microsoft Power BI Desktop\bin\PBIDesktop.exe" + +# Run a specific report in Power BI Desktop as the `cube` user +runas /user:cube "C:\Program Files\Microsoft Power BI Desktop\bin\PBIDesktop.exe \"C:\Users\Administrator\Desktop\Dashboard.pbix\"" +``` + +__This flow should only be used for testing purposes.__ Note that, when Power BI Desktop +is started as a user different from the currently logged-in Windows account, it may +encounter permission issues, e.g., when saving files on network drives. + +In a production environment, Power BI Desktop should be used with [Kerberos +authentication][ref-kerberos]. + +### Power BI Service + +Initiated by Power BI Service, NTLM authentication works as follows: + +* [The gateway is configured](#installing-the-gateway) with a master user account. +* When users interact with a Power BI report in Power BI Service, their _user principal +name_ (UPN) is passed to the gateway. +* The gateway performs an NTLM challenge-response authentication and passes the the +credentials of the master user account to the Cube Cloud deployment. It also passes the +UPN of the interacting user. +* The Cube Cloud deployment [verifies the credentials](#verifying-the-credentials) and +changes the user name to the UPN of the interacting user. + +__This is the recommended way to authenticate Power BI Service requests.__ + +## Configuration + +Using NTLM authentication requires configuring the deployment to [verify the +credentials](#verifying-the-credentials). + +To use NTLM authentication with Power BI Service, you also need to [install the on-premises +data gateway](#installing-the-gateway) first. + +### Installing the gateway + +You need to have the [on-premises data gateway][link-power-bi-opdg] installed +on a Windows Server machine. + +It should be configured to authenticate with a _master user_ account. It can be a +local user on the machine or a domain user. + +### Verifying the credentials + +By default, `CUBEJS_SQL_USER` and `CUBEJS_SQL_PASSWORD` environment variables are used +to verify the passed credentials. You can also customize the authentication by using the +[`check_sql_auth` configuration option][ref-config-check-sql-auth]. + +Also, the `CUBEJS_SQL_SUPER_USER` environment variable or the [`can_switch_sql_user` +configuration option][ref-config-can-switch-sql-user] can be used to ensure that the +user name can be changed to the UPN of the interacting user only if proper credentials +of the master user account were passed. + + +[link-ntlm]: https://en.wikipedia.org/wiki/NTLM +[ref-dax-api]: /product/apis-integrations/dax-api +[ref-mdx-api]: /product/apis-integrations/mdx-api +[link-power-bi-opdg]: https://learn.microsoft.com/en-us/power-bi/connect-data/service-gateway-onprem +[ref-kerberos]: /product/auth/methods/kerberos +[ref-config-check-sql-auth]: /reference/configuration/config#check_sql_auth +[ref-config-can-switch-sql-user]: /reference/configuration/config#can_switch_sql_user diff --git a/docs/pages/product/configuration/visualization-tools/powerbi.mdx b/docs/pages/product/configuration/visualization-tools/powerbi.mdx index d368f06440ac0..c0bfc933dcf2e 100644 --- a/docs/pages/product/configuration/visualization-tools/powerbi.mdx +++ b/docs/pages/product/configuration/visualization-tools/powerbi.mdx @@ -2,20 +2,17 @@ [Microsoft Power BI][link-powerbi] is a popular business intelligence tool. -Cube Cloud works with both [Power BI Desktop and Power BI service][link-powerbi-desktop-vs-service]. -If you're using Power BI service, you need to set up an [on-premises data gateway][link-powerbi-gateway]. +Cube Cloud works with both [Power BI Desktop and Power BI Service][link-powerbi-desktop-vs-service]. +If you're using Power BI Service, you need to set up an [on-premises data gateway][link-powerbi-gateway]. -## Connect from Cube Cloud +## Connect to the DAX API -Cube Cloud provides the [DAX API][ref-dax-api] to connect to Power BI. - -Navigate to the [Integrations][ref-integrations-tools] page, click Connect to Cube, -and choose Microsoft Power BI to get detailed instructions. +Cube Cloud provides the [DAX API][ref-dax-api] for the native Power BI connectivity. @@ -25,36 +22,47 @@ method. -## Connect from Cube Core +In Power BI Desktop, choose the SQL Server Analysis Services database option +when connecting to a data source. Then, enter the DAX API credentials and choose +Windows authentication. It accomodates both [Kerberos][ref-kerberos] and +[NTLM][ref-ntlm] methods. -You can connect a Cube deployment to Power BI using the [SQL API][ref-sql-api]. -However, it would not provide the same experience as the DAX API. +To find your DAX API credentials, go to the [Integrations][ref-integrations-apis] page, +click API credentials, and choose the DAX API tab. -In Cube Core, the SQL API is disabled by default. Enable it and [configure -the credentials](/product/apis-integrations/sql-api#configuration) to -connect to Power BI. +### Authentication methods -## Connecting from Power BI +Cube Cloud supports the following authentication methods for Power BI: -### DAX API +| Application | Authentication | Notes | +| --- | --- | --- | +| Power BI Desktop | [NTLM][ref-ntlm-desktop] | 🟑 Works well for testing purposes | +| Power BI Desktop | [Kerberos][ref-kerberos] | 🟒 Recommended for production | +| Power BI Service | [NTLM][ref-ntlm] + [Kerberos][ref-kerberos] | 🟒 Recommended for production.
Requires [on-premises data gateway][ref-opdg] | -In Power BI, choose the SQL Server Analysis Services database option -when connecting to a data source. The, enter the credentials. +### Connection methods -To find your DAX API credentials, go to the [Integrations][ref-integrations-apis] page, -click API credentials, and choose the DAX API tab. +Power BI provides [three methods][link-powerbi-connection] to connect to data +sources: _live connection_, _DirectQuery_, and _import mode_. - +| | Live connection | DirectQuery | Import mode | +| --- | --- | --- | --- | +| Data location | 🟒 Data source | 🟒 Data source | 🟑 Power BI | +| Data freshness | 🟒 Real-time data | 🟒 Real-time data | 🟑 Stale copy | +| Semantic model | 🟒 Up-to-date model | 🟑 Stale copy | 🟑 Stale copy | +| Queries | 🟒 Composed in UI
πŸ”΄ No custom queries | 🟒 Composed in UI
🟒 Custom queries | 🟒 Composed in UI
🟒 Custom queries | -It's not recommended to import data into Power BI when connecting to Cube. -Use a _live connection_ whenever possible. [Read more][ref-powerbi-connection-methods] -about pros and cons of these methods. +__It's recommended to use a _live connection_ whenever possible.__ Use _DirectQuery_ +if you need to write your own DAX queries, but be aware that you must manually +synchronize semantic models as they evolve. _Import mode_ is not recommended, as +it removes the benefits of using a semantic layer. -
+## Connect to the SQL API -### SQL API +You can connect a Cube deployment to Power BI using the [SQL API][ref-sql-api] +as if Cube is a Postgres database. It would provide much more limited functionality +than the DAX API. However, this is the only option when using Cube Core. -Power BI can also connect to Cube as to a Postgres database. [link-powerbi]: https://www.microsoft.com/en-gb/power-platform/products/power-bi/ [link-powerbi-desktop-vs-service]: https://learn.microsoft.com/en-us/power-bi/fundamentals/service-service-vs-desktop @@ -64,4 +72,9 @@ Power BI can also connect to Cube as to a Postgres database. [ref-integrations-apis]: /product/workspace/integrations#view-api-credentials [ref-sql-api]: /product/apis-integrations/sql-api [ref-sls]: /product/apis-integrations/semantic-layer-sync -[ref-powerbi-connection-methods]: /product/apis-integrations/dax-api#connection-methods \ No newline at end of file +[ref-powerbi-connection-methods]: /product/apis-integrations/dax-api#connection-methods +[ref-kerberos]: /product/auth/methods/kerberos +[ref-ntlm]: /product/auth/methods/ntlm +[ref-ntlm-desktop]: /product/auth/methods/ntlm#power-bi-desktop +[link-powerbi-connection]: https://learn.microsoft.com/en-us/power-bi/connect-data/service-live-connect-dq-datasets +[ref-opdg]: /product/auth/methods/ntlm#configuration \ No newline at end of file