Skip to main content
New tool CRON Expression Builder — preview next run times before you schedule Apex. Open the builder →
Diagram showing the process for unattended Salesforce sandbox user token generation in a CI/CD flow
Integration

Unattended Sandbox User Token Generation for CI/CD

Automating access token retrieval for numerous sandbox test users is a common CI/CD hurdle when testing as specific identities. This analysis explores viable unattended OAuth flows or API mechanisms.

The short answer

This article outlines methods for programmatically obtaining OAuth access tokens for non-admin test users in Salesforce sandboxes without manual intervention during CI/CD pipelines. It evaluates why standard authentication flows fail and examines solutions like OAuth 2.0 token exchange and Tooling API metadata queries.

Key takeaways Standard unattended JWT bearer authentication fails across newly provisioned sandboxes because the Connected App ConsumerKey changes with each sandbox instance. The OAuth 2.0 Token Exchange Flow can leverage an existing administrator session to exchange an admin token for a test user token if delegation is configured. Querying the ConnectedApplication object via the Tooling API retrieves the sandbox-specific ConsumerKey to enable standard JWT bearer flows for each test user. Interactive browser logins, the sandboxAuth Tooling API endpoint, and the deprecated username-password flow cannot be used for unattended test user token generation.

Unattended CI/CD Sandbox User Authentication: Access Token Generation

Developing a robust, fully automated CI/CD pipeline for Salesforce sandboxes often necessitates authenticating API calls as specific, non-admin test users within those sandboxes. The challenge arises in programmatically obtaining an OAuth access token for these arbitrary users without manual intervention (like browser redirects).

This document outlines the existing state, ruled-out paths, and potential solutions for obtaining access tokens for pre-provisioned sandbox test users unattended.

Current CI/CD Automation Status

The existing automation successfully handles the initial setup phases:

  • Sandbox provisioning is completed.
  • The Sandbox Administrator is authenticated using the Tooling API (/services/data/vXX.0/tooling/executeAnonymous) or equivalent endpoint via the JWT Bearer flow, yielding an administrative access token.
  • The required set of approximately 110 test users are created within the sandbox.

The Roadblock: Arbitrary User Token Retrieval

The core requirement is to retrieve a valid OAuth access token for each of the 110 created test users, solely using the already obtained admin token or known static credentials (like the private key file).

Ruled Out Authentication Flows

Several standard methods are unsuitable for this specific unattended sandbox requirement:

  • sf org login web: Requires interactive browser flow, precluding unattended execution.
  • sf org login jwt (Standard): This flow relies on the Sandbox's unique consumerKey. Since this key changes with every new sandbox instance, it cannot be reliably stored or retrieved programmatically for all test users across dynamic environments.
  • sandboxAuth Tooling API Endpoint: This endpoint is scoped to authenticate the sandbox creator (the admin user), not arbitrary test users provisioned later.
  • Username/Password OAuth Flow: This flow is deprecated and still requires access to the apex-callout-solutions/" class="auto-link">Connected App's consumerKey and consumerSecret, which suffers from the same variability as the JWT flow if tied to the sandbox instance.

Known Technical Assets

We possess the following reliable assets:

  1. A valid access token for the Sandbox Administrator.
  2. The usernames for all target test users.
  3. A static private key file usable across organizational environments.
  4. The knowledge that the Connected App configuration (Client ID/Consumer Key) is identical to Production, although the instance-specific Client ID must be resolved.

Investigating Programmatic Token Generation Paths

Since standard direct flows are blocked by the dynamic consumerKey requirement, the solution likely involves delegation or leveraging existing session context.

1. Admin-Delegated Token Generation via REST

This path explores if the existing administrative session can delegate authority to generate tokens for other users. This typically points toward the OAuth 2.0 Token Exchange Flow.

OAuth 2.0 Token Exchange (urn:ietf:params:oauth:grant-type:token-exchange)

This grant type allows a client that possesses a security token (the admin access token) to exchange it for a new token on behalf of a different subject (the test user). This requires that the Connected App permits token exchange and that the security token presented (the admin token) authorizes the exchange for the desired subject.

  • Potential Implementation Requirement: If the Connected App is configured correctly for delegation or audience restriction, exchanging the admin token (subject_token) for a test user token (resource_owner_id) might be feasible.

2. Apex Execution as Target User

If REST APIs do not expose a direct delegation mechanism, leveraging Apex running as the target user may provide the necessary context.

  1. Use the existing Admin token to execute an Apex anonymous block via the Tooling API (/tooling/executeAnonymous).
  2. The Apex code runs under the Admin context.
  3. Use System.runAs(TestUserRecord) to impersonate the test user context within the Apex execution.
  4. Inside the runAs block, attempt to access or generate a session ID/token specific to that user context. Note: Generating a full OAuth token from within Apex for external use is complex, often requiring custom Apex endpoints designed to mimic OAuth provider behavior, which may still need a Consumer Key.

3. Discovering Sandbox-Specific Connected App Details

If the consumerKey for the Sandbox's version of the Connected App could be retrieved programmatically, the standard JWT flow could be used for each user.

  • Tooling API Search: Investigate the ConnectedApplication object (or related metadata via the Tooling API) to see if the ConsumerKey for the sandbox instance can be queried after creation, perhaps linked to the sandbox ID or Admin ID.
// Pseudocode for potential Tooling API query
SELECT Id, ConsumerKey FROM ConnectedApplication WHERE Name = 'YourAppName'

If this key is retrievable, you can proceed with the standard JWT flow for each test user, using their respective username, the retrieved sandbox ConsumerKey, and the static Private Key.

Key Takeaways

  1. The fundamental barrier is the instance-specific ConsumerKey preventing standard unattended JWT flows for new users.
  2. The OAuth 2.0 Token Exchange Flow using the established Admin token is the most promising standard OAuth path, provided the Connected App is configured to allow delegation across user identities.
  3. If OAuth exchange fails, querying the Tooling API for the sandbox's ConnectedApplication record to retrieve the instance-specific ConsumerKey allows reverting to a standard, user-specific JWT grant for each test user.

Frequently asked questions

How do you generate access tokens for sandbox test users unattended in CI/CD?

You can exchange an existing administrator session token for a test user token using the OAuth 2.0 Token Exchange Flow, or query the Tooling API to discover the sandbox ConsumerKey and execute user-specific JWT bearer flows.

Why does standard JWT flow fail for arbitrary sandbox users in CI/CD?

The standard JWT bearer flow relies on a static ConsumerKey, but Salesforce assigns an instance-specific ConsumerKey that changes with every new sandbox creation.

Can you query the sandbox Connected App consumer key via the Tooling API?

Yes, an administrative access token can query the ConnectedApplication object via the Tooling API to retrieve the sandbox-specific ConsumerKey and proceed with standard JWT authentication for test users.

Newsletter

One email every Tuesday

New guides, tool updates, and the release-note changes that break things.

No spam. Unsubscribe in one click.

Comments

Loading comments...

Leave a Comment