Single sign-on (SSO)

View as Markdown
PREVIEW This feature is in public preview. It is under active development and may have stability or performance issues. It isn't subject to our backwards compatibility guarantees.

Single sign-on (SSO) allows users to authenticate to Self-Managed Materialize using their organization’s identity provider (IdP) via OpenID Connect (OIDC). Instead of managing passwords directly in Materialize, users sign in through their IdP (e.g., Okta, Microsoft Entra ID) and receive a JWT token that Materialize validates.

NOTE: SSO handles authentication only. Permissions within the database are managed separately using role-based access control (RBAC).

Before you begin

Make sure you have:

  • An OIDC-capable identity provider (e.g., Okta, Microsoft Entra ID, or any provider that supports OpenID Connect).
  • Admin access to your Kubernetes cluster where Materialize is deployed.

Step 1. Configure your identity provider

NOTE:

You will use the following values from your IdP configuration to configure OIDC system parameters for Materialize:

  • The OIDC issuer URL
  • The client ID for the console application
  • If using service accounts, the client ID, client secret, and expected audience for each service-account application

The following steps create the OIDC application for the Materialize Console (browser-based login). If you also need service accounts, you will create additional applications in the Service accounts section.

  1. In the Okta Admin Console, go to Applications > Applications and click Create App Integration.

  2. Select OIDC - OpenID Connect as the sign-in method and Single-Page Application as the application type. Click Next.

  3. Configure the application:

    • App integration name: Enter a name (e.g., Materialize).
    • Grant type: Ensure Authorization Code is selected (PKCE is used automatically for single-page applications).
    • Sign-in redirect URIs: Enter https://<your-console-domain>/auth/callback. If you want to use the CLI token flow, also add http://localhost:9876/callback.
    • Sign-out redirect URIs: Optionally, enter https://<your-console-domain>/account/login.
  4. Click Save.

  5. On the application’s General tab, note the Client ID.

    Single-page applications use PKCE instead of a client secret. You do not need a client secret for the console application.

  6. Go to Security > API and note your Issuer URI from the authorization server you want to use (e.g., https://your-org.okta.com/oauth2/default).

    Custom domains: When the authorization server Issuer is set to Dynamic (based on Request Domain), Okta issues tokens whose iss claim uses your custom domain (for example, https://sso.your-org.com/oauth2/default) instead of the default Okta URL. Configure the oidc_issuer system parameter in Materialize to match that issuer value exactly.

  7. Go to the Assignments tab and assign the users or groups that should have access to Materialize.

    When a user authenticates via SSO, Materialize uses a JWT claim to determine the role name. See Mapping IdP users to Materialize roles for more details.

  8. Configure the authorization server. In the Okta Admin Console, go to Security > API and click on the authorization server you want to use (e.g., default).

    1. On the Settings tab, note the Issuer URI. This is the value you will use for the oidc_issuer system parameter.

    2. Go to the Scopes tab and ensure the openid and email scopes exist (they are present by default).

    3. Go to the Access Policies tab. You need at least one policy with a rule that allows the grant types you plan to use:

      To add or edit a rule:

      1. Click Add New Access Policy (or select an existing policy).
      2. Click Add Rule within the policy.
      3. Under Grant type is, check the grant types you need.
      4. Under Assigned to, select the clients (applications) this rule applies to.
      5. Click Create Rule.
  1. In the Azure portal, go to Microsoft Entra ID > App registrations and click New registration.

  2. Configure the registration:

    • Name: Enter a name (e.g., Materialize).
    • Supported account types: Select the appropriate option for your organization (typically Accounts in this organizational directory only).
    • Redirect URI: Select Single-page application (SPA) and enter https://<your-console-domain>/auth/callback. After registration, you can add http://localhost:9876/callback under Authentication if you want to use the CLI token flow.
  3. Click Register.

  4. On the application’s Overview page, note the Application (client) ID and the Directory (tenant) ID.

  5. Go to Certificates & secrets > New client secret. Add a description and expiration, then click Add. Note the secret Value.

    A client secret is not required for the console login (which uses authorization code with PKCE), but is needed if you plan to use the Client Credentials flow for service accounts.

  6. Construct your issuer URL using your tenant ID:

    https://login.microsoftonline.com/<tenant-id>/v2.0
    
  7. Go to Enterprise applications > select your application > Users and groups and assign the users or groups that should have access to Materialize.

    When a user authenticates via SSO, Materialize uses a JWT claim to determine the role name. See Mapping IdP users to Materialize roles for more details.

  1. In your identity provider, create a new OIDC public client application (single-page application type) with the Authorization Code grant type and PKCE support.

  2. Set the redirect URI to https://<your-console-domain>/auth/callback. If you want to use the CLI token flow, also add http://localhost:9876/callback.

  3. Note the client ID and issuer URL provided by your identity provider. The issuer URL is typically the base URL of your identity provider’s OIDC discovery endpoint (without /.well-known/openid-configuration).

  4. Ensure the openid scope is available.

  5. Assign users or groups that should have access to Materialize.

    When a user authenticates via SSO, Materialize uses a JWT claim to determine the role name. See Mapping IdP users to Materialize roles for more details.

NOTE:

Once you have configured your IdP, you will need the following values to configure OIDC system parameters for Materialize:

  • The OIDC issuer URL
  • The client ID for the console application
  • If using service accounts, the client ID, client secret, and expected audience for each service-account application

Step 2. Enable OIDC authentication

To configure Self-Managed Materialize for OIDC authentication, update the following fields:

Resource Configuration Description
Materialize CR spec.authenticatorKind Set to Oidc to enable OIDC authentication.
Kubernetes Secret external_login_password_mz_system Specify the password for the mz_system user. Add external_login_password_mz_system to the Kubernetes Secret referenced in the Materialize CR’s spec.backendSecretName field. The mz_system user always authenticates with a password. This user is required by the Materialize Operator for upgrades and serves as an emergency administrative account.

The following example Kubernetes manifest includes configuration for OIDC authentication:

apiVersion: v1
kind: Namespace
metadata:
  name: materialize-environment
---
apiVersion: v1
kind: Secret
metadata:
  name: materialize-backend
  namespace: materialize-environment
stringData:
  metadata_backend_url: "..."
  persist_backend_url: "..."
  license_key: "..."
  external_login_password_mz_system: "enter_mz_system_password"
---
apiVersion: materialize.cloud/v1alpha1
kind: Materialize
metadata:
  name: 12345678-1234-1234-1234-123456789012
  namespace: materialize-environment
spec:
  environmentdImageRef: materialize/environmentd:v26.26.0 # Use v26.26.0 or later
  backendSecretName: materialize-backend
  authenticatorKind: Oidc
  requestRollout: 00000000-0000-0000-0000-000000000003 # Switching to Oidc requires a rollout

Apply the updated manifest to your Kubernetes cluster. See Upgrading for details on rollout configuration.

WARNING! Once enabled, ensure that the authenticatorKind field is set for any future version upgrades or rollouts of the Materialize CR. Having it undefined will reset authenticationKind to None.

Step 3. Configure OIDC system parameters

Configure the OIDC system parameters to connect Materialize to your identity provider. You can use either a ConfigMap or SQL commands, but it is strongly recommended to use a ConfigMap. See Configure via Configmap for more details.

OIDC system parameters

Parameter Description Required Default
oidc_issuer The OIDC issuer URL (e.g., https://your-org.okta.com/oauth2/default). Materialize uses this to discover the JWKS endpoint for token validation. Yes None
oidc_audience A JSON array of expected audience values for token validation (e.g., ["your-client-id"]). Use the client ID from Step 1. Materialize checks that the JWT’s aud claim contains at least one of these values. By default, this is empty, and audience validation is skipped. No []
oidc_authentication_claim The JWT claim to use as the Materialize username. For ID tokens (human users), a common claim is email. For access tokens from the Client Credentials flow, ensure this claim exists in the token. See Mapping IdP users to Materialize roles for details. No sub
console_oidc_client_id The OIDC client ID used by the web console for the authorization code flow. For console login Empty
console_oidc_scopes Space-separated OIDC scopes requested by the web console when obtaining a token. Scopes control which claims are included in the token. The openid scope is required to obtain an ID token. Add email to include the email claim, or profile to include name claims. If oidc_authentication_claim references a claim like email, you must request the corresponding scope here. For console login Empty
WARNING! When oidc_audience is empty, audience validation is skipped. This means any valid token from the same identity provider can authenticate to Materialize, including tokens issued for other applications. Always set oidc_audience in production environments.

Configure via ConfigMap

Create a ConfigMap with your OIDC parameters and reference it in the Materialize CR’s spec.systemParameterConfigmapName field. At this point, your manifest should look like:

apiVersion: v1
kind: ConfigMap
metadata:
  name: mz-system-params
  namespace: materialize-environment
data:
  system-params.json: |
    {
      "oidc_issuer": "YOUR_OIDC_ISSUER",
      "oidc_audience": "[\"YOUR_CLIENT_ID\"]",
      "oidc_authentication_claim": "email",
      "console_oidc_client_id": "YOUR_CLIENT_ID",
      "console_oidc_scopes": "openid email"
    }
---
apiVersion: v1
kind: Secret
metadata:
  name: materialize-backend
  namespace: materialize-environment
stringData:
  metadata_backend_url: ...
  persist_backend_url: ...
  license_key: ...
  external_login_password_mz_system: "enter_mz_system_password"
---
apiVersion: materialize.cloud/v1alpha1
kind: Materialize
metadata:
  name: 12345678-1234-1234-1234-123456789012
  namespace: materialize-environment
spec:
  authenticatorKind: Oidc
  backendSecretName: materialize-backend
  requestRollout: 00000000-0000-0000-0000-000000000003 # Switching to Oidc requires a rollout
  systemParameterConfigmapName: mz-system-params
NOTE: This example sets oidc_authentication_claim to email rather than the default sub, so each user’s role name comes from their email claim. Because the authentication claim references email, console_oidc_scopes includes the email scope to ensure that claim is present in the token.

Apply the updated manifest to your Kubernetes cluster. For more on configuring system parameters via a ConfigMap, see System parameters configuration.

Configure via SQL

Alternatively, connect as mz_system and set the parameters using ALTER SYSTEM SET. The mz_system user always authenticates with a password, even when OIDC is enabled.

ALTER SYSTEM SET oidc_issuer = 'https://your-org.okta.com/oauth2/default';
ALTER SYSTEM SET oidc_audience = '["YOUR_CLIENT_ID"]';
ALTER SYSTEM SET oidc_authentication_claim = 'email';
ALTER SYSTEM SET console_oidc_client_id = 'YOUR_CLIENT_ID';
ALTER SYSTEM SET console_oidc_scopes = 'openid email';

Step 4. Verify the configuration

  1. Navigate to your Materialize Console. You should see an option to Use single sign-on.

    Materialize Console login screen showing the SSO sign-in
option

  2. Sign in through your IdP. After successful authentication, you are redirected back to the Materialize Console.

  3. To confirm which role you’ve signed in as via SSO, open the SQL Shell in the Materialize Console. In the welcome message, you should see the role name labeled under “User”. This is derived from the oidc_authentication_claim claim in your identity token:

Materialize Console Shell

Connecting via SQL clients

To connect to Materialize using a SQL client like psql, you need an OIDC ID token.

If your client doesn’t support OAuth, you can create a role with a SQL password instead. See SQL password authentication.

Get a token using CLI tools

You can fetch an ID token from the command line using oauth2c. This is useful when configuring a non-interactive client like dbt or Terraform.

  1. Confirm http://localhost:9876/callback is registered as a redirect URI on the console OIDC client (added in Step 1). oauth2c listens on this URL during the auth code exchange.

  2. Install oauth2c. On macOS:

    brew install cloudentity/tap/oauth2c
    

    Other platforms: see the oauth2c installation guide.

  3. Run oauth2c to fetch the ID token:

    oauth2c <ISSUER_URL> \
      --client-id <YOUR_CLIENT_ID> \
      --response-types code \
      --response-mode form_post \
      --grant-type authorization_code \
      --pkce \
      --scopes 'openid email' \
      --auth-method none \
      --silent | jq -r '.id_token'
    

    A browser window opens to complete the IdP login. After signing in, oauth2c prints the ID token to stdout.

ID tokens expire (typically within an hour). Re-run the command above when your token expires.

Get a token from the Materialize console

Clicking “Connect” in the Materialize console will provide you with an ID token that you can use to connect.

Materialize Console connect instructions for OIDC

Connect with psql

Use the ID token as your password:

PGPASSWORD="<your-id-token>" \
psql -h <materialize-host> -p 6875 -U <username> materialize

Replace <username> with the value of the authentication claim in your JWT (e.g., your email address if oidc_authentication_claim is set to email).

NOTE: Materialize validates the token at connection time only. Once a connection is established, it persists until disconnected, regardless of token expiry.

Provisioning roles

Mapping IdP users to Materialize roles

Each user or service account that authenticates via OIDC maps to a single Materialize database role. When a user authenticates into Materialize, their role name is the value of the JWT claim keyed by oidc_authentication_claim.

For example, if oidc_authentication_claim is set to email and a user authenticates with the following JWT:

{
  "sub": "auth0|abc123",
  "email": "alice@your-org.com",
  "name": "Alice",
  "iat": 1516239022
}

Their role name will be alice@your-org.com.

If a user logs in and no matching role exists, Materialize auto-provisions one, as described in the next section.

Auto-provisioning roles

When a user signs in and no role matching their oidc_authentication_claim value exists, Materialize automatically creates a role for them.

Auto-provisioned roles:

  • Have default privileges only.
  • Must be granted additional privileges through RBAC.
  • Are not automatically removed when the user is removed from the IdP. See De-provisioning users for cleanup instructions.

Auditing auto-provisioned roles

To view which roles were auto-provisioned via OIDC, query mz_audit_events:

SELECT details
FROM mz_audit_events
WHERE event_type = 'create' AND object_type = 'role' AND details ->> 'auto_provision_source' = 'oidc'
ORDER BY occurred_at DESC;

Roles created through OIDC authentication will have auto_provision_source set to oidc.

Pre-provisioning roles

An administrator can create roles before users login, rather than rely on auto-provisioning. To pre-provision a role, connect as a superuser and create the role with a name matching the expected JWT claim value:

CREATE ROLE "alice@your-org.com" WITH LOGIN;

Like auto-provisioned roles, pre-provisioned roles start with default privileges only and must be granted additional privileges through RBAC.

Service accounts

For machine-to-machine access, you have three options:

Even with OIDC enabled, Materialize still accepts SQL password authentication. This is required for clients that don’t support OAuth flows. The simplest way to give such a service or application access is to create a role with a SQL password.

  1. As a user with the CREATEROLE privilege, create the role with a password:

    CREATE ROLE "svc-dbt" WITH LOGIN PASSWORD 'a-strong-password';
    
  2. Grant the privileges this service account needs. See Manage database roles for the full privilege model.

  3. Connect using the password directly:

    PGPASSWORD="a-strong-password" \
    psql -h <materialize-host> -p 6875 -U svc-dbt materialize
    

For dbt-specific setup, see dbt connection profiles. For Terraform, see Terraform: get started.

Resource Owner Password flow

Use this approach when you need a service account that authenticates with a username and password to obtain an ID token.

  1. In the Okta Admin Console, go to Applications > Applications and click Create App Integration.

  2. Select OIDC - OpenID Connect as the sign-in method and Native Application as the application type. Click Next.

  3. Configure the application:

    • App integration name: Enter a name (e.g., Materialize ROPC).
    • Grant type: Enable Resource Owner Password.
  4. Click Save and note the Client ID and Client Secret.

  5. Go to the Assignments tab and assign the service account user.

  6. Ensure your authorization server’s access policy includes a rule that allows the Resource Owner Password grant type for this application. See the authorization server setup in Step 1.

  7. In Okta, create a new user to serve as the service account (e.g., svc-materialize@your-org.com).

    The Resource Owner Password flow does not support MFA in Okta. The service account user must not have MFA enabled.

  8. Fetch an ID token:

    curl -X POST https://your-org.okta.com/oauth2/default/v1/token \
      -H "Content-Type: application/x-www-form-urlencoded" \
      -H "Accept: application/json" \
      --data-urlencode "grant_type=password" \
      --data-urlencode "username=svc-materialize@your-org.com" \
      --data-urlencode "password=YOUR_SERVICE_ACCOUNT_PASSWORD" \
      --data-urlencode "scope=openid email" \
      --data-urlencode "client_id=YOUR_ROPC_CLIENT_ID" \
      --data-urlencode "client_secret=YOUR_ROPC_CLIENT_SECRET"
    
  9. Extract the id_token from the JSON response and use it to connect:

    PGPASSWORD="<id-token>" \
    psql -h <materialize-host> -p 6875 -U svc-materialize@your-org.com materialize
    
  1. In the Azure portal, go to Microsoft Entra ID > App registrations and click New registration. Create a dedicated registration for this flow rather than reusing the console application from Step 1.

  2. Configure the registration:

    • Name: Enter a name (e.g., Materialize ROPC).
    • Supported account types: Select the appropriate option for your organization.
  3. Click Register.

  4. Go to Authentication and set Allow public client flows to Yes. This is required for the Resource Owner Password flow.

  5. On the application’s Overview page, note the Application (client) ID and the Directory (tenant) ID.

  6. Go to Certificates & secrets > New client secret. Add a description and expiration, then click Add. Note the secret Value.

  7. Create a new user to serve as the service account, then assign it to this application under Enterprise applications > Users and groups.

  8. Fetch an ID token:

    curl -X POST https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token \
      -H "Content-Type: application/x-www-form-urlencoded" \
      --data-urlencode "grant_type=password" \
      --data-urlencode "username=svc-materialize@your-org.com" \
      --data-urlencode "password=YOUR_SERVICE_ACCOUNT_PASSWORD" \
      --data-urlencode "scope=openid email" \
       --data-urlencode "client_id=YOUR_CLIENT_ID"
      --data-urlencode "scope=openid" \
      --data-urlencode "client_id=YOUR_CLIENT_ID" \
      --data-urlencode "client_secret=YOUR_CLIENT_SECRET"
    
  9. Extract the id_token from the JSON response and use it to connect:

    PGPASSWORD="<id-token>" \
    psql -h <materialize-host> -p 6875 -U svc-materialize@your-org.com materialize
    
  1. Create a service account user in your identity provider.

  2. Assign the service account to your Materialize application.

  3. Enable the Resource Owner Password Credentials grant for your application.

  4. Fetch an ID token from your IdP’s token endpoint:

    curl -X POST https://your-idp.com/oauth2/token \
      -H "Content-Type: application/x-www-form-urlencoded" \
      --data-urlencode "grant_type=password" \
      --data-urlencode "username=svc-materialize@your-org.com" \
      --data-urlencode "password=YOUR_SERVICE_ACCOUNT_PASSWORD" \
      --data-urlencode "scope=openid email" \
      --data-urlencode "client_id=YOUR_CLIENT_ID" \
      --data-urlencode "client_secret=YOUR_CLIENT_SECRET"
    
  5. Extract the id_token from the JSON response and use it to connect:

    PGPASSWORD="<id-token>" \
    psql -h <materialize-host> -p 6875 -U svc-materialize@your-org.com materialize
    

Client Credentials flow

Use this approach to treat an IdP client as a service account. This is useful for automated systems that do not have a user context.

NOTE: oidc_audience is an array of values. Before running the ALTER SYSTEM SET oidc_audience examples below, check the current value with SHOW oidc_audience; and append the new audience rather than overwriting it. Otherwise you may remove the console’s audience or other configured values.
  1. In the Okta Admin Console, go to Applications > Applications and click Create App Integration.

  2. Select OIDC - OpenID Connect as the sign-in method and Web Application as the application type. Click Next.

  3. Configure the application:

    • App integration name: Enter a name (e.g., Materialize Service Account 1).
    • Grant type: Enable Client Credentials (deselect other grant types).
  4. Click Save and note the Client ID and Client Secret.

  5. Ensure your authorization server’s access policy includes a rule that allows the Client Credentials grant type for this application. See the authorization server setup in Step 1.

  6. Configure a custom claim for the service account identity.

    The oidc_authentication_claim setting is global — it applies to both human users (ID tokens) and service accounts (access tokens). If set to email, human users get readable role names (e.g., alice@your-org.com), but Client Credentials access tokens do not include an email claim by default. If set to sub, Client Credentials tokens work, but human users lose email-based role names and get opaque subject IDs instead.

    To solve this, create a custom claim (e.g., sql_username) in your authorization server that maps to user.email for ID tokens and to a configured value for access tokens:

    1. In the Okta Admin Console, go to Security > API and select your authorization server.

    2. Go to the Claims tab and click Add Claim.

    3. Configure the claim for ID tokens (human users):

      • Name: sql_username
      • Include in token type: ID Token (always).
      • Value type: Expression.
      • Value: appuser.email
      • Include in: Any scope.
    4. Click Create, then click Add Claim again.

    5. Configure the claim for access tokens (service accounts):

      • Name: sql_username
      • Include in token type: Access Token (always).
      • Value type: Expression.
      • Value: app.sub
      • Include in: Any scope.
    6. Click Create.

    7. Set the authentication claim in Materialize:

      ALTER SYSTEM SET oidc_authentication_claim = 'sql_username';
      

    If you have multiple service accounts using Client Credentials, each needs its own Okta application.

  7. Fetch an access token:

    curl -X POST https://your-org.okta.com/oauth2/default/v1/token \
      -H "Content-Type: application/x-www-form-urlencoded" \
      -H "Accept: application/json" \
      --data-urlencode "grant_type=client_credentials" \
      --data-urlencode "scope=openid" \
      --data-urlencode "client_id=YOUR_SERVICE_CLIENT_ID" \
      --data-urlencode "client_secret=YOUR_SERVICE_CLIENT_SECRET"
    
  8. Ensure oidc_audience includes the expected audience value for tokens from your authorization server. In Okta, the aud claim is set to the authorization server’s audience (configured in Security > API > your auth server > Settings), not the client ID. For the default authorization server, this is typically api://default:

    -- Make sure to add to the array if already set
    ALTER SYSTEM SET oidc_audience = '["api://default"]';
    
  9. Extract the access_token from the JSON response and use it to connect:

    PGPASSWORD="<access-token>" \
    psql -h <materialize-host> -p 6875 -U <service-account-name> materialize
    

    The <service-account-name> must match the value of the sql_username claim in the access token (e.g., svc-my-service).

  1. In the Azure portal, go to Microsoft Entra ID > App registrations and click New registration.

  2. Configure the registration:

    • Name: Enter a name (e.g., Materialize Service Account).
    • Supported account types: Select the appropriate option for your organization.
  3. Click Register.

  4. On the application’s Overview page, note the Application (client) ID.

  5. Go to Certificates & secrets > New client secret. Add a description and expiration, then click Add. Note the secret Value.

  6. Fetch an access token:

    curl -X POST https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token \
      -H "Content-Type: application/x-www-form-urlencoded" \
      --data-urlencode "grant_type=client_credentials" \
      --data-urlencode "scope=YOUR_SERVICE_CLIENT_ID/.default" \
      --data-urlencode "client_id=YOUR_SERVICE_CLIENT_ID" \
      --data-urlencode "client_secret=YOUR_SERVICE_CLIENT_SECRET"
    
  7. Ensure oidc_audience includes the expected audience value for Client Credentials tokens. In Entra, the aud claim is determined by the scope parameter in the token request. When using YOUR_SERVICE_CLIENT_ID/.default, the audience is the service client ID:

    -- Make sure to add to the array if already set
    ALTER SYSTEM SET oidc_audience = '["YOUR_SERVICE_CLIENT_ID"]';
    
  8. Extract the access_token from the JSON response and use it to connect:

    PGPASSWORD="<access-token>" \
    psql -h <materialize-host> -p 6875 -U <service-account-name> materialize
    

    The <service-account-name> must match the value of the authentication claim in the access token.

  1. In your identity provider, create a new OIDC client application with the Client Credentials grant type.

  2. Note the Client ID and Client Secret.

  3. Fetch an access token from your IdP’s token endpoint:

    curl -X POST https://your-idp.com/oauth2/token \
      -H "Content-Type: application/x-www-form-urlencoded" \
      --data-urlencode "grant_type=client_credentials" \
      --data-urlencode "scope=openid" \
      --data-urlencode "client_id=YOUR_SERVICE_CLIENT_ID" \
      --data-urlencode "client_secret=YOUR_SERVICE_CLIENT_SECRET"
    
  4. Ensure oidc_audience includes the expected audience value for Client Credentials tokens. Check the aud claim in the token issued by your IdP to determine the correct value:

    -- Make sure to add to the array if already set
    ALTER SYSTEM SET oidc_audience = '["YOUR_AUDIENCE_VALUE"]';
    
  5. Extract the access_token from the JSON response and use it to connect:

    PGPASSWORD="<access-token>" \
    psql -h <materialize-host> -p 6875 -U <service-account-name> materialize
    

    The <service-account-name> must match the value of the authentication claim in the access token.

De-provisioning users

When a user is removed from the identity provider, they can no longer authenticate to Materialize because their JWT tokens will no longer be valid. However, the corresponding Materialize role is not automatically deleted. This is intentional to avoid disrupting ownership of database objects.

To remove the role after de-provisioning:

-- Reassign owned objects if needed
REASSIGN OWNED BY <username> TO <new-owner>;
-- Then drop the role
DROP ROLE <username>;

Troubleshooting

Symptom Possible cause Resolution
Console does not show SSO login option console_oidc_client_id and console_oidc_scopes are not set Set console_oidc_client_id to your OIDC client ID
SSO login redirects fail Incorrect IdP configuration Verify the redirect URI is set to https://<your-console-domain>/auth/callback and the IdP application type is set as a Single Page Application
SSO login redirects to login page Materialize database is rejecting the token Verify that the token generated by your IdP includes the required claims.
environmentd fails to upgrade external_login_password_mz_system not set Ensure the external_login_password_mz_system is configured
“Invalid token” error on psql connection Wrong or expired JWT token Obtain a fresh token; verify oidc_issuer matches the token’s iss claim
“Audience validation failed” Client ID not in oidc_audience Add the client ID to oidc_audience: ALTER SYSTEM SET oidc_audience = '["your-client-id"]'
User gets wrong role name oidc_authentication_claim set to wrong claim Verify the claim name and check the JWT contents (e.g., using jwt.io)

To inspect the current OIDC configuration, login as mz_system and run the following SQL:

SHOW oidc_issuer;
SHOW oidc_audience;
SHOW oidc_authentication_claim;
SHOW console_oidc_client_id;
SHOW console_oidc_scopes;

FAQ

What happens during a blue/green deployment?

OIDC configuration (system parameters) and auto-provisioned roles are persisted in the Materialize catalog. Blue/green deployments do not affect SSO configuration or user roles. No additional action is required.

What happens if I tear down my Materialize environment?

Role data and OIDC configuration are stored in the Materialize catalog, which is persisted in your configured object storage (e.g., S3). If you delete the Materialize instance in Kubernetes and re-apply the Materialize CR, the instance rehydrates from the persisted catalog, recovering all roles and configuration.

If the underlying object storage is also deleted, the catalog and all role data are lost. Use your cloud provider’s disaster recovery policies to protect against this scenario.

See also

Back to top ↑