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 scopes — alter 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.
discover
Section titled “discover”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.
| Flag | Required | Description |
|---|---|---|
--issuer-url <url> | yes | 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. |
alter identity-providers discover --issuer-url https://acme.okta.comcreate
Section titled “create”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.
| Flag | Required | Description |
|---|---|---|
--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> | conditional | Expected 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> | no | Override the user-identity claim (auto-detected; defaults to sub; maximum 128 characters). |
--group-claim <claim> | no | Override the group-membership claim (auto-detected; maximum 128 characters). |
--group-claim-is-id | no | Assert 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> | no | Override the role claim (auto-detected; maximum 128 characters). |
--wallet-client-id <id> | no | OIDC client ID for interactive wallet sign-in (maximum 255 characters). Must be paired with --wallet-client-secret. |
--wallet-client-secret <value> | no | OIDC 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> | no | JSON 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.
alter identity-providers create \ --issuer-url https://acme.okta.com \ --audience https://api.example.comwebhook
Section titled “webhook”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.
| Flag | Required | Description |
|---|---|---|
--app <app-id-or-name> | yes* | The application (*or link a workspace / set ALTER_APP_ID). |
--provider <provider-id> | yes | The identity provider’s ID. |
--secret <value> | no | Signing 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. |
--yes | no | Skip the confirmation prompt on disable / rotate (for CI). Required when rotating with --secret -. Rotating invalidates the previous secret immediately. |
--force | no | disable 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 --force | Confirms 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. |
# Enable (Clerk: paste the dashboard secret from a file)alter identity-providers webhook enable --provider <id> --secret @/run/secrets/whsec
# Check status, rotate, disablealter 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 --yesalter 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.comRecipes
Section titled “Recipes”Preview claim mappings, then create with an explicit user-ID claim
alter identity-providers discover --issuer-url https://acme.okta.comalter identity-providers create \ --issuer-url https://acme.okta.com \ --audience api://default \ --user-id-claim subCreate an Auth0 provider for user sign-in
# 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 subCreate a WorkOS provider with stable-ID group keying (enables group grants)
# 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-idCreate with wallet sign-in, secret read from a file (CI-safe)
Here --wallet-client-id supplies the effective audience, so --audience can be omitted.
alter identity-providers create \ --issuer-url https://acme.okta.com \ --wallet-client-id <oidc-client-id> \ --wallet-client-secret @/run/secrets/idp-client-secretRelated
Section titled “Related”alter providers— OAuth providers your users connect to- Authentication — minting a token with the right scopes