docs: EE console SSO troubleshooting and improvements

PR-URL: https://github.com/hasura/graphql-engine-mono/pull/9685
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Rob Dominguez <24390149+robertjdominguez@users.noreply.github.com>
GitOrigin-RevId: f0e5f538b652bff0deee7a15eb5b68d991c28639
This commit is contained in:
Toan Nguyen 2023-07-05 21:18:19 +07:00 committed by hasura-bot
parent 147839079f
commit 31af5d6ab8
17 changed files with 1393 additions and 4 deletions

View File

@ -521,3 +521,5 @@ words:
- Heyyy
- Heyy
- optimise
enableFiletypes:
- mdx

View File

@ -0,0 +1,341 @@
---
sidebar_label: ADFS
description: Active Directory Federation Services (ADFS) SSO tutorial for Hasura Enterprise Edition
title: 'EE: ADFS SSO'
keywords:
- hasura
- console
- docs
- enterprise
- single sign on
- SSO
- SAML
- ADFS
sidebar_position: 3
toc_max_heading_level: 2
---
import Thumbnail from '@site/src/components/Thumbnail';
# Console SSO with Active Directory Federation Services (ADFS)
<div className="badge badge--primary heading-badge">Available on: Self-hosted Enterprise</div>
## Overview
SSO can be configured with ADFS SAML by setting up [Dex](https://dexidp.io/docs/) as an OAuth2 proxy. Access can be
configured for all users of a domain or only for members of certain groups.
This guide assumes you have a Hasura GraphQL Engine instance running with a valid license key. If you don't have one,
you can get a license key via a [30-day free trial](/enterprise/try-hasura-enterprise-edition.mdx) or by contacting the
[Hasura team](mailto:sales@hasura.io).
:::info Supported from
SSO for ADFS is supported from versions `v2.25.0` and above.
:::
## Step 1: Configure ADFS
We assume that you have deployed the
[ADFS service](https://learn.microsoft.com/en-us/windows-server/identity/ad-fs/deployment/ad-fs-deployment-guide). To
configure SAML for ADFS, you need to create a
[Relying party trust](https://learn.microsoft.com/en-us/windows-server/identity/ad-fs/operations/create-a-relying-party-trust)
and make sure that:
- The `Enable support for the SAML 2.0 WebSSO protocol` checkbox is checked.
- The Dex callback URL is entered in the `Relying party SAML 2.0 SSO service URL` textbox.
<Thumbnail
src="/img/enterprise/sso-adfs-trust-party-url.png"
alt="Relying party SAML 2.0 SSO service URL"
width="600px"
/>
- On the `Configure Identifiers page`, add a `Relying party trust identifier`
:::info You'll need this later
You'll need the `Relying party trust identifier` to configure Dex's `entityIssuer`. Note this value.
:::
### Add Claims
After creating the Relying Party Trust, select the `Relying Party Trusts` folder from AD FS Management, and choose
`Edit Claim Rules` from the Actions sidebar to add claims.
- To pass attributes of a user from LDAP, create a rule with the `Send LDAP Attributes as Claims` as a template.
- Choose `Active Directory` as your Attribute Store.
- Map your LDAP attributes to ongoing claim types. Dex only requires the `username`, `mail`, and role-equivalent fields.
<Thumbnail src="/img/enterprise/sso-adfs-add-claims.png" alt="Add claims for SSO ADFS" width="600px" />
- Click on the `View Rule Language` button to get the attribute name. These were the attribute names that were mapped in
the previous step.
<Thumbnail src="/img/enterprise/sso-adfs-view-rule.png" alt="View XML attribute names" width="600px" />
- Click `Finish` and `Apply` the change in the `Edit Claim Issuance Policy` window.
### Export Signing Certificate
Finally, you'll need to export the signing certificate from the ADFS console to mount it to Dex.
<Thumbnail src="/img/enterprise/sso-adfs-certificates.png" alt="ADFS SSO Certificates" width="600px" />
1. Go to `ADFS > Service > Certificates`. Select the `Token-signing` certificate, and right-click to select
`View Certificate`.
2. On the `Details tab`, click `Copy to File...`. This launches the Certificate Export Wizard. Click `Next`.
3. Choose `Base-64 encoded X.509 (.CER)` as the format you'd like to use. Click Next.
4. Download to the location where Dex is deployed.
## Step 2: Configure Hasura
The table below describes the configuration options for ADFS SSO. Hasura GraphQL Engine will expect these values to be
set as the value of the
[`HASURA_GRAPHQL_SSO_PROVIDERS`](/deployment/graphql-engine-flags/reference.mdx/#single-sign-on-providers) environment
variable:
| Key | Example | Description |
| ----------------------- | --------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `client_id` | `dex-login` | Any name identifying the Dex client |
| `admin_roles` | `["admin"]` | X-hasura-roles that should be given admin access to Console |
| `name` | Dex Login | A display name for this login method on the Console |
| `authorization_url` | `http://dex-endpoint-from-browser:port/dex/auth` | Endpoint of Dex for auth request, should be reachable from browser |
| `request_token_url` | `http://dex-endpoint-from-browser:port/dex/token` | Endpoint of Dex for token request, should be reachable from browser |
| `scope` | `openid offline_access groups` | Oauth2 scopes to be used against Dex |
| `jwt_secret.type` | `RS256` | Key type Dex is configured with |
| `jwt_secret.jwk_url` | `http://dex-endpoint-from-hasura:port/dex/keys` | JWK URL that is published by dex |
| `jwt_secret.issuer` | `http://dex-endpoint-from-browser:port/dex` | Issuer that is configured with Dex, same as issuer in Dex configuration, this is typically the endpoint at which Dex can be reached at |
| `jwt_secret.claims_map` | `{"x-hasura-allowed-roles": {"path": "$.groups"},"x-hasura-default-role": {"path": "$.groups[0]"}}` | Mapping groups parsed by Dex to roles on Hasura |
Using the information above as an example, you can configure the `HASURA_GRAPHQL_SSO_PROVIDERS` environment variable as
follows:
```json
[
{
"client_id": "dex-login",
"admin_roles": ["admin"],
"name": "Dex Login",
"authorization_url": "http://localhost:5556/dex/auth",
"request_token_url": "http://localhost:5556/dex/token",
"scope": "openid offline_access groups",
"jwt_secret": {
"type": "RS256",
"jwk_url": "http://localhost:5556/dex/keys",
"issuer": "http://localhost:5556:5556/dex",
"claims_map": {
"x-hasura-allowed-roles": {
"path": "$.groups"
},
"x-hasura-default-role": {
"path": "$.groups[0]"
}
}
}
}
]
```
:::info Setting environment variables
For guidance on setting environment variables or flags for Hasura GraphQL Engine, see
[server configuration](/deployment/graphql-engine-flags/index.mdx).
:::
## Step 3: Configure Dex
Your Dex configuration will need the following fields set to enable ADFS SAML SSO. You can find a sample configuration
file below. This file should be saved in the `/dex` directory of your container.
### Issuer
The base path of Dex and the external name of the OpenID Connect service. This is the canonical URL that all clients
**must** use to refer to Dex. If a path is provided, Dex's HTTP service will listen at a non-root URL. This is the
public URL at which Dex is available.
Example:
```plaintext
http://dex-domain:5556/dex
```
### Static clients
This contains the `id` and `redirectURIs`. The `id` will reference the `client_id` in the Hasura configuration. The
`redirectURIs` will be the oauth callback URL of Hasura Console, which is at
`http(s)://<hasura-endpoint>/console/oauth2/callback`.
Example:
```yaml
staticClients:
- id: dex-login
redirectURIs:
- 'http://localhost:8080/console/oauth2/callback'
name: 'Dex Login'
public: true
```
### Connectors
The connectors field is an array of objects that define the various connectors being used in the Dex configuration. Each
object in the array contains a type field that specifies the type of connector being used. Here, we'll use `type: saml`
along with a series of fields that are specific to the SAML connector.
```yaml
connectors:
- type: saml
id: saml-auth0
name: Auth0 SAML
config:
ssoURL: https://sts.example.local/adfs/ls/
ca: /etc/dex/saml-ca.pem
# insecureSkipSignatureValidation: true
redirectURI: http://localhost:5556/dex/callback
usernameAttr: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name
emailAttr: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress
groupsAttr: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role
entityIssuer: https://sts.example.local/adfs/ls/
```
### Sample configuration file for Dex
<details>
<summary>Click here to see a sample configuration file for Dex.</summary>
```yaml
# The base path of dex and the external name of the OpenID Connect service.
# This is the canonical URL that all clients MUST use to refer to dex. If a
# path is provided, dex's HTTP service will listen at a non-root URL.
# Public URL that dex is available at
issuer: http://localhost:5556/dex
# The storage configuration determines where dex stores its state. Supported
# options include SQL flavors and Kubernetes third party resources.
#
# See the documentation (https://dexidp.io/docs/storage/) for further information.
storage:
type: sqlite3
config:
file: /var/dex/dex.db
# Configuration for the HTTP endpoints.
web:
http: 0.0.0.0:5556
allowedOrigins: ['*']
# Uncomment for HTTPS options.
# https: 127.0.0.1:5554
# tlsCert: /etc/dex/tls.crt
# tlsKey: /etc/dex/tls.key
# Uncomment this block to enable configuration for the expiration time durations.
# Is possible to specify units using only s, m and h suffixes.
# expiry:
# deviceRequests: "5m"
# signingKeys: "6h"
# idTokens: "24h"
# refreshTokens:
# reuseInterval: "3s"
# validIfNotUsedFor: "2160h" # 90 days
# absoluteLifetime: "3960h" # 165 days
# Options for controlling the logger.
# logger:
# level: "debug"
# format: "text" # can also be "json"
oauth2:
responseTypes: ['code'] # also allowed are "token" and "id_token"
skipApprovalScreen: true
#
staticClients:
- id: dex-login
redirectURIs:
- 'http://localhost:8080/console/oauth2/callback'
name: 'Dex Login'
public: true
connectors:
- type: saml
id: saml-auth0
name: Auth0 SAML
config:
ssoURL: https://sts.example.local/adfs/ls/
ca: /etc/dex/adfs-saml.cer
# insecureSkipSignatureValidation: true
redirectURI: http://localhost:5556/dex/callback
usernameAttr: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name
emailAttr: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress
groupsAttr: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role
entityIssuer: https://sts.example.local/adfs/ls/
```
</details>
## Step 4: Update your deployment
Finally, you'll need to configure your deployment with these changes. Here is a Docker Compose example, with the
configuration:
```yaml
version: '3.8'
services:
postgres:
image: postgres:15
restart: always
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- '5432'
environment:
POSTGRES_PASSWORD: postgrespassword
hasura-pro:
image: hasura/graphql-engine:v2.25.0
ports:
- '8080:8080'
depends_on:
- postgres
restart: always
environment:
HASURA_GRAPHQL_EE_LICENSE_KEY: <YOUR_EE_LICENSE_KEY>
HASURA_GRAPHQL_ADMIN_SECRET: <YOUR_ADMIN_SECRET>
HASURA_GRAPHQL_DATABASE_URL: postgres://postgres:postgrespassword@postgres:5432/postgres?sslmode=disable
HASURA_GRAPHQL_ENABLE_CONSOLE: 'true'
HASURA_GRAPHQL_DEV_MODE: 'true'
HASURA_GRAPHQL_ENABLED_LOG_TYPES: startup,http-log,webhook-log,websocket-log,query-log
HASURA_GRAPHQL_ENABLED_APIS: metadata,graphql,config,metrics
HASURA_GRAPHQL_METRICS_SECRET: <YOUR_METRICS_SECRET>
HASURA_GRAPHQL_CONSOLE_ASSETS_DIR: /srv/console-assets
HASURA_GRAPHQL_SSO_PROVIDERS:
'[{"client_id": "dex-login","admin_roles": ["hasura-admin@company.com"], "name": "Dex
Login","authorization_url": "http://127.0.0.1:5556/dex/auth","request_token_url":
"http://127.0.0.1:5556/dex/token","scope": "openid offline_access groups","jwt_secret": {"type":
"RS256","jwk_url": "http://dex:5556/dex/keys","issuer": "http://127.0.0.1:5556/dex","claims_map":
{"x-hasura-allowed-roles": { "path": "$.groups" },"x-hasura-default-role": { "path": "$.groups[0]" }}}}]'
dex:
image: dexidp/dex
restart: always
volumes:
- ./dex/config.docker.yaml:/etc/dex/config.docker.yaml
- ./dex/adfs-saml.cer:/dex/adfs-saml.cer
ports:
- '5556:5556'
volumes:
postgres_data:
```
## Step 5: Log in
At this point, you should see a `Dex Login` option on the Hasura Console. Now, you're ready to log in with your ADFS
account 🎉
<Thumbnail src="/img/enterprise/Dex-sso.png" alt="Dex on Hasura Console" width="600px" />

View File

@ -0,0 +1,459 @@
---
sidebar_label: Auth0
description: Auth0 SSO tutorial for Hasura Enterprise Edition
title: 'EE: Auth0 SSO'
keywords:
- hasura
- console
- docs
- enterprise
- single sign on
- SSO
- Auth0
sidebar_position: 4
---
import Thumbnail from '@site/src/components/Thumbnail';
# Console SSO with Auth0
<div className="badge badge--primary heading-badge">Available on: Self-hosted Enterprise</div>
## Overview
Auth0 is a rapidly integrable authentication and authorization service. You can use it easily to manage admin users,
integrate SSO with Hasura GraphQL Engine or act as middleware to connect non-OAuth compliant identity providers (IdP).
This guide assumes you have a Hasura GraphQL Engine instance running with a valid license key. If you don't have one,
you can get a license key via a [30-day free trial](/enterprise/try-hasura-enterprise-edition.mdx) or by contacting the
[Hasura team](mailto:sales@hasura.io).
:::info Supported from
SSO for LDAP is supported from versions `v2.25.0` and above.
:::
## Get started
You can try the SSO configuration with [this demo](https://github.com/hasura/ee-sso-demo). The demo uses
[OpenLDAP](https://www.openldap.org/) to integrate with Dex. You can clone the repository, edit the EE License Key
environment variable, and start up Docker Compose services.
```bash
git clone https://github.com/hasura/ee-sso-demo.git
cd ee-sso-demo
cp dotenv .env
docker-compose up -d
```
Finally, browse `http://localhost:8080` and try the SSO login.
## OAuth 2.0 / OpenID Connect
### Step 1: Configure Auth0
After creating an Auth0 application, go to the Settings tab and configure:
- Application URIs:
- Set `Allowed Callback URLs` to match the callback URL of the Hasura Console, e.g
`http://localhost:8080/console/oauth2/callback`
- Set `Allowed Web Origins` to match the origin of the Hasura Console, e.g `http://localhost:8080`
- Cross-Origin Authentication:
- Enable the `Allow Cross-Origin Authentication` setting.
- Set `Allowed Origins (CORS)` to match the origin of the Hasura Console, e.g: `http://localhost:8080`
- Open the `Advanced Settings` accordion at the bottom:
- Switch to the tab `Grant Types` and enable the `Authorization Code` checkbox.
- Switch to the `Endpoints` tab and note down required configuration values for Hasura SSO:
- `authorization_url`: OAuth Authorization URL
- `request_token_url`: OAuth Token URL
- `jwt_secret.jwk_url`: JSON Web Key Set
Save changes and note the Client ID in the `Basic Information` section. We'll need this later.
By default, OAuth0 doesn't include the role value in JWT claims. We need to either:
- Force the `admin` role to the `jwt_secret.claims_map` mappings field in the `HASURA_GRAPHQL_SSO_PROVIDERS`
configuration:
```json
{
"jwt_secret": {
// ...
"claims_map": {
"x-hasura-allowed-roles": ["admin"],
"x-hasura-default-role": "admin"
}
}
}
```
- Or, add an Auth0 action or legacy Auth pipeline to add the role claim into the JWT payload.
For better security, or if your Auth0 application is reused for many different client applications, you should create an
admin role for the privileged user and add the role to JWT claims:
- Go to the `User Management -> Roles` page, and create a new role with the name `admin`.
- Assign some users with that role to verify later.
- Go to the `Actions -> Flows` page, choose the `Login` flow, and add a custom action to add claims.
```typescript
/**
* Handler that will be called during the execution of a PostLogin flow.
*
* @param {Event} event - Details about the user and the context in which they are logging in.
* @param {PostLoginAPI} api - Interface whose methods can be used to change the behavior of the login.
*/
exports.onExecutePostLogin = async (event, api) => {
const namespace = 'https://hasura.io/jwt/claims';
if (event.authorization) {
const claims = {
'x-hasura-default-role': event.authorization.roles[0],
'x-hasura-allowed-roles': event.authorization.roles,
'x-hasura-user-id': event.user.user_id,
};
api.idToken.setCustomClaim(namespace, claims);
}
};
```
- Deploy the action.
- Head back to the flow and drag the custom action to the center of the flow diagram.
<Thumbnail src="/img/enterprise/sso-auth0-action-claims.png" alt="Auth0 Custom Claim Action" />
### Step 2: Configure Hasura
The table below describes the configuration options for Auth0 SSO. Hasura GraphQL Engine will expect these values to be
set as the value of the
[`HASURA_GRAPHQL_SSO_PROVIDERS`](/deployment/graphql-engine-flags/reference.mdx/#single-sign-on-providers) environment
variable:
| Key | Example | Description |
| -------------------- | -------------------------------------- | --------------------------------------------------------------------------------------------------- |
| `client_id` | `<client-id>` | The Client ID of Auth0 application |
| `admin_roles` | `["admin"]` | X-hasura-roles that should be given admin access to Console |
| `name` | Auth0 Login | A display name for this login method on the Console |
| `authorization_url` | `<OAuth Authorization URL>` | Endpoint of Auth0 application for auth request, should be reachable from browser |
| `request_token_url` | `<OAuth Token URL>` | Endpoint of Auth0 application for token request, should be reachable from browser |
| `scope` | `openid` | Oauth2 scopes to be used against Auth0 application |
| `jwt_secret.type` | `RS256` | Key type Auth0 application is configured with |
| `jwt_secret.jwk_url` | `<JSON Web Key Set>` | JWK URL that is published by Auth0 application |
| `jwt_secret.issuer` | `https://some-auth0-app.us.auth0.com/` | Issuer that is configured with Auth0, this is typically the base OAuth URL of the Auth0 application |
Using the information above as an example, you can configure the `HASURA_GRAPHQL_SSO_PROVIDERS` environment variable as
follows:
```json
[
{
"client_id": "<Auth0 Client ID>",
"admin_roles": ["admin"],
"name": "Auth0 Login",
"authorization_url": "https://some-auth0-app.us.auth0.com/authorize",
"request_token_url": "https://some-auth0-app.us.auth0.com/oauth/token",
"scope": "openid",
"jwt_secret": {
"type": "RS256",
"jwk_url": "https://some-auth0-app.us.auth0.com/.well-known/jwks.json",
"issuer": "https://some-auth0-app.us.auth0.com/"
}
}
]
```
:::info Setting environment variables
For guidance on setting environment variables or flags for Hasura GraphQL Engine, see
[server configuration](/deployment/graphql-engine-flags/index.mdx).
:::
### Step 3: Deploy and Log in
At this point, you should see a `Auth0 Login` option on the Hasura Console. Now, you're ready to log in with your Auth0
account 🎉
<Thumbnail src="/img/enterprise/sso-animated-demo.gif" alt="Console SSO demo" />
## SAML
The Auth0 application also supports SAML 2.0. Though, the OAuth configuration is simpler to integrate. You can try it to
verify with Dex integration.
### Step 1: Configure Auth0
The configuration is similar to the [OAuth 2.0 / OpenID Connect](#step-1-configure-auth0) with some extra
configurations:
- Go to `Application -> Addons tab` and enable the `SAML2 WEB APP` plugin.
- The `Settings` dialog will be opened. You need to add the Dex endpoint into `Application Callback URL` textbox (e.g.,
`http://localhost:5556/dex/callback`).
- After saving, switch to the `Usage` tab and note down required values for Dex connector configuration:
- The SSO URL (Identity Provider Login URL).
- Issuer: `urn:some-auth0-app.us.auth0.com`.
- Download Auth0 certificate (Identity Provider Certificate) to the configuration folder of Dex.
Auth0 doesn't include roles in attributes of the XML response either. We need to add the `roles` field to custom claims.
```typescript
/**
* Handler that will be called during the execution of a PostLogin flow.
*
* @param {Event} event - Details about the user and the context in which they are logging in.
* @param {PostLoginAPI} api - Interface whose methods can be used to change the behavior of the login.
*/
exports.onExecutePostLogin = async (event, api) => {
api.idToken.setCustomClaim('roles', event.authorization.roles);
}
};
```
Auth0 automatically serializes custom claims into XML attributes with the `http://schemas.auth0.com/` prefix (e.g.,
`http://schemas.auth0.com/roles`).
### Step 2: Configure Hasura
The table below describes the configuration options for Auth0 SAML SSO. Hasura GraphQL Engine will expect these values
to be set as the value of the
[`HASURA_GRAPHQL_SSO_PROVIDERS`](/deployment/graphql-engine-flags/reference.mdx/#single-sign-on-providers) environment
variable:
| Key | Example | Description |
| ----------------------- | --------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `client_id` | `dex-login` | Any name identifying the Dex client |
| `admin_roles` | `["admin"]` | X-hasura-roles that should be given admin access to Console |
| `name` | Dex Login | A display name for this login method on the Console |
| `authorization_url` | `http://dex-endpoint-from-browser:port/dex/auth` | Endpoint of Dex for auth request, should be reachable from browser |
| `request_token_url` | `http://dex-endpoint-from-browser:port/dex/token` | Endpoint of Dex for token request, should be reachable from browser |
| `scope` | `openid offline_access groups` | Oauth2 scopes to be used against Dex |
| `jwt_secret.type` | `RS256` | Key type Dex is configured with |
| `jwt_secret.jwk_url` | `http://dex-endpoint-from-hasura:port/dex/keys` | JWK URL that is published by dex |
| `jwt_secret.issuer` | `http://dex-endpoint-from-browser:port/dex` | Issuer that is configured with Dex, same as issuer in Dex configuration, this is typically the endpoint at which Dex can be reached at |
| `jwt_secret.claims_map` | `{"x-hasura-allowed-roles": {"path": "$.groups"},"x-hasura-default-role": {"path": "$.groups[0]"}}` | Mapping groups parsed by Dex to roles on Hasura |
Using the information above as an example, you can configure the `HASURA_GRAPHQL_SSO_PROVIDERS` environment variable as
follows:
```json
[
{
"client_id": "dex-login",
"admin_roles": ["admin", "admins"],
"name": "Dex Login",
"authorization_url": "http://localhost:5556/dex/auth",
"request_token_url": "http://localhost:5556/dex/token",
"scope": "openid offline_access groups",
"jwt_secret": {
"type": "RS256",
"jwk_url": "http://dex:5556/dex/keys",
"issuer": "http://localhost:5556:5556/dex",
"claims_map": {
"x-hasura-allowed-roles": {
"path": "$.groups"
},
"x-hasura-default-role": {
"path": "$.groups[0]"
}
}
}
}
]
```
:::info Setting environment variables
For guidance on setting environment variables or flags for Hasura GraphQL Engine, see
[server configuration](/deployment/graphql-engine-flags/index.mdx).
:::
### Step 3: Configure Dex
Your Dex configuration will need the following fields set to enable SAML SSO. You can find a sample configuration file
below. This file should be saved in the `/dex` directory of your container.
#### Issuer
The base path of Dex and the external name of the OpenID Connect service. This is the canonical URL that all clients
**must** use to refer to Dex. If a path is provided, Dex's HTTP service will listen at a non-root URL. This is the
public URL at which Dex is available.
Example:
```plaintext
http://dex-domain:5556/dex
```
#### Static clients
This contains the `id` and `redirectURIs`. The `id` will reference the `client_id` in the Hasura configuration. The
`redirectURIs` will be the oauth callback URL of Hasura Console, which is at
`http(s)://<hasura-endpoint>/console/oauth2/callback`.
Example:
```yaml
staticClients:
- id: dex-login
redirectURIs:
- 'http://localhost:8080/console/oauth2/callback'
name: 'Dex Login'
public: true
```
#### Connectors
The connectors field is an array of objects that define the various connectors being used in the Dex configuration. Each
object in the array contains a `type` field that specifies the type of connector being used. Here, we'll use
`type: saml` along with a series of fields that are specific to the SAML connector.
```yaml
connectors:
- type: saml
id: saml-auth0
name: Auth0 SAML
config:
ssoURL: https://some-auth0-app.us.auth0.com/samlp/xxxxxxxx
ca: /etc/dex/saml-ca.pem
# insecureSkipSignatureValidation: true
redirectURI: http://localhost:5556/dex/callback
usernameAttr: http://schemas.auth0.com/name
emailAttr: http://schemas.auth0.com/email
groupsAttr: http://schemas.auth0.com/roles
entityIssuer: urn:some-auth0-app.us.auth0.com
```
#### Sample configuration file for Dex
<details>
<summary>Click here to see a sample configuration file for Dex.</summary>
```yaml
# The base path of dex and the external name of the OpenID Connect service.
# This is the canonical URL that all clients MUST use to refer to dex. If a
# path is provided, dex's HTTP service will listen at a non-root URL.
# Public URL that dex is available at
issuer: http://localhost:5556/dex
# The storage configuration determines where dex stores its state. Supported
# options include SQL flavors and Kubernetes third party resources.
#
# See the documentation (https://dexidp.io/docs/storage/) for further information.
storage:
type: sqlite3
config:
file: /var/dex/dex.db
# Configuration for the HTTP endpoints.
web:
http: 0.0.0.0:5556
allowedOrigins: ['*']
# Uncomment for HTTPS options.
# https: 127.0.0.1:5554
# tlsCert: /etc/dex/tls.crt
# tlsKey: /etc/dex/tls.key
# Uncomment this block to enable configuration for the expiration time durations.
# Is possible to specify units using only s, m and h suffixes.
# expiry:
# deviceRequests: "5m"
# signingKeys: "6h"
# idTokens: "24h"
# refreshTokens:
# reuseInterval: "3s"
# validIfNotUsedFor: "2160h" # 90 days
# absoluteLifetime: "3960h" # 165 days
# Options for controlling the logger.
# logger:
# level: "debug"
# format: "text" # can also be "json"
oauth2:
responseTypes: ['code'] # also allowed are "token" and "id_token"
skipApprovalScreen: true
#
staticClients:
- id: dex-login
redirectURIs:
- 'http://localhost:8080/console/oauth2/callback'
name: 'Dex Login'
public: true
connectors:
- type: saml
id: saml-auth0
name: Auth0 SAML
config:
ssoURL: https://some-auth0-app.us.auth0.com/samlp/xxxxxxxx
ca: /etc/dex/saml-ca.pem
# insecureSkipSignatureValidation: true
redirectURI: http://localhost:5556/dex/callback
usernameAttr: http://schemas.auth0.com/name
emailAttr: http://schemas.auth0.com/email
groupsAttr: http://schemas.auth0.com/roles
entityIssuer: urn:some-auth0-app.us.auth0.com
```
</details>
### Step 4: Update your deployment
Finally, you'll need to configure your deployment with these changes. Here is a Docker Compose example, with the
configuration:
```yaml
version: '3.8'
services:
postgres:
image: postgres:15
restart: always
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- '5432'
environment:
POSTGRES_PASSWORD: postgrespassword
hasura-pro:
image: hasura/graphql-engine:v2.25.0
ports:
- '8080:8080'
depends_on:
- postgres
restart: always
environment:
HASURA_GRAPHQL_EE_LICENSE_KEY: <YOUR_EE_LICENSE_KEY>
HASURA_GRAPHQL_ADMIN_SECRET: <YOUR_ADMIN_SECRET>
HASURA_GRAPHQL_DATABASE_URL: postgres://postgres:postgrespassword@postgres:5432/postgres?sslmode=disable
HASURA_GRAPHQL_ENABLE_CONSOLE: 'true'
HASURA_GRAPHQL_DEV_MODE: 'true'
HASURA_GRAPHQL_ENABLED_LOG_TYPES: startup,http-log,webhook-log,websocket-log,query-log
HASURA_GRAPHQL_ENABLED_APIS: metadata,graphql,config,metrics
HASURA_GRAPHQL_METRICS_SECRET: <YOUR_METRICS_SECRET>
HASURA_GRAPHQL_CONSOLE_ASSETS_DIR: /srv/console-assets
HASURA_GRAPHQL_SSO_PROVIDERS:
'[{"client_id": "dex-login","admin_roles": ["admin", "authors"], "name": "Dex Login","authorization_url":
"http://127.0.0.1:5556/dex/auth","request_token_url": "http://127.0.0.1:5556/dex/token","scope": "openid
offline_access groups","jwt_secret": {"type": "RS256","jwk_url": "http://dex:5556/dex/keys","issuer":
"http://127.0.0.1:5556/dex","claims_map": {"x-hasura-allowed-roles": { "path": "$.groups"
},"x-hasura-default-role": { "path": "$.groups[0]" }}}}]'
dex:
image: dexidp/dex
restart: always
volumes:
- ./dex/config.docker.yaml:/etc/dex/config.docker.yaml
ports:
- '5556:5556'
volumes:
postgres_data:
```
### Step 5: Log in
At this point, you should see a `Dex Login` option on the Hasura Console. Now, you're ready to log in with your LDAP
account 🎉

View File

@ -11,7 +11,7 @@ keywords:
- SSO
- SAML
- Azure
sidebar_position: 3
sidebar_position: 5
---
import Thumbnail from '@site/src/components/Thumbnail';

View File

@ -19,6 +19,17 @@ import Thumbnail from '@site/src/components/Thumbnail';
<div className="badge badge--primary heading-badge">Available on: Self-hosted Enterprise</div>
## Authorization Flow
<Thumbnail src="/img/enterprise/sso-auth-flow-oauth.png" alt="SSO OAuth flow" />
1. First of all, the GraphQL Engine server needs to know the authentication context and verification secrets of the
Identity Provider (IdP). If the JSON Web Key Sets (JWKS) are exposed on the remote URL, the server will fetch the JWT
secret on start up.
2. When clicking on the SSO login button, the Console initiates the Authorization Code flow with the IdP.
3. On successful authorization, the IdP issues a JWT ID token to the Console with an `admin` or equivalent role.
4. The Console then uses the JWT to execute Metadata and GraphQL API calls.
## Configuration
### Configuring the identity provider
@ -76,6 +87,18 @@ about how the middleware handles external providers. Dex supports [SAML 2.0](htt
[LDAP](https://dexidp.io/docs/connectors/ldap/) protocols, as well as identity providers like GitHub, Google, and Active
Directory.
The authorization flow is similar to the OAuth / OpenID Connect flow, with an extra step to authenticate the IdP through
middleware.
<Thumbnail src="/img/enterprise/sso-auth-flow-middleware.png" alt="SSO middleware authentication flow" />
1. Configure GraphQL Engine with the JWT Secret and Login URL of the middleware.
2. When clicking on the SSO login button, the Console initiates the Authorization Code flow with the middleware.
3. The middleware handles the authorization with the IdP.
4. On successful authorization, the middleware converts the profile of the IdP to a JWT ID token and issues it to the
Console.
5. The Console then uses the JWT to execute Metadata and GraphQL API calls.
### SAML configuration
#### Configuring the identity provider

View File

@ -11,7 +11,7 @@ keywords:
- SSO
- SAML
- google workspace
sidebar_position: 4
sidebar_position: 6
toc_max_heading_level: 2
---

View File

@ -25,8 +25,8 @@ import Thumbnail from '@site/src/components/Thumbnail';
With Hasura Enterprise Edition, you can enable SSO (Single Sign-On) on the Hasura Console with your identity management
system through the [OAuth 2.0](https://oauth.net) / [OpenID Connect](https://openid.net/connect) protocol.
Hasura provides full support for OAuth 2.0 as a Single Sign-On (SSO) solution without the need for additional tooling or services.
OAuth 2.0 is an industry-standard protocol that enables secure and delegated access to protected resources.
Hasura provides full support for OAuth 2.0 as a Single Sign-On (SSO) solution without the need for additional tooling or
services. OAuth 2.0 is an industry-standard protocol that enables secure and delegated access to protected resources.
Hasura SSO can also be extended to use additional providers by leveraging [Dex](https://github.com/dexidp/dex).
@ -51,5 +51,9 @@ To get started, either use our general configuration guide or follow the specifi
provider:
- [Single Sign-on configuration](/enterprise/sso/config.mdx)
- [Enable ADFS Single Sign-on](/enterprise/sso/adfs.mdx)
- [Enable Auth0 Single Sign-on](/enterprise/sso/auth0.mdx)
- [Enable Azure AD Single Sign-on](/enterprise/sso/azure-ad.mdx)
- [Enable Google Workspace Single Sign-on](/enterprise/sso/google-workspace.mdx)
- [Enable LDAP Single Sign-on](/enterprise/sso/ldap.mdx)
- [Troubleshooting](/enterprise/sso/troubleshooting.mdx)

View File

@ -0,0 +1,437 @@
---
sidebar_label: LDAP
description: LDAP SSO tutorial for Hasura Enterprise Edition
title: 'EE: LDAP SSO'
keywords:
- hasura
- console
- docs
- enterprise
- single sign on
- SSO
- LDAP
sidebar_position: 7
---
import Thumbnail from '@site/src/components/Thumbnail';
# Console SSO with LDAP
<div className="badge badge--primary heading-badge">Available on: Self-hosted Enterprise</div>
## Overview
SSO can be configured with LDAP by setting up [Dex](https://dexidp.io/docs/) as an OAuth2 proxy. Access can be
configured for all users of a domain or only for members of certain groups.
This guide assumes you have a Hasura GraphQL Engine instance running with a valid license key. If you don't have one,
you can get a license key via a [30-day free trial](/enterprise/try-hasura-enterprise-edition.mdx) or by contacting the
[Hasura team](mailto:sales@hasura.io).
:::info Supported from
SSO for LDAP is supported from versions `v2.25.0` and above.
:::
## Get started
You can try the SSO configuration with [this demo](https://github.com/hasura/ee-sso-demo). The demo uses
[OpenLDAP](https://www.openldap.org/) to integrate with Dex. You can clone the repository, edit the EE License Key
environment variable, and start up Docker Compose services.
```bash
git clone https://github.com/hasura/ee-sso-demo.git
cd ee-sso-demo
cp dotenv .env
docker-compose up -d
```
Finally, browse `http://localhost:8080` and try the SSO login.
## Walkthrough
### Step 1: Configure Hasura
The table below describes the configuration options for LDAP SSO. Hasura GraphQL Engine will expect these values to be
set as the value of the
[`HASURA_GRAPHQL_SSO_PROVIDERS` environment variable](/deployment/graphql-engine-flags/reference.mdx/#single-sign-on-providers):
| Key | Example | Description |
| ----------------------- | --------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `client_id` | `dex-login` | Any name identifying the Dex client |
| `admin_roles` | `["admin", "admins"]` | X-hasura-roles that should be given admin access to Console |
| `name` | Dex Login | A display name for this login method on the Console |
| `authorization_url` | `http://dex-endpoint-from-browser:port/dex/auth` | Endpoint of Dex for auth request, should be reachable from browser |
| `request_token_url` | `http://dex-endpoint-from-browser:port/dex/token` | Endpoint of Dex for token request, should be reachable from browser |
| `scope` | `openid offline_access groups` | Oauth2 scopes to be used against Dex |
| `jwt_secret.type` | `RS256` | Key type Dex is configured with |
| `jwt_secret.jwk_url` | `http://dex-endpoint-from-hasura:port/dex/keys` | JWK URL that is published by dex |
| `jwt_secret.issuer` | `http://dex-endpoint-from-browser:port/dex` | Issuer that is configured with Dex, same as issuer in Dex configuration, this is typically the endpoint at which Dex can be reached at |
| `jwt_secret.claims_map` | `{"x-hasura-allowed-roles": {"path": "$.groups"},"x-hasura-default-role": {"path": "$.groups[0]"}}` | Mapping groups parsed by Dex to roles on Hasura |
Using the information above as an example, you can configure the `HASURA_GRAPHQL_SSO_PROVIDERS` environment variable as
follows:
```json
[
{
"client_id": "dex-login",
"admin_roles": ["admin", "admins"],
"name": "Dex Login",
"authorization_url": "http://localhost:5556/dex/auth",
"request_token_url": "http://localhost:5556/dex/token",
"scope": "openid offline_access groups",
"jwt_secret": {
"type": "RS256",
"jwk_url": "http://dex:5556/dex/keys",
"issuer": "http://localhost:5556:5556/dex",
"claims_map": {
"x-hasura-allowed-roles": {
"path": "$.groups"
},
"x-hasura-default-role": {
"path": "$.groups[0]"
}
}
}
}
]
```
:::info Setting environment variables
For guidance on setting environment variables or flags for Hasura GraphQL Engine, see
[server configuration](/deployment/graphql-engine-flags/index.mdx).
:::
### Step 2: Configure Dex
Your Dex configuration will need the following fields set to enable LDAP SSO. You can find a sample configuration file
below. This file should be saved in the `/dex` directory of your container.
#### Issuer
The base path of Dex and the external name of the OpenID Connect service. This is the canonical URL that all clients
**must** use to refer to Dex. If a path is provided, Dex's HTTP service will listen at a non-root URL. This is the
public URL at which Dex is available.
Example:
```plaintext
http://dex-domain:5556/dex
```
#### Static clients
This contains the `id` and `redirectURIs`. The `id` will reference the `client_id` in the Hasura configuration. The
`redirectURIs` will be the oauth callback URL of Hasura Console, which is at
`http(s)://<hasura-endpoint>/console/oauth2/callback`.
Example:
```yaml
staticClients:
- id: dex-login
redirectURIs:
- 'http://localhost:8080/console/oauth2/callback'
name: 'Dex Login'
public: true
```
#### Connectors
The connectors field is an array of objects that define the various connectors being used in the Dex configuration. Each
object in the array contains a `type` field that specifies the type of connector being used. Here, we'll use
`type: ldap` along with a series of fields that are specific to the LDAP connector.
```yaml
connectors:
- type: ldap
name: OpenLDAP
id: ldap
config:
# The following configurations seem to work with OpenLDAP:
#
# 1) Plain LDAP, without TLS:
host: ldap:389
insecureNoSSL: true
#
# 2) LDAPS without certificate validation:
#host: localhost:636
#insecureNoSSL: false
#insecureSkipVerify: true
#
# 3) LDAPS with certificate validation:
#host: YOUR-HOSTNAME:636
#insecureNoSSL: false
#insecureSkipVerify: false
#rootCAData: 'CERT'
# ...where CERT="$( base64 -w 0 your-cert.crt )"
# This would normally be a read-only user.
bindDN: cn=admin,dc=example,dc=org
bindPW: admin
usernamePrompt: Email Address
userSearch:
baseDN: ou=People,dc=example,dc=org
filter: '(objectClass=person)'
username: mail
# "DN" (case sensitive) is a special attribute name. It indicates that
# this value should be taken from the entity's DN not an attribute on
# the entity.
idAttr: DN
emailAttr: mail
nameAttr: cn
groupSearch:
baseDN: ou=Groups,dc=example,dc=org
filter: '(objectClass=groupOfNames)'
userMatchers:
# A user is a member of a group when their DN matches
# the value of a "member" attribute on the group entity.
- userAttr: DN
groupAttr: member
# The group name should be the "cn" value.
nameAttr: cn
```
You need to configure mappings for the login form, user and groups attributes. For instance with the LDAP configuration:
```ldif
# User definitions
dn: ou=People,dc=example,dc=org
objectClass: organizationalUnit
ou: People
dn: cn=jane,ou=People,dc=example,dc=org
objectClass: person
objectClass: inetOrgPerson
sn: doe
cn: jane
mail: janedoe@example.com
userpassword: foo
# Group definitions.
dn: ou=Groups,dc=example,dc=org
objectClass: organizationalUnit
ou: Groups
dn: cn=admins,ou=Groups,dc=example,dc=org
objectClass: groupOfNames
cn: admins
member: cn=jane,ou=People,dc=example,dc=org
```
The attribute mappings configuration of Dex should be:
```yaml
usernamePrompt: Email Address
userSearch:
baseDN: ou=People,dc=example,dc=org
filter: '(objectClass=person)'
# we want the user using email to login
username: mail
# "DN" (case sensitive) is a special attribute name. It indicates that
# this value should be taken from the entity's DN not an attribute on
# the entity.
idAttr: DN
emailAttr: mail
nameAttr: cn
groupSearch:
baseDN: ou=Groups,dc=example,dc=org
filter: '(objectClass=groupOfNames)'
userMatchers:
# A user is a member of a group when their DN matches
# the value of a "member" attribute on the group entity.
- userAttr: DN
groupAttr: member
# The group name should be the "cn" value.
nameAttr: cn
```
#### Sample configuration file for Dex
<details>
<summary>Click here to see a sample configuration file for Dex.</summary>
```yaml
# The base path of dex and the external name of the OpenID Connect service.
# This is the canonical URL that all clients MUST use to refer to dex. If a
# path is provided, dex's HTTP service will listen at a non-root URL.
# Public URL that dex is available at
issuer: http://localhost:5556/dex
# The storage configuration determines where dex stores its state. Supported
# options include SQL flavors and Kubernetes third party resources.
#
# See the documentation (https://dexidp.io/docs/storage/) for further information.
storage:
type: sqlite3
config:
file: /var/dex/dex.db
# Configuration for the HTTP endpoints.
web:
http: 0.0.0.0:5556
allowedOrigins: ['*']
# Uncomment for HTTPS options.
# https: 127.0.0.1:5554
# tlsCert: /etc/dex/tls.crt
# tlsKey: /etc/dex/tls.key
# Uncomment this block to enable configuration for the expiration time durations.
# Is possible to specify units using only s, m and h suffixes.
# expiry:
# deviceRequests: "5m"
# signingKeys: "6h"
# idTokens: "24h"
# refreshTokens:
# reuseInterval: "3s"
# validIfNotUsedFor: "2160h" # 90 days
# absoluteLifetime: "3960h" # 165 days
# Options for controlling the logger.
# logger:
# level: "debug"
# format: "text" # can also be "json"
oauth2:
responseTypes: ['code'] # also allowed are "token" and "id_token"
skipApprovalScreen: true
#
staticClients:
- id: dex-login
redirectURIs:
- 'http://localhost:8080/console/oauth2/callback'
name: 'Dex Login'
public: true
connectors:
- type: ldap
name: OpenLDAP
id: ldap
config:
# The following configurations seem to work with OpenLDAP:
#
# 1) Plain LDAP, without TLS:
host: ldap:389
insecureNoSSL: true
#
# 2) LDAPS without certificate validation:
#host: localhost:636
#insecureNoSSL: false
#insecureSkipVerify: true
#
# 3) LDAPS with certificate validation:
#host: YOUR-HOSTNAME:636
#insecureNoSSL: false
#insecureSkipVerify: false
#rootCAData: 'CERT'
# ...where CERT="$( base64 -w 0 your-cert.crt )"
# This would normally be a read-only user.
bindDN: cn=admin,dc=example,dc=org
bindPW: admin
usernamePrompt: Email Address
userSearch:
baseDN: ou=People,dc=example,dc=org
filter: '(objectClass=person)'
username: mail
# "DN" (case sensitive) is a special attribute name. It indicates that
# this value should be taken from the entity's DN not an attribute on
# the entity.
idAttr: DN
emailAttr: mail
nameAttr: cn
groupSearch:
baseDN: ou=Groups,dc=example,dc=org
filter: '(objectClass=groupOfNames)'
userMatchers:
# A user is a member of a group when their DN matches
# the value of a "member" attribute on the group entity.
- userAttr: DN
groupAttr: member
# The group name should be the "cn" value.
nameAttr: cn
```
</details>
### Step 3: Update your deployment
Finally, you'll need to configure your deployment with these changes. Here is a Docker Compose example, with the
configuration:
```yaml
version: '3.8'
services:
postgres:
image: postgres:15
restart: always
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- '5432'
environment:
POSTGRES_PASSWORD: postgrespassword
hasura-pro:
image: hasura/graphql-engine:v2.25.0
ports:
- '8080:8080'
depends_on:
- postgres
restart: always
environment:
HASURA_GRAPHQL_EE_LICENSE_KEY: <YOUR_EE_LICENSE_KEY>
HASURA_GRAPHQL_ADMIN_SECRET: <YOUR_ADMIN_SECRET>
HASURA_GRAPHQL_DATABASE_URL: postgres://postgres:postgrespassword@postgres:5432/postgres?sslmode=disable
HASURA_GRAPHQL_ENABLE_CONSOLE: 'true'
HASURA_GRAPHQL_DEV_MODE: 'true'
HASURA_GRAPHQL_ENABLED_LOG_TYPES: startup,http-log,webhook-log,websocket-log,query-log
HASURA_GRAPHQL_ENABLED_APIS: metadata,graphql,config,metrics
HASURA_GRAPHQL_METRICS_SECRET: <YOUR_METRICS_SECRET>
HASURA_GRAPHQL_CONSOLE_ASSETS_DIR: /srv/console-assets
HASURA_GRAPHQL_SSO_PROVIDERS:
'[{"client_id": "dex-login","admin_roles": ["admin", "authors"], "name": "Dex Login","authorization_url":
"http://127.0.0.1:5556/dex/auth","request_token_url": "http://127.0.0.1:5556/dex/token","scope": "openid
offline_access groups","jwt_secret": {"type": "RS256","jwk_url": "http://dex:5556/dex/keys","issuer":
"http://127.0.0.1:5556/dex","claims_map": {"x-hasura-allowed-roles": { "path": "$.groups"
},"x-hasura-default-role": { "path": "$.groups[0]" }}}}]'
dex:
image: dexidp/dex
restart: always
volumes:
- ./dex/config.docker.yaml:/etc/dex/config.docker.yaml
ports:
- '5556:5556'
volumes:
postgres_data:
```
### Step 4: Log in
At this point, you should see a `Dex Login` option on the Hasura Console. Now, you're ready to log in with your LDAP
account 🎉
<Thumbnail src="/img/enterprise/Dex-sso.png" alt="Dex on Hasura Console" width="600px" />

View File

@ -0,0 +1,123 @@
---
sidebar_label: Troubleshooting
description: Troubleshoot SSO Errors for Hasura Enterprise Edition
title: 'EE: Troubleshoot SSO'
keywords:
- hasura
- console
- docs
- enterprise
- single sign on
- SSO
- SAML
- troubleshooting
sidebar_position: 8
---
# Troubleshooting Console SSO Errors
<div className="badge badge--primary heading-badge">Available on: Self-hosted Enterprise</div>
## Introduction
This section provides references that can help in troubleshooting errors when integrating Console SSO.
## Troubleshooting
### Could not verify JWT: JWTNotInIssuer.
Make sure that the `issuer` config of Dex matches the `issuer` value in the `jwt_secret` value.
### Login Failed: user doesn't have permission
Role values in the JWT token don't contain any role in the `admin_roles` config. If the structure of the JWT payload
doesn't follow the Hasura claim specification, you need to set the claim map JSON path to select the equivalent field
for role.
```json
{
"client_id": "example-app",
// ...
"jwt_secret": {
"type": "RS256",
"jwk_url": "http://dex:5556/dex/keys",
"issuer": "http://localhost:5556/dex",
"claims_map": {
"x-hasura-allowed-roles": { "path": "$.groups" },
"x-hasura-default-role": { "path": "$.groups[0]" }
}
}
}
```
If there isn't any equivalent field for the role, or you just want to test the authentication flow, you can hard-code
the `admin` role.
```json
{
// ...
"admin_roles": ["admin"],
"jwt_secret": {
// ...
"claims_map": {
"x-hasura-allowed-roles": ["admin"],
"x-hasura-default-role": "admin"
}
}
}
```
### Error fetching JWK: ConnectionFailure
GraphQL Engine will fail to start if it can't fetch the JWK secret information from the remote Identity Provider. You
should verify if the IdP service is online and accepts connections.
If both services are in the same internal network - such as Docker or Kubernetes - and the GraphQL Engine instance is
unable to resolve the public DNS of the IdP service, you should change the domain of the JWK URL to the internal DNS
domain.
For example, in the SSO configuration of Dex IdP in the docker-compose stack, the `jwk_url` is set to `http://dex:5556`
instead of `http://localhost:5556`.
```json
{
"client_id": "example-app",
"authorization_url": "http://localhost:5556/dex/auth", // public: the web browser can redirect to public dns only
"request_token_url": "http://localhost:5556/dex/token", // public: the web browser can request to public dns only
"jwt_secret": {
"type": "RS256",
"jwk_url": "http://dex:5556/dex/keys" // private dns: graphql engine connects to dex internally
}
}
```
### Error fetching JWK: certificate rejected (CertificateUnknown)
SSL certificate of the IdP service is a self-signed cert, and GraphQL Engine doesn't trust it. You need to either mount
the certificate file to the `/etc/ssl/certs/` folder, use the `HASURA_GRAPHQL_CERTIFICATE_AUTHORITY=<cert/path>`
environment variable via the CLI, or disable CA verification through the TLS Allowlist feature.
If both GraphQL Engine and the IdP service are in the same internal network, you can consider using HTTP URL to the
private DNS domain of the IdP service.
### Debug the JWT
Open the Network tab in the Developer Tool's panel to track HTTP requests. Find a `/v1/metadata` request which includes
a `Hasura-Sso-Token` request header and copy the token body. Finally, go to https://jwt.io/ and paste the token to debug
the JSON content.
<Thumbnail src="/img/enterprise/sso-token-debug.jpg" alt="SSO Token inspect" width="600px" />
### Can I verify the authentication flow between Dex and Hasura EE without IdP?
Dex supports mock connector and basic password authentication that you can use to verify the authentication flow between
Dex and Hasura EE first. The default role of the mock connector is `authors`, so make sure to add that role to the
`admin_roles` list.
```yaml
# dex/config.docker.yaml
connectors:
- type: mockCallback
id: mock
name: Mock
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB