Kysoql
Authentication flows

First-party username-password

Use Salesforce OAuth 2.0 for First-Party Applications username-password authorization challenges.

This flow lets a private first-party Experience Cloud application collect a user's username/password itself, then send a headless authorization challenge to Salesforce. It is distinct from Salesforce's retiring legacy OAuth username-password grant.

Request an authorization code

import { SalesforceAuth } from "@kysoql/auth";

export function firstPartyLogin(
  username: string,
  password: string,
  clientAssertion: string,
  codeChallenge: string,
) {
  const auth = new SalesforceAuth({
    loginUrl: "https://customers.example.my.site.com/customers",
    clientId: "external-client-app-id",
  });

  return auth.firstPartyAuthorizationChallenge({
    parameters: {
      username,
      password,
      client_id: "external-client-app-id",
      client_assertion: clientAssertion,
      code_challenge: codeChallenge,
      scope: "api refresh_token",
    },
  });
}

Salesforce can return a resumable auth_session when the request needs corrected or additional data. Kysoql returns that as kind: "challenge". Resubmit only the fields Salesforce requires for the current continuation step.

Use uvidHintToken when the named-user flow continues from a guest session. Headless user discovery can be implemented with Salesforce's documented login_hint and customdata parameters.

After kind: "authorized", exchange authorizationCode through auth.exchangeAuthorizationCode().

On this page