> ## Documentation Index
> Fetch the complete documentation index at: https://cockroachlabs.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Cluster Single Sign-on (SSO) using JSON Web Tokens (JWTs)

export const InternalLink = ({version, path = "", children, ...props}) => {
  let detectedVersion = version || "stable";
  if (typeof window !== 'undefined' && !version) {
    const match = window.location.pathname.match(/\/docs\/([^/]+)/);
    if (match) {
      detectedVersion = match[1];
    }
  }
  const normalizedPath = path.startsWith("/") ? path.slice(1) : path;
  return <a href={`/docs/${detectedVersion}/${normalizedPath}`} {...props}>
      {children}
    </a>;
};

CockroachDB clusters allow users to authenticate with Single Sign-on (SSO), both to the <InternalLink path="ui-overview">DB Console</InternalLink>, and for SQL client access.

Cluster single sign-on (SSO) enables users to access the SQL interface of a CockroachDB cluster (whether provisioned on CockroachDB Cloud or self-hosted) with the full security of single sign-on (SSO), using JSON Web Tokens (JWTs) from external identity providers (IdPs) such as Okta, Google, Azure AD, or Keycloak.

Users can obtain JWTs directly from their IdP and use them to authenticate to SQL clients. Optionally, CockroachDB Cloud Advanced clusters and self-hosted clusters can also generate JWTs via the DB Console as a convenience feature. When DB Console JWT generation is enabled, users can sign in to their IdP through a link embedded in the DB Console, then copy the generated JWT and use it in a SQL connection string to authenticate to the cluster.

JWT authentication supports automatic role synchronization and user provisioning. When <InternalLink path="jwt-authorization">JWT authorization</InternalLink> is enabled, users' role memberships are automatically synchronized based on group claims from the IdP on each login. Additionally, [automatic user provisioning](#configure-user-provisioning) can automatically create SQL users on first authentication, eliminating the need to pre-create users.

This page describes how to configure a cluster for cluster single sign-on using JWTs and then how users can authenticate using the JWTs:

