Set up authentication with Okta

Configure Okta to authenticate against the Moveworks Conversations API using a JWT OAuth credential.
View as Markdown

The Conversations API is in Controlled Availability. Endpoints, behaviors, and configuration surfaces may change during CA. Contact your Moveworks account team to participate.

This guide walks through configuring Okta to authenticate against the Moveworks Conversations API.

Which Okta authorization server to use

The one decision that shapes your configuration is which authorization server issues the token.

Authorization serveraud behaviorWhat to do with the Audience field
Custom Authorization Server (recommended)You control the audience. You can set it to any value.Leave the Audience field blank. Moveworks generates a unique audience, which you then set as the audience on your Okta custom authorization server.
Org Authorization ServerFixed to your Okta org URL. Cannot be customized.Populate the Audience field with your Okta org URL (the fixed aud value your tokens carry).

Okta’s sub claim typically carries a usable identifier such as the user’s username or email, so the default sub claim works for identity resolution.

Prerequisites

Confirm the following with your Moveworks account team:

  • Your Moveworks tenant is provisioned for the Conversations API and your account team has provided the Bot Name (used in the Assistant-Name header on every API call).
  • You have access to the Moveworks Admin Portal (https://{org}.moveworks.com).
  • You have admin access to your Okta org, including the authorization server you intend to use.
  • The identifier your Okta sub claim will carry (commonly the user’s email) is already resolvable against your Moveworks user roster.

Step 1: Create the JWT OAuth credential in Moveworks

In the Moveworks Admin Portal, go to https://{org}.moveworks.com/http-connectors/connector_studio/homeCredentials → create a new credential, and set the fields as follows.

FieldValue for OktaNotes
Credential NameA descriptive label, e.g. Okta-CAPIFree text.
Credential TypeJWT OAuthReveals the fields below.
Public Key valueYour authorization server’s metadata URL, e.g. https://{yourOktaDomain}/oauth2/{authServerId}/.well-known/openid-configurationThis field accepts a WKE (well-known endpoint) URL in place of a PEM string. In Okta this is the Metadata URI under Security → API → Authorization Server → Settings. Moveworks auto-discovers the issuer and fetches the JWKS signing keys from it. For the Org Authorization Server, the URL omits the /oauth2/{authServerId} segment.
AudienceCustom Auth Server: leave blank. Org Auth Server: your Okta org URL.With a Custom Authorization Server, leave blank so Moveworks mints a unique audience for you to configure in Okta. With the Org Authorization Server, aud is fixed to the Okta org URL, so enter that exact value.
IssuerYour authorization server’s issuer, e.g. https://{yourOktaDomain}/oauth2/{authServerId}The iss claim your tokens carry. Together with Audience, it uniquely identifies this credential. Org Authorization Server issuer is https://{yourOktaDomain}.
Identifier TypeIdPTells Moveworks to resolve the identifier claim through an integration rather than as a raw email or record ID.
Integration IDconversations_rest_apiRequired when Identifier Type is IdP. Moveworks matches the sub claim against the user’s Conversations API channel entry on their profile.
Identifier Claimsub (default)Leave as the default sub, since Okta’s sub is a usable identifier. Set it to email only if your identifier lives in a different claim.

Save the credential. If you left Audience blank, note the unique audience value Moveworks displays; you will configure it in Okta next.

Step 2: Configure Okta

1

Create the OAuth application

In the Okta Admin Console, create a new OIDC application. For browser-based clients use a Single-Page Application with the Authorization Code flow and PKCE enabled. For backend clients use a Web Application as appropriate.

2

Assign users or groups

Assign the users or groups that should have access to the application.

3

Add trusted origins (browser clients only)

Under Security → API → Trusted Origins, add your application’s domain with CORS and Redirect enabled.

4

Configure the authorization server

Use (or create) a Custom Authorization Server under Security → API → Authorization Servers. If you left the Audience field blank in Moveworks, set this authorization server’s audience to the unique value Moveworks generated. On the Org Authorization Server the audience is fixed to the Okta org URL and cannot be changed, which is why you register that value in Moveworks instead.

5

Confirm scopes and claims

Ensure openid is available at minimum, so the user’s identity is present in the token. Confirm the sub claim carries the identifier that resolves against the Moveworks user roster.

6

Grant access via policy

On the authorization server’s Access Policies tab, add a policy that grants the application access to the authorization server. Without this attachment, tokens for the application will be denied by the access policy at issuance time.

Step 3: Validate

The examples below use https://api.moveworks.ai, which is only correct for orgs on the US Production data center. Replace it with the base URL for your data center from the Base URLs table (for example, https://api.am-eu-central.moveworks.ai for EU). Requests to the wrong host return 404 or invalid_audience.

3.1 Inspect a token

Obtain an access token from Okta for a test user (via the Okta SDK or the /v1/token endpoint with PKCE) and decode it (for example, at jwt.io). Confirm:

  • iss matches the Issuer you registered.
  • aud matches what you registered (the Moveworks-generated audience for a Custom Auth Server, or the Okta org URL for the Org Auth Server).
  • sub is present and matches the identifier your Moveworks user roster expects.

3.2 Exchange for a Moveworks token

$curl -X POST "https://api.moveworks.ai/oauth/v1/token" \
> -H "Content-Type: application/x-www-form-urlencoded" \
> --data-urlencode "grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer" \
> --data-urlencode "assertion=<OKTA_ACCESS_TOKEN>"

A successful response returns a Moveworks access token (valid ~1 hour).

3.3 Test the API

$curl -X POST "https://api.moveworks.ai/assistant/v1/conversations" \
> -H "Content-Type: application/json" \
> -H "Assistant-Name: <YOUR_BOT_NAME>" \
> -H "Authorization: Bearer <MW_ACCESS_TOKEN>" \
> -d '{"title": "Test conversation"}'

A 201 with a conversation_id confirms the integration works end to end.

Summary

Credential fieldOkta value
Public Key valueWKE URL: https://{yourOktaDomain}/oauth2/{authServerId}/.well-known/openid-configuration
AudienceCustom Auth Server: blank (Moveworks mints it). Org Auth Server: Okta org URL.
Issuerhttps://{yourOktaDomain}/oauth2/{authServerId}
Identifier TypeIdP
Integration IDconversations_rest_api
Identifier Claimsub (default)
Okta sideSet the custom auth server audience to the Moveworks-generated value (if used). No custom claims needed.

For interaction patterns (polling and streaming) and the full API contract, see the Conversations API reference.