Skip to content

The Golden Pass

Module 2 of 5 in the chapter Acting as Someone: The Impersonation Flows, chapter 11 of Securing Salesforce: Identity and Access. Each module stands on its own.

The question this module answers: How does the JWT bearer flow let a trusted system act as someone, and what stops it acting as anyone?

Back to the Burger House, with nobody home. For the festival to hand over Priya’s drink without Priya, the Burger House has to become something special: an approved vendor. The festival has to trust it completely.

How did we build that kind of trust in single sign-on? With a certificate. The identity provider kept its private key, Salesforce held its certificate, and a signed assertion was enough (chapters 3 and 6). The JWT bearer flow does exactly the same thing. The Burger House keeps a private key. Its certificate goes on the app in Salesforce. And from then on, a message signed with that key is believed.

The message is a JWT, a JSON Web Token, and people say “jot”. Think of it as a sealed envelope. Inside, it says: let me in as Priya. The seal is the Burger House’s signature. Salesforce opens it, checks the seal against the certificate, and lets them in as Priya. No person involved. It’s a golden pass.

Same cells as module 1. Here’s what JWT bearer puts in them.

The golden pass: JWT bearer The same four lanes and cells as Nobody home. Before anything, the Burger House uploads its certificate to the app in Salesforce and keeps the private key; the app holds the certificate and says who's pre-authorized: only those users. Priya isn't there. Step 1: her standing order is due at night. Nobody signs in, so the login page isn't used. Step 2: the golden pass: the Burger House sends a JWT naming Priya, signed with its private key, to the token endpoint, which checks the signature, the claims, and that Priya is pre-authorized; the check passes and it returns an access token, with no refresh token. Step 3: the Burger House fetches her drink from the API as Priya. Footnote: whoever holds the private key can act as anyone the app allows; keep the list short. {"author": "Steve Simpson", "blueprint": "1.0.0", "builder": "standard 1.58.0", "built": "2026-11-05", "id": "DGM-IAM-AS-02", "rights": "\u00a9 2026 Twinshark LLC. All rights reserved.", "template": "cells 0.5.0", "theme": "stevetecharc 1.4.0"} PRIYA THE BURGER HOUSE SALESFORCE: THE ENTRANCE SALESFORCE: TOKEN ENDPOINT AND API Before: the certificate the Burger House keeps the private key The app in Salesforce the certificate, and who's pre-authorized Priya: not there asleep, away, or never signs in 1. Her standing order is due at night: her drink from the festival Nobody to sign in the login page isn't used 2. The golden pass a JWT naming Priya, signed with its key The token endpoint checks the signature, the claims, and that Priya is pre-authorized 3. Fetches her drink as Priya: her access, her name on changes The API what Priya may see uploads the certificate pre-authorized users only the JWT access token, no refresh the access token her data Whoever holds the private key can act as anyone the app allows. Keep the list short. HOW TO READ IT Salesforce the check passes © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge
  1. Before anything: the Burger House makes a key pair and uploads the certificate to its external client app in Salesforce, with Enable JWT Bearer Flow turned on (S2). Salesforce wants the JWT “signed using RSA SHA256”, and the certificate can’t be bigger than 4 KB (S1).
  2. When the order is due, the Burger House builds a JWT naming Priya and signs it with its private key.
  3. It posts the JWT to the token endpoint. Salesforce checks the signature against the certificate, checks the claims, checks that Priya is allowed, and issues an access token (S1).
  4. It fetches her drink, as Priya.

A JWT is three parts, each base64url-encoded, joined with dots: a header, the claims, and the signature. The header just says how it’s signed: {"alg":"RS256"}. The claims say who and for whom (S1):

ClaimWhat it holds
issThe issuer: “the OAuth client_id of the external client app” with the certificate
subThe subject: the username of the person to act as, Priya
audThe audience: https://login.salesforce.com, or https://test.salesforce.com for a sandbox, or the site’s URL for an Experience Cloud site
expWhen it expires, in seconds since 1970; Salesforce allows “a 3-minute buffer for clock skew”

Then the signature: the header and claims, signed with the private key. Change one character inside, and the signature no longer matches.

One more claim is worth knowing. A JWT ID, jti, is optional, but “if you pass a JTI claim… Salesforce validates that the JTI claim hasn’t been sent before. This validation prevents JWT replay attacks” (S1). Send one, and a copied JWT can’t be used twice.

The request is one POST to the token endpoint (S1):

POST /services/oauth2/token
grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer
&assertion=eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOi...

That’s chapter 8’s base pattern again: present something, get a wristband. Only now what’s presented is the signed JWT, not a client secret.

Notice two things that aren’t there. There’s no scope: “You can’t specify scopes in a JWT bearer token flow”; the scopes come from the app (S1). And the answer has an access token, the instance_url and Priya’s id, but “This flow never issues a refresh token” (S1). When the token runs out, sign a new JWT.

Here’s what makes it powerful, and dangerous. Whoever holds the private key can sign a JWT naming anyone. So what stops the Burger House from becoming anybody at all?

Prior approval. Salesforce only issues the token for users the app is approved for (S1). On an external client app, set Permitted Users to Admin approved users are pre-authorized, and then choose the profiles and permission sets that are pre-authorized (S2).

Now think about what that means. Put a profile on that list, and the Burger House can impersonate anyone in that profile. Every one of them. Put System Administrator on it, and it can be any admin.

So keep it narrow:

  • Use a permission set, not a profile. A permission set that holds only the users the system really needs to act for.
  • Never an admin. No one with System Administrator or Modify All Data on the list.
  • Guard the private key like the most important secret you have, because it is. Keep it in a vault, never in code.
  • Short expiry and a JWT ID, so a stolen JWT is worth little.

Only between systems you trust implicitly. In my experience, I’d only use JWT bearer when you really have control of both systems: say, two of a company’s own trusted servers, very secure, run by the same team. I’ve set it up at multiple clients, and it’s very useful when that’s true.

Here’s a typical one. Another company system pushes changes into Salesforce, and each change has to be recorded as the person who made it there, not as the integration user. Make sure the user exists in both systems, and the JWT names the right Salesforce user every time. Then the audit trail traces each change to a person.

You’ve probably used it already without noticing. The Salesforce CLI’s org login jwt command logs in with exactly this flow, using an external client app with the certificate you upload (S2). That’s how a build pipeline logs in to an org with nobody at the keyboard. This chapter’s practice does it by hand, so you can see every piece.

And if the other system won’t give Salesforce, or you, that much trust? That’s module 3.

Test knowledge. In my experience, know that JWT bearer is for a trusted server acting as a pre-authorized user, signed with the private key whose certificate is on the app, with no person and no refresh token.

In 2023 I made a video of the JWT bearer flow, with the Burger House as an approved vendor and the sealed envelope. The note under the video says what’s still right and what’s changed since.

STA 3.16 · Salesforce OAuth JWT Bearer Flow Explained · 7:49 · published 2023-10-11 · plays from YouTube when you click it · Watch on YouTube · More videos: Salesforce Identity & Access Videos

Module 3: borrowed trust. The SAML bearer assertion and the SAML assertion flow.

  • Whether one system is trusted enough to act as people in another.
  • Exactly who it may act as: a permission set with only those users, never a profile, never an admin.
  • Where the private key lives, and who can reach it.
  • The JWT’s lifetime, and whether to send a JWT ID.