Skip to main content
SFDC Developers
Integration

Unattended Sandbox User Token Generation for CI/CD

Vinay Vernekar · · 5 min read

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 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.

Share this article

Vinay Vernekar

Vinay Vernekar

Salesforce Developer & Founder

Vinay is a seasoned Salesforce developer with over a decade of experience building enterprise solutions on the Salesforce platform. He founded SFDCDevelopers.com to share practical tutorials, best practices, and career guidance with the global Salesforce community.

Comments

Loading comments...

Leave a Comment

Trending Now
Check back soon for trending Salesforce developer content