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 uniqueconsumerKey. Since this key changes with every new sandbox instance, it cannot be reliably stored or retrieved programmatically for all test users across dynamic environments.sandboxAuthTooling 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
consumerKeyandconsumerSecret, 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:
- A valid access token for the Sandbox Administrator.
- The usernames for all target test users.
- A static private key file usable across organizational environments.
- 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.
- Use the existing Admin token to execute an Apex anonymous block via the Tooling API (
/tooling/executeAnonymous). - The Apex code runs under the Admin context.
- Use
System.runAs(TestUserRecord)to impersonate the test user context within the Apex execution. - Inside the
runAsblock, 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
ConnectedApplicationobject (or related metadata via the Tooling API) to see if theConsumerKeyfor 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
- The fundamental barrier is the instance-specific
ConsumerKeypreventing standard unattended JWT flows for new users. - 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.
- If OAuth exchange fails, querying the Tooling API for the sandbox’s
ConnectedApplicationrecord to retrieve the instance-specificConsumerKeyallows reverting to a standard, user-specific JWT grant for each test user.
Leave a Comment