Salesforce JWT Authentication Without the Confusion

April 13, 2026

Salesforce JWT Authentication Without the Confusion

If JWT authentication felt harder than it should, you are not alone.

The first time most people set it up in Salesforce, it feels like there are too many moving parts: a connected app, a certificate, a client id, an integration user, and a signed token. It sounds heavy. In practice, the idea is simple.

You are telling Salesforce:

  • this app is trusted
  • this is the user it wants to act as
  • here is proof that the request really came from the app

That is the whole story.

What JWT auth is good for

JWT Bearer Flow is a good fit when you have a backend service talking to Salesforce without a human logging in each time.

Common examples:

  • a Node.js service pushing records into Salesforce
  • an integration job running on a schedule
  • middleware calling Salesforce APIs in the background
  • internal apps that need server-to-server access

It is usually a better choice than storing a username, password, and security token in some config file.

The basic flow

Here is the short version:

  1. Create a Connected App in Salesforce.
  2. Upload a certificate to that Connected App.
  3. Pick the Salesforce user the app should act as.
  4. Your external app creates a signed JWT.
  5. That JWT is sent to Salesforce's token endpoint.
  6. Salesforce returns an access token.

After that, you use the access token like any other OAuth token.

The pieces you need

1. A Connected App

This is where Salesforce knows your external system exists.

You will need:

  • Consumer Key
  • OAuth enabled
  • JWT Bearer Flow enabled
  • the right scopes

For most API integrations, these scopes are enough:

  • Access and manage your data (api)
  • Perform requests at any time (refresh_token, offline_access)

Even though refresh token is not the focus of JWT flow, many teams still include the standard API-related scopes in the connected app.

2. A certificate

This is the part that signs the JWT.

Salesforce stores the public certificate. Your app keeps the private key.

That private key should stay private. Do not commit it to the repo. Do not email it around. Do not leave it in random local folders.

3. An integration user

This is the Salesforce user the JWT flow will impersonate.

Use a dedicated integration user whenever possible. It makes access easier to control and auditing much cleaner.

4. The JWT claims

The token you send to Salesforce usually includes:

  • iss: your Connected App consumer key
  • sub: the Salesforce username
  • aud: the login URL
  • exp: expiry time

The aud value is easy to get wrong.

Use:

  • https://login.salesforce.com for production
  • https://test.salesforce.com for sandbox

A small example

Here is a simple Node.js example using jsonwebtoken.

import fs from "node:fs"; import jwt from "jsonwebtoken"; const privateKey = fs.readFileSync("./server.key", "utf8"); const token = jwt.sign( { iss: process.env.SF_CONSUMER_KEY, sub: process.env.SF_USERNAME, aud: "https://login.salesforce.com", }, privateKey, { algorithm: "RS256", expiresIn: "3m", }, ); console.log(token);

Then send it to Salesforce:

curl -X POST https://login.salesforce.com/services/oauth2/token \ -d "grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer" \ -d "assertion=YOUR_SIGNED_JWT"

If everything is configured correctly, Salesforce returns an access token and an instance URL.

The part people usually miss

Most JWT issues are not actually JWT issues. They are setup issues.

Usually it is one of these:

  • wrong username in sub
  • wrong login domain in aud
  • expired token
  • certificate uploaded in the wrong connected app
  • private key does not match the uploaded certificate
  • connected app is not approved for the user
  • user does not have permission to use the connected app

So when it fails, do not start by rewriting code. Start by checking the setup line by line.

A practical checklist

When I troubleshoot JWT auth in Salesforce, I usually go through this order:

  1. Confirm the Connected App consumer key.
  2. Confirm the username in sub is exact.
  3. Confirm aud matches prod or sandbox.
  4. Confirm the certificate in Salesforce matches the private key being used.
  5. Confirm the user is allowed to use the connected app.
  6. Confirm the user has API access and the right permissions.

This saves a lot of time.

Why teams like this approach

JWT auth is popular for Salesforce integrations because it is clean.

  • no password stored in code
  • no interactive login step
  • good fit for automation
  • easier to manage for backend services

It is not magic, but it is reliable once the setup is right.

Final thought

JWT authentication in Salesforce looks intimidating at first mostly because the setup lives in multiple places. But once you understand that Salesforce is simply verifying a signed request from a trusted app, it becomes much easier to reason about.

Set up the connected app carefully, use a dedicated integration user, keep the private key safe, and check the aud and sub values before anything else. That alone solves most problems.

GitHub
LinkedIn
Salesforce Trailblazer