Skip to content

Reference

alter identity-providers

Stand up an end-user identity provider (OIDC) for an app from the CLI.

An app can trust an external identity provider (Auth0, Clerk, Okta, WorkOS) so its end users sign in with their existing accounts. These commands stand one up.

alter identity-providers discover --issuer-url <url>
alter identity-providers create --issuer-url <url> (--audience ... | --wallet-client-id ... --wallet-client-secret ...)
alter identity-providers webhook enable --provider <id> [--secret -|@file|<value>]
alter identity-providers webhook disable --provider <id> [--yes] [--force --confirm <issuer-host>]
alter identity-providers webhook rotate --provider <id> [--secret -|@file|<value>] [--yes]
alter identity-providers webhook status --provider <id>

App-scoped commands take --app <id> (or the app’s name), or link a workspace / set ALTER_APP_ID. discover / create need dashboard_identity_providers:create; the webhook subcommands need dashboard_identity_providers:webhooks. Because identity-provider configuration is an organization-admin action, only an organization admin can mint a token carrying these scopesalter auth login --scopes dashboard_identity_providers:create (or …:webhooks) run by a non-admin is refused at sign-in. Both grants are literal-only: * and dashboard_identity_providers:* do not cover them. The namespace is also available as alter idp, and create accepts the alias configure.

Preview OIDC discovery for an issuer URL without saving anything. Returns the detected provider type, JWKS URI, and suggested claim mappings, so the mappings can be verified — or overridden on create — before the one-shot create.

FlagRequiredDescription
--issuer-url <url>yesOIDC issuer URL (e.g. https://acme.okta.com). The issuer itself, not a /.well-known/... URL. A bare host with no scheme (e.g. WorkOS’s acme-corp.authkit.app) is accepted — https:// is prepended. The normalized URL must be HTTPS and at most 512 characters; localhost and explicit HTTP are rejected locally.
Terminal window
alter identity-providers discover --issuer-url https://acme.okta.com

Configure the identity provider for the app. Discovery runs against the issuer and must succeed — an unreachable or invalid issuer is rejected and nothing is saved. Claim mappings are auto-detected from the issuer; pass the override flags to set them explicitly. Every create needs an effective audience, supplied either explicitly with --audience or implicitly by the wallet client pair.

FlagRequiredDescription
--issuer-url <url>yes (unless --input)OIDC issuer URL (e.g. https://acme.okta.com). The issuer itself, not a /.well-known/... URL. A bare host with no scheme (e.g. WorkOS’s acme-corp.authkit.app) is accepted — https:// is prepended. The normalized URL must be HTTPS and at most 512 characters; localhost and explicit HTTP are rejected locally.
--audience <aud>conditionalExpected JWT aud claim (maximum 512 characters). Required unless --wallet-client-id supplies the OIDC relying-party audience. Tokens without the effective audience are rejected.
--user-id-claim <claim>noOverride the user-identity claim (auto-detected; defaults to sub; maximum 128 characters).
--group-claim <claim>noOverride the group-membership claim (auto-detected; maximum 128 characters).
--group-claim-is-idnoAssert the group claim emits stable group IDs (Okta 00g…, WorkOS org_…) rather than display names. Required for Okta/WorkOS group-principal grants; cannot be changed after the first user signs in. Requires --group-claim. (Auth0 group grants are not currently supported.)
--role-claim <claim>noOverride the role claim (auto-detected; maximum 128 characters).
--wallet-client-id <id>noOIDC client ID for interactive wallet sign-in (maximum 255 characters). Must be paired with --wallet-client-secret.
--wallet-client-secret <value>noOIDC client secret for wallet sign-in. Use - to read from stdin or @/path/to/file; an inline value prints a shell-history warning. Must be paired with --wallet-client-id.
--input <path>noJSON body from a file (@path) or stdin (-); replaces the per-field flags. Field names are the wire names (issuer_url, group_claim, group_claim_is_id, …). The CLI applies the same issuer, audience, field-length, wallet-pair, and group-claim checks as the flag form before sending the request.

Without the wallet flags, the identity provider validates inbound tokens and --audience is required. To also enable interactive wallet sign-in, pass both wallet flags — they are all-or-nothing, the audience defaults to the client ID, and the credentials are verified against the provider before anything is saved. A hard rejection fails the create with nothing saved; if verification is inconclusive (for example a transient network issue), the save proceeds unverified and the CLI prints a notice on stderr — verify with a sign-in.

--audience is checked against the provider in the same way, because the value is sent to the provider on every sign-in and one it does not recognize breaks sign-in for every end user. A rejected audience fails the create with nothing saved and exit code 1 (a validation rejection, per the exit-code table in the scripting guide), and the error names the provider’s own reason. When the audience cannot be checked — the probe did not complete, or no wallet client pair was supplied to check it with — the create succeeds and the CLI prints the verdict on stderr:

alter: audience preflight: skipped — The audience "https://api.example.com" was NOT verified: wallet sign-in credentials are not configured, so there is no client to probe the identity provider with.

A rejection is a non-zero exit, not a stderr notice. Redirect stderr to keep it out of a JSON pipeline; do not discard it, since it is the only place an unverified audience is reported.

Terminal window
alter identity-providers create \
--issuer-url https://acme.okta.com \
--audience https://api.example.com

Manage the identity provider’s webhook integration — how Alter receives events (e.g. group-sync) from the provider. These need the dashboard_identity_providers:webhooks scope, are app-scoped like the rest of the namespace (pass --app <id> (or the app’s name), or use a linked workspace / ALTER_APP_ID), and identify the provider with --provider <id>. Enabling and rotating return the signing secret, which is shown once.

FlagRequiredDescription
--app <app-id-or-name>yes*The application (*or link a workspace / set ALTER_APP_ID).
--provider <provider-id>yesThe identity provider’s ID.
--secret <value>noSigning secret for enable / rotate. For Clerk, paste the Dashboard whsec_ value; for Okta, the Event Hook secret; for WorkOS, the endpoint’s signing secret from WorkOS Dashboard → Webhooks (any format — the whsec_ prefix is not a WorkOS contract). Use - for stdin or @/path for a file; an inline value prints a shell-history warning. For Auth0, omit to have one generated. For Clerk, Okta, and WorkOS the secret is required — the CLI checks this (and Clerk’s whsec_ prefix) before making any change. On rotate, --secret - requires --yes — the stdin secret and the confirmation prompt can’t share the same stream.
--yesnoSkip the confirmation prompt on disable / rotate (for CI). Required when rotating with --secret -. Rotating invalidates the previous secret immediately.
--forcenodisable only. Active group-bound grants depend on the webhook for real-time revocation, so a plain disable is rejected with a conflict while any exist. --force revokes those grants (each revocation is audit-logged) and then disables webhooks. The cascade is type-to-confirm gated: pass --confirm <issuer-host> or answer the interactive prompt.
--confirm <issuer-host>with --forceConfirms the --force cascade by naming the provider’s exact issuer host (shown by webhook status as issuer_host; case-insensitive). Required in non-interactive (CI / piped) environments where the type-to-confirm prompt cannot run; the backend enforces the same match server-side.
Terminal window
# Enable (Clerk: paste the dashboard secret from a file)
alter identity-providers webhook enable --provider <id> --secret @/run/secrets/whsec
# Check status, rotate, disable
alter identity-providers webhook status --provider <id>
# Rotate (Clerk/Okta/WorkOS require the new secret; Auth0 omits --secret to generate one)
alter identity-providers webhook rotate --provider <id> --secret @/run/secrets/whsec --yes
alter identity-providers webhook disable --provider <id>
# Disable while group-bound grants exist: revoke them and disable
# (type-to-confirm: --confirm must name the provider's issuer host)
alter identity-providers webhook disable --provider <id> --force --confirm acme.okta.com

Preview claim mappings, then create with an explicit user-ID claim

Terminal window
alter identity-providers discover --issuer-url https://acme.okta.com
alter identity-providers create \
--issuer-url https://acme.okta.com \
--audience api://default \
--user-id-claim sub

Create an Auth0 provider for user sign-in

Terminal window
# Auth0 group grants are not currently supported (its Groups feature is
# Early Access), so no group claim is needed — Auth0 handles user sign-in
# and user-principal grants. Use Okta/WorkOS/Clerk for group grants.
alter identity-providers create \
--issuer-url https://acme.us.auth0.com \
--audience https://api.example.com \
--user-id-claim sub

Create a WorkOS provider with stable-ID group keying (enables group grants)

Terminal window
# WorkOS shows the AuthKit domain without a scheme — paste it bare
# (acme-corp.authkit.app) and the CLI prepends https:// for you.
alter identity-providers create \
--issuer-url acme-corp.authkit.app \
--audience https://api.example.com \
--group-claim org_id \
--group-claim-is-id

Create with wallet sign-in, secret read from a file (CI-safe)

Here --wallet-client-id supplies the effective audience, so --audience can be omitted.

Terminal window
alter identity-providers create \
--issuer-url https://acme.okta.com \
--wallet-client-id <oidc-client-id> \
--wallet-client-secret @/run/secrets/idp-client-secret

Report an issue with this page

Necessary

Required for sign-in, security, authorization, and remembering your choices.

Always active

Analytics

Helps us understand which product and documentation features are useful.

Performance diagnostics

Uses performance tracing and privacy-masked session replay to diagnose problems.

You can change these choices at any time from Cookie settings.