Why Salesforce’s JWT connected app auth works for APIs but not for real UI logins in Playwright tests
When I first started exploring ways to automate Salesforce login in Playwright, the OAuth 2.0 JWT Bearer flow seemed like the perfect solution. It was secure, didn’t require storing usernames or passwords, and was widely used for backend authentication. On paper, it felt like the right direction.
But once I tried to apply it to browser‑based UI automation, the reality was different.
The idea was simple: use a Salesforce Connected App to generate an access token without needing a human login. The steps looked straightforward:
The JWT flow itself worked perfectly — Salesforce issued a valid access token with no issues.
The problem started when I tried to use that token to skip the UI login experience.
This was the key discovery:
Here’s what that means:
When I opened Salesforce in Playwright, MFA, SSO, and standard login flows still kicked in. There was no supported way to inject the JWT token into a browser session and have Salesforce consider it authenticated.
For this POC, the requirement was clear:
Automate the same UI login flow that a real user experiences — or skip it using a stored session.
JWT simply didn’t align with that need.
Practical Challenges with Key Management
Even aside from the UI limitation, JWT introduced additional operational complexity:
So even though JWT works well for API authentication, it added overhead without solving the UI automation problem.
Although it wasn’t the right fit for Playwright UI login, the JWT flow still has valuable use cases:
The main takeaway from this POC was simple:
Salesforce UI authentication and API authentication are two completely different worlds.
JWT works beautifully in the API world — but it cannot replace the browser login path required for Salesforce UI automation.
Once this became clear, the focus shifted toward techniques like storage state, which are actually compatible with UI automation.