# Authentication and token refresh (/docs/rest/authentication)



`@kysoql/rest` only needs a Salesforce instance URL and bearer token. [`@kysoql/auth`](/docs/auth) is the companion package for obtaining and renewing those tokens.

Keeping authentication separate means the REST executor works the same way whether your application uses JWT bearer, refresh tokens, client credentials, an interactive login flow, or a session supplied by another system.

<SalesforceReference title="Authorization Through External Client Apps or Connected Apps and OAuth 2.0" href="https://developer.salesforce.com/docs/platform/api-rest/guide/intro-oauth-and-connected-apps.html" />

## Use an existing access token [#use-an-existing-access-token]

```ts
import { createRestExecutor } from "@kysoql/rest";

export function executorForSession(instanceUrl: string, accessToken: string) {
  return createRestExecutor({ instanceUrl, accessToken, apiVersion: "65.0" });
}
```

Use the `instance_url` returned by Salesforce authentication rather than a generic login host. A static token is never refreshed automatically.

## Use a renewable token provider [#use-a-renewable-token-provider]

Flows that issue refresh tokens can plug directly into the REST executor through `storedRefreshToken()`:

```ts
import {
  createMemoryRefreshTokenStore,
  SalesforceAuth,
} from "@kysoql/auth";
import { createRestExecutor } from "@kysoql/rest";

export async function createRefreshingExecutor(refreshToken: string) {
  const auth = new SalesforceAuth({
    loginUrl: "https://example.my.salesforce.com",
    clientId: "oauth-client-id",
  });

  const sessionAuth = auth.storedRefreshToken({
    initialRefreshToken: refreshToken,
    refreshTokenStore: createMemoryRefreshTokenStore(),
  });

  const session = await sessionAuth.getSession();

  return createRestExecutor({
    instanceUrl: session.instanceUrl,
    accessToken: sessionAuth.accessTokenProvider,
  });
}
```

The REST client caches the provider's current token. If Salesforce returns `401 INVALID_SESSION_ID`, it asks the provider for a refreshed token and replays that request once.

Concurrent requests on the same REST client share in-progress token acquisition and refresh work. If several application processes share a rotating refresh token in Redis, coordinate rotation across those processes with your normal distributed locking strategy.

## Compatibility helpers [#compatibility-helpers]

`@kysoql/rest` still exports `authenticateClientCredentials()` and `refreshAccessToken()` for existing users. New authentication code should generally use `SalesforceAuth`, which keeps the full set of supported flows and token-storage behaviour in one package.

You do not need either package's authentication helpers if your application already has a valid Salesforce bearer token.

## Keep credentials at the application boundary [#keep-credentials-at-the-application-boundary]

Generated Salesforce types do not grant object, field, or record access. Salesforce applies the permissions of the identity behind the token.

Keep client secrets, private keys, refresh tokens, and production access tokens out of source code and logs. See [security and production use](/docs/core/reference/security) and [refresh-token storage](/docs/auth/storage).