* [Configure a cluster for cluster single sign-on using JWTs](#configure-your-cluster-for-sso)
* [Configure user provisioning](#configure-user-provisioning) (optional)
* [Authenticate to your cluster](#authenticate-to-your-cluster)

**Prerequisites**

* **Identity Provider (IdP)**: You must have access to an identity provider that supports JWT tokens, such as Okta, Google, Azure AD, or Keycloak.
* **Cluster Settings Access**: You must have the ability to update your cluster settings. Refer to <InternalLink path="set-cluster-setting#required-privileges">`SET CLUSTER SETTING`: Required permissions</InternalLink>.
* **SQL User Provisioning**:
  * If you are using [automatic user provisioning](#configure-user-provisioning), SQL users will be created automatically on first authentication.
  * If automatic user provisioning is disabled, a SQL user that corresponds with your external identity must be pre-created on the cluster. To create users, you must have access to the <InternalLink path="security-reference/authorization#admin-role">`admin` role</InternalLink>.
* **(Optional) DB Console JWT Generation**: To use the DB Console to generate JWTs (instead of obtaining them directly from your IdP), you must have your cluster pre-configured for OIDC/SSO authentication for DB Console. Use the <InternalLink path="sso-db-console">Single Sign-on (SSO) for DB Console</InternalLink> guide to set this up.
* **(Optional) JWT Authorization**: To enable automatic role synchronization based on IdP group claims, see <InternalLink path="jwt-authorization">JWT Authorization</InternalLink>.

## Configure your cluster for SSO

### Cluster Settings

You must configure the <InternalLink path="cluster-settings">cluster settings</InternalLink> in the following table to enable JWT authentication to your cluster. Refer to the [Update your cluster settings](#update-your-cluster-settings) section to configure your cluster settings.

| Cluster Setting                                                        | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| ---------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `server.jwt\_authentication.enabled`                                   | Defaults to `false`, must be set to `true` to enable embedded JWT generation.                                                                                                                                                                                                                                                                                                                                                                                                            |
| `server.jwt\_authentication.jwks`                                      | A list of public signing keys for allowed IdPs; must include your IdP's key. If `server.jwt\_authentication.jwks\_auto\_fetch.enabled` is `true`, there is no need to set `server.jwt\_authentication.jwks`.                                                                                                                                                                                                                                                                             |
| `server.jwt\_authentication.jwks\_auto\_fetch.enabled`                 | If `true`, public signing keys are automatically fetched from the issuer and there is no need to set `server.jwt\_authentication.jwks`. Defaults to `false`.                                                                                                                                                                                                                                                                                                                             |
| `server.jwt_authentication.issuers.configuration`                      | A list of accepted token issuers; must include your IdP. Can be any of the following: <ul><li>A string representing a valid issuer URL</li><li>A string that contains a JSON array of issuer URLs</li><li>A string that contains a JSON map of issuer URLs to JWKS URIs</li></ul>The format is detected automatically. Refer to the [configuration examples](#configuration-examples). The previous cluster setting name `server.jwt_authentication.issuers` is aliased to this setting. |
| `server.jwt\_authentication.issuer\_custom\_ca`                        | A string that contains the name of the custom root CA to use for verifying certificates when fetching a JWKS from the issuer.                                                                                                                                                                                                                                                                                                                                                            |
| `server.jwt\_authentication.client.timeout`                            | An optional HTTP client timeout for external calls made during JWT authentication, in seconds. Defaults to `15` seconds.                                                                                                                                                                                                                                                                                                                                                                 |
| `server.jwt\_authentication.audience`                                  | This must match `server.oidc\_authentication.client\_id`; refer to <InternalLink path="sso-db-console">Single Sign-on (SSO) for DB Console</InternalLink>.                                                                                                                                                                                                                                                                                                                               |
| `server.jwt\_authentication.claim`                                     | The JWT field that will be used to determine the user identity in CockroachDB; normally set either to `email`, or `sub` (subject).                                                                                                                                                                                                                                                                                                                                                       |
| `server.jwt\_authentication.authorization.enabled`                     | Enables automatic role synchronization based on JWT groups claim. See <InternalLink path="jwt-authorization">JWT Authorization</InternalLink>. Defaults to `false`.                                                                                                                                                                                                                                                                                                                      |
| `server.jwt\_authentication.group\_claim`                              | JWT field containing groups for authorization. Defaults to `groups`. See <InternalLink path="jwt-authorization">JWT Authorization</InternalLink>.                                                                                                                                                                                                                                                                                                                                        |
| `server.jwt\_authentication.userinfo\_group\_key`                      | Userinfo endpoint JSON key for groups fallback. Defaults to `groups`. See <InternalLink path="jwt-authorization">JWT Authorization</InternalLink>.                                                                                                                                                                                                                                                                                                                                       |
| `security.provisioning.jwt.enabled`                                    | Enables automatic user creation on first JWT login. Defaults to `false`. See [Configure user provisioning](#configure-user-provisioning).                                                                                                                                                                                                                                                                                                                                                |
| `server.oidc\_authentication.generate\_cluster\_sso\_token.enabled`    | Enables token generation; must be set to `true`.                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `server.oidc\_authentication.generate\_cluster\_sso\_token.use\_token` | Selects which part of the received OIDC credentials to display.                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `server.identity\_map.configuration`                                   | Takes an [Identity Map configuration](#identity-map-configuration).                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `server.sql\_host`                                                     | This display value informs users the host for their SQL connections. Default: `localhost`.                                                                                                                                                                                                                                                                                                                                                                                               |
| `server.sql\_port`                                                     | This display value informs users the port for their SQL connections. Default: `26257`.                                                                                                                                                                                                                                                                                                                                                                                                   |

### Update your cluster settings

<Note>
  <InternalLink path="sso-db-console">Single Sign-on (SSO) for DB Console</InternalLink> and cluster SSO cannot be configured with different
  IdPs.
</Note>

Follow these steps to configure Cluster SSO.

1. In your IdP, find:
   * The **issuer name**, which can be found in the `iss` field of a JWT.
   * The issuer's **OpenID configuration endpoint**, which is typically published at `https://{ issuer URL }/.well-known/openid-configuration`. The **issuer URL** is the domain portion of the configuration endpoint. From the full endpoint, you can find the issuer URL, and vice versa. For example, the issuer URL for CockroachDB Cloud is `https://cockroachlabs.cloud` and the configuration endpoint is `https://cockroachlabs.cloud/.well-known/openid-configuration`. The configuration endpoint for Google Cloud is `https://accounts.google.com` and the configuration endpoint is `https://accounts.google.com/.well-known/openid-configuration`. If you omit the `.well-known/openid-configuration` portion, it is appended automatically.
   * The **public signing key** your issuer uses to sign JWTs. Your cluster will reject JWTs that are not signed by this key. Fetch the public signing key from the configuration endpoint. For example:

     ```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
     curl --silent https://accounts.google.com/.well-known/openid-configuration | jq .jwks_uri | xargs curl
     ```

     ```txt theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
     {
       "keys": [
         {
           "alg": "RS256",
           "use": "sig",
           "e": "AQAB",
           "kty": "RSA",
           "kid": "7c0b6913fe13820a333399ace426e70535a9a0bf",
           "n": "lWXY0XOj_ikSIDIvGOhfuRhQJAAj6BWsbbZ6P-PXRclzV32-QLB4GZHPPcH37Lou5pQsTQPvTETAfCLnglIRSbP8x1zA5tUakRlm5RiGF4kcWh5k60x8u0Uslx-d6EueKuY-KLHUVDuMULlHkYAScIdYnXz-Cnr6PFZj8RQezzdPVPH53Q8a_Z9b-vpGzsMS5gszITb-72OQNokojXdPVctl5WzSx-JnWbJxPiwHx_dSWgmTnyiYrZLqrqfampGdroaamtIXy0W8CAe0uCqcD1LunpfX-Q-RD1IycxnEaXSuUKhNhCcxtHWrozEyeD23Zja2WlcvHdYuTzyrvrvS9Q"
         },
         {
           "kid": "6f7254101f56e41cf35c9926de84a2d552b4c6f1",
           "e": "AQAB",
           "alg": "RS256",
           "use": "sig",
           "n": "oUriU8GqbRw-avcMn95DGW1cpZR1IoM6L7krfrWvLSSCcSX6Ig117o25Yk7QWBiJpaPV0FbP7Y5-DmThZ3SaF0AXW-3BsKPEXfFfeKVc6vBqk3t5mKlNEowjdvNTSzoOXO5UIHwsXaxiJlbMRalaFEUm-2CKgmXl1ss_yGh1OHkfnBiGsfQUndKoHiZuDzBMGw8Sf67am_Ok-4FShK0NuR3-q33aB_3Z7obC71dejSLWFOEcKUVCaw6DGVuLog3x506h1QQ1r0FXKOQxnmqrRgpoHqGSouuG35oZve1vgCU4vLZ6EAgBAbC0KL35I7_0wUDSMpiAvf7iZxzJVbspkQ",
           "kty": "RSA"
         }
       ]
     }
     ```

2. Enable JWT SQL authentication for your cluster:

   ```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   SET CLUSTER SETTING server.jwt_authentication.enabled = true;
   ```

3. Add your IdP's issuer URL to your cluster's list of accepted token issuers. If you have already configured <InternalLink path="sso-db-console#cluster-settings">Single Sign-on (SSO) for DB Console</InternalLink>, the issuer URL must match the value of `server.oidc_authentication.provider_url`.

   ```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   SET CLUSTER SETTING server.jwt_authentication.issuers.configuration = 'https://cockroachlabs.cloud';
   ```

4. Configure your cluster's audience, which is your cluster's ID (or JSON array of IDs) in your IdP. The audience is a mechanism for limiting the clients that can obtain JWTs from your IdP. If you have already configured <InternalLink path="sso-db-console#cluster-settings">Single Sign-on (SSO) for DB Console</InternalLink>, the issuer URL must match the value of `server.oidc_authentication.client_id`.

   Many third-party token issuers, including GCP and Azure, default to creating tokens with a generic default audience. We recommend limiting the scope of access tokens if possible.

   By extension, if your provider allows you to specify scopes or permissions on the token, we recommend configuring the scopes or permissions to be as restrictive as possible.

   ```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   SET CLUSTER SETTING server.jwt_authentication.audience = '984901724939-njig7lkv7k724rbv2hllvr4of8ul7th7.apps.googleusercontent.com';
   ```

5. Configure the field in the JWT that contains the email address that corresponds to a SQL user.

   ```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   SET CLUSTER SETTING server.jwt_authentication.claim = 'email';
   ```

6. Add your IdP's public signing key, which you found previously, to your cluster's list of acceptable signing JSON web keys (JWKS). Your cluster will reject JWTs that are not signed by a signing key that is listed in `server.jwt_authentication.jwks`. If you want to [enable automatic fetching of signing keys](#configuration-examples) instead of configuring static signing keys, skip this step.

   IdPs such as Google rotate their signing keys periodically. You must update your cluster with a new signing key before the previous one expires, or your SQL clients will be unable to connect with cluster SSO. **We recommend updating this cluster setting with the current key daily to avoid this scenario.** Alternatively, you can enable `server.jwt_authentication.jwks_auto_fetch.enabled` to automatically fetch signing keys from the issuer instead of maintaining a static list of signing keys. If `server.jwt_authentication.jwks_auto_fetch.enabled` is enabled, then `server.jwt_authentication.jwks` is ignored.

   By default, CockroachDB Advanced clusters are configured with CockroachDB Cloud's public key, so that CockroachDB Cloud can serve as an IdP. This is required for <InternalLink version="cockroachcloud" path="cloud-sso-sql">SSO with `ccloud`</InternalLink>. When modifying this cluster setting, do not omit the CockroachDB Cloud public key from the key set, or SSO with `ccloud` will no longer work.

   The public key for can be found at `https://cockroachlabs.cloud/.well-known/openid-configuration`.

   Replace the full contents of `keys` with the list of keys you found previously.

   ```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   SET CLUSTER SETTING server.jwt_authentication.jwks = '{
     "keys": [
       {
         ...
       }
     ]
   }';
   ```

7. Instead of setting `server.jwt_authentication.jwks` to a list of static signing keys, you can set `server.server.jwt_authentication.jwks_auto_fetch.enabled` to `true` to enable automatic fetching of signing keys for the issuers specified in `server.jwt_authentication.issuers.configuration`. Signing keys are fetched from the issuer's`https://{ domain }/.well-known/openid-configuration` endpoint.

| Type                 | Example                                                                                                                                                                      |
| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Single issuer URL    | `'https://accounts.google.com/'`                                                                                                                                             |
| Array of issuer URLs | `'["example.com/adfs","https://accounts.google.com"]'`                                                                                                                       |
| Map of issuer URLs   | `'{ "issuer\_jwks\_map": { "https://accounts.google.com/": "https://www.googleapis.com/oauth2/v3/certs", "example.com/adfs": "https://example.com/adfs/discovery/keys" } }'` |

8. Set your Identity Map. Refer to [Identity Map configuration](#identity-map-configuration).

   ```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   SET CLUSTER SETTING
     server.identity_map.configuration = 'https://accounts.google.com /^(.*)@cockroachlabs\.com$ \1';
   ```

9. Enable token generation.

   This will also enable the **Token Generation** button to appear in the DB Console.

   ```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   SET CLUSTER SETTING
     server.oidc_authentication.generate_cluster_sso_token.enabled = true;
   ```

10. Configure how the user's identity will be displayed by setting `server.oidc_authentication.generate_cluster_sso_toke.use_token` to either `id_token` or `access_token`, depending on the structure of the JWTs issued by your IdP.

    ```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
    SET CLUSTER SETTING
      server.oidc_authentication.generate_cluster_sso_token.use_token = id_token;
    ```

## How CockroachDB determines the SQL username from a JWT

1. `server.jwt_authentication.claim` determines which field to use to identify the external user. This must match a SQL user via the identity map.
2. `server.identity_map.configuration` maps that claim (along with the token’s issuer) to a SQL username.

## Identity Map configuration

Th cluster setting `server.identity_map.configuration` holds your cluster's identity map configuration, which tells your cluster how to map external identities to SQL users. This is functionally similar to PostgreSQL's [User Name Map](https://www.postgresql.org/docs/current/auth-username-maps).

<Note>
  Each line potentially maps many external identities to one SQL user, and a configuration can contain multiple lines,
  so the mapping can be many-to-many. The cluster checks to see if the SQL username given in the connection request
  matches the identity in the token by any of the lines in the Identity Map.
</Note>

The format of an identity map configuration is a space-separated triple consisting of:

`<external issuer <external user ID> <SQL username>`

Examples:

* `https://accounts.google.com /^(.*)@cockroachlabs\.com$ \1`

  Maps every `cockroachlabs` email to a SQL user with the same username. That is, the part of the email address to the left of the `@`). For example, `docs@cockroachlabs.com` becomes `docs`.

* `https://accounts.google.com 1232316645658094244789 roach`

  Maps a single external identity with the hard-coded ID to the <InternalLink version="cockroachcloud" path="managing-access#manage-sql-users-on-a-cluster">SQL user</InternalLink> `roach`.

* `https://accounts.google.com /^([9-0]*)$ gcp_\1`

  Maps each GCP-provisioned service account to a SQL user named `gcp_{ GCP user ID }`. For example, `gcp_1234567` for a service account with ID `1234567`.

## Configure user provisioning

CockroachDB can automatically create users on their first JWT authentication, eliminating the need to pre-create user accounts.

### Enable user provisioning

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
SET CLUSTER SETTING security.provisioning.jwt.enabled = true;
```

### How it works

1. A user presents a valid JWT token during authentication.
2. If the user doesn't exist in CockroachDB, the user is created automatically.
3. The user is tagged with the `PROVISIONSRC` role option: `jwt_token:<issuer`, where `<issuer` is the JWT issuer URL.
4. If <InternalLink path="jwt-authorization">JWT authorization</InternalLink> is also enabled, roles are synchronized immediately after user creation.

### Auditing provisioned users

You can identify automatically provisioned users by viewing their role options:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
SHOW ROLES;
```

Example output:

```txt theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
  username  |                       options                        | member_of
------------+------------------------------------------------------+-----------
  alice     | {PROVISIONSRC=jwt_token:https://auth.example.com}    | {developers}
  bob       | {PROVISIONSRC=jwt_token:https://auth.example.com}    | {admins}
```

Users provisioned via JWT will have `PROVISIONSRC=jwt_token:<issuer` in their options column.

### Security considerations

* **Validate JWT issuers carefully**: Ensure `server.jwt_authentication.issuers.configuration` only includes trusted issuers, as any valid JWT from these issuers can create new users.
* **Monitor provisioned users**: Regularly review automatically created users to ensure only authorized users are being provisioned.
* **Combine with JWT authorization**: Consider enabling <InternalLink path="jwt-authorization">JWT authorization</InternalLink> to automatically grant appropriate roles to provisioned users based on their IdP group memberships.
* **Password management**: Provisioned users cannot change their own passwords, as authentication is managed through the IdP.

<Note>
  If you are going to use JWT user provisioning in conjunction with <InternalLink path="jwt-authorization">JWT authorization</InternalLink>,
  be sure to create the necessary roles in CockroachDB before enabling user provisioning. Auto-provisioned users will
  only receive roles for groups that already exist as CockroachDB roles.
</Note>

## Authenticate to your cluster

JWT authentication supports two methods for obtaining tokens:

1. **Obtain JWTs directly from your IdP**: Use your identity provider's API or SDK to generate JWT tokens (e.g., via Okta APIs, Google OAuth, Azure AD). This is the primary method and requires only the JWT authentication cluster settings configured above.
2. **Generate JWTs via DB Console**: If you have <InternalLink path="sso-db-console">OIDC authentication for DB Console</InternalLink> configured, users can obtain JWT tokens through the DB Console UI.

This section describes the DB Console method. For obtaining JWTs directly from your IdP, refer to your identity provider's documentation.

### Authenticate using DB Console-generated JWTs

Once DB Console SSO and Cluster SSO with JWTs are enabled and your cluster is [properly configured](#configure-your-cluster-for-sso) (including mapping authorized external users to SQL roles), users can self-provision auth tokens through a sign-in flow embedded in the DB Console. These tokens (JWTs) are intended as short-lived credentials. The expiry is set based on the OIDC token from your identity provider, which is typically 1 hour.

<Tip>
  This example uses <InternalLink path="cockroach-sql">`cockroach sql`</InternalLink>, but you can use any SQL client that supports
  sufficiently long passwords.
</Tip>

1. Obtain a token.

   Go to your cluster's DB Console and click the **Generate JWT auth token for cluster SSO** button

2. Use the token in place of a password in your database connection string.

   ```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   cockroach sql --url "postgresql://{SQL_USERNAME}:{JWT_TOKEN}@{CLUSTER_HOST}:26257?options=--crdb:jwt_auth_enabled=true" --certs-dir={CLUSTER_CERT_DIR}
   ```

   ```txt theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   Welcome to the cockroach SQL interface...
   ```

## What's Next?

* Learn more about <InternalLink path="authentication">Authentication</InternalLink> in CockroachDB.
* This [Cockroach Labs blog post](https://www.cockroachlabs.com/blog/sso-to-clusters-with-jwt) covers and provides further resources for a variety of auth token-issuing use cases, including using Okta and Google Cloud Platform to issue tokens.

## See also

* <InternalLink path="ui-overview">DB Console Overview</InternalLink>
* <InternalLink path="sso-db-console">Single Sign-on (SSO) for DB Console</InternalLink>
* <InternalLink path="jwt-authorization">JWT Authorization</InternalLink>
* <InternalLink path="oidc-authorization">OIDC Authorization</InternalLink>
* <InternalLink path="ldap-authorization">LDAP Authorization</InternalLink>
