Close Menu

    Subscribe to Updates

    Get the latest creative news from FooBar about art, design and business.

    What's Hot

    OAuth 2.0, Named Credentials & Connected Apps: Building a Secure Salesforce Migration Architecture

    May 29, 2026

    15 Salesforce Career Tips Nobody Tells You Until It’s Too Late

    May 27, 2026

    Salesforce Data Migration: Org Readiness Assessment & What Most Teams Get Wrong

    May 25, 2026
    Facebook X (Twitter) Instagram
    Facebook Instagram LinkedIn WhatsApp Telegram
    Salesforce TrailSalesforce Trail
    • Home
    • Insights & Trends
    • Salesforce News
    • Specialized Career Content
      • Salesforce
      • Administrator
      • Salesforce AI
      • Developer
      • Consultant
      • Architect
      • Designer
    • About Us
    • Contact Us
    Salesforce TrailSalesforce Trail
    Home - Developer - OAuth 2.0, Named Credentials & Connected Apps: Building a Secure Salesforce Migration Architecture
    Developer

    OAuth 2.0, Named Credentials & Connected Apps: Building a Secure Salesforce Migration Architecture

    Kiran Sreeram PrathiBy Kiran Sreeram PrathiMay 29, 20268 Mins Read
    Facebook LinkedIn Telegram WhatsApp
    OAuth 2.0, Named Credentials & Connected Apps
    Share
    Facebook LinkedIn Email Telegram WhatsApp Copy Link Twitter

    Secure, auditable, and maintainable authentication is the foundation of every reliable Salesforce integration. For data migration, where millions of records may transit through a single integration user credential over hours or days, the authentication architecture is not an afterthought; it is a first-class engineering concern.

    In Part 1 of this series, we covered org readiness API limits, metadata inventory, and storage projections. This article covers the three authentication patterns that matter most for Salesforce data migration: OAuth 2.0 Client Credentials Flow, JWT Bearer Token Flow, and Named Credentials, and how to set up your Connected App correctly before any of them work the way you need.

    Table of Contents

    Connected App Configuration

    A Salesforce Connected App is the OAuth 2.0 client registration that authorises an external application to interact with your org. For a data migration integration, the Connected App should be purpose-built for the migration workload and retired or deactivated after completion.

    Connected App SettingRecommended ValueRationale
    OAuth Scopesapi, bulk_api, refresh_tokenMinimum scopes for Bulk API 2.0 and REST access
    IP RelaxationRelax IP restrictions (migration servers)Allows migration server IPs without whitelist churn
    Refresh Token PolicyExpire refresh token after 90 daysLimits exposure without forcing re-auth during migration
    Require Secret for Web ServerEnabledPrevents unauthorised client_credentials flows
    Enable Client Credentials FlowEnabled (for server-to-server)Removes user interaction from automated migration jobs
    Permitted UsersAdmin approved users are pre-authorisedLimits OAuth to the migration integration user only

    🔍 Also Read: Salesforce Data Migration: Org Readiness Assessment & What Most Teams Get Wrong

    OAuth 2.0 Flows for Server-to-Server Migration

    Client Credentials Flow (Recommended for Automation)

    The OAuth 2.0 Client Credentials Flow is the recommended authentication pattern for fully automated, server-to-server migration jobs. Unlike the Web Server Flow (which requires a browser redirect and user interaction) or the JWT Bearer Token Flow (which requires certificate management), the Client Credentials Flow is operationally simpler: the external application exchanges its client_id and client_secret for an access token directly, with no user session involved.

    				
    					OAuth 2.0 Client Credentials Flow: Salesforce Token Exchange
    
      +--------------------------+          +----------------------------------+
      |  External Migration App  |          |       Salesforce Platform        |
      +-----------+--------------+          +-------------+--------------------+
                  |                                       |
                  |  POST /services/oauth2/token          |
                  |  grant_type=client_credentials        |
                  |  client_id=<Connected App Key>        |
                  |  client_secret=<Connected App Secret> |
                  |-------------------------------------->|
                  |                                       |
                  |          200 OK                       |
                  |  {                                    |
                  |    access_token: 'XXXXXX',            |
                  |    instance_url: 'https://org.sf.com',|
                  |    token_type:   'Bearer',            |
                  |    scope:        'api bulk_api'       |
                  |  }                                    |
                  |<--------------------------------------|
                  |                                       |
                  |  Authorization: Bearer <access_token> |
                  |  (All subsequent API calls)           |
                  |-------------------------------------->|
    
    
    				
    			
    				
    					// Node.js: OAuth 2.0 Client Credentials Token Acquisition
    const axios = require('axios');
    const qs    = require('querystring');
    
    async function getAccessToken(config) {
      const response = await axios.post(
        `${config.sfLoginUrl}/services/oauth2/token`,
        qs.stringify({
          grant_type   : 'client_credentials',
          client_id    : config.clientId,
          client_secret: config.clientSecret,
        }),
        { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }
      );
      return {
        accessToken : response.data.access_token,
        instanceUrl : response.data.instance_url,
        expiresAt   : Date.now() + 3600 * 1000, // 1-hour TTL
      };
    }
    
    // Singleton token cache: avoids re-authentication on every API call
    let tokenCache = null;
    
    async function getValidToken(config) {
      if (!tokenCache || Date.now() >= tokenCache.expiresAt - 60000) {
        tokenCache = await getAccessToken(config);
        console.log(`[Auth] Token refreshed at ${new Date().toISOString()}`);
      }
      return tokenCache;
    }
    
    				
    			

    JWT Bearer Token Flow (Certificate-Based)

    For organisations with strict secret management policies that prohibit long-lived client secrets, the JWT Bearer Token Flow provides a certificate-based alternative. The external application signs a JWT assertion using an RSA private key, and Salesforce validates the assertion against the public certificate registered in the Connected App. This approach integrates naturally with enterprise secret management solutions such as HashiCorp Vault, AWS Secrets Manager, or Azure Key Vault.

    				
    					# Python: JWT Bearer Token Flow
    import jwt, time, requests
    from cryptography.hazmat.primitives import serialization
    
    def get_jwt_access_token(config: dict) -> dict:
        with open(config['private_key_path'], 'rb') as f:
            private_key = serialization.load_pem_private_key(f.read(), password=None)
        
        now = int(time.time())
        payload = {
            'iss': config['client_id'],           # Connected App consumer key
            'sub': config['integration_user'],    # Integration user's username
            'aud': 'https://login.salesforce.com',
            'exp': now + 300,                     # Token valid for 5 minutes only
        }
        assertion = jwt.encode(payload, private_key, algorithm='RS256')
        
        resp = requests.post(
            f"{config['sf_login_url']}/services/oauth2/token",
            data={
                'grant_type': 'urn:ietf:params:oauth:grant-type:jwt-bearer',
                'assertion' : assertion,
            },
            headers={'Content-Type': 'application/x-www-form-urlencoded'},
        )
        resp.raise_for_status()
        return resp.json()  # { access_token, instance_url, token_type }
    
    				
    			

    🔍 Also Read: How to Write a Salesforce Business Requirements Document That Developers Can Actually Use

    Named Credentials: Decoupling Authentication from Code

    Salesforce Named Credentials provide a platform-native mechanism for storing endpoint URLs and authentication credentials in a secure, version-controlled configuration object rather than hardcoding them in Apex code or embedding them in environment variables. For migrations that include Salesforce-to-Salesforce callouts (for example, a post-migration validation Apex class invoking an internal REST service), Named Credentials are the recommended pattern.

    Named Credentials eliminate the need to handle OAuth token management in code because the Salesforce platform automatically handles token acquisition, caching, and renewal transparently. An Apex callout that references a Named Credential will always use a valid, non-expired token without any developer-managed refresh logic.

    				
    					Named Credential Architecture: Apex Callout Flow
    
      +-------------------------------------------------------------------+
      |                    Salesforce Org                                 |
      |                                                                   |
      |  +------------------+   callout:MigrationAPI/endpoint            |
      |  |   Apex Class     |----------------------------------------->  |
      |  |  (Validator.cls) |                          ^                 |
      |  +------------------+    Named Credential       |                 |
      |                         +-------------------+   |                 |
      |                         | Label: MigrationAPI|  |                 |
      |                         | URL:  https://api  +--+                 |
      |                         | Auth: OAuth 2.0    | (token managed     |
      |                         | (Client Creds)     |  by platform)      |
      |                         +-------------------+                    |
      +-------------------------------------------------------------------+
                                        |
                                        v
                           +------------------------+
                           | External Migration API  |
                           | (REST: HTTPS / TLS 1.3) |
                           +------------------------+
    
    
    				
    			
    				
    					// Apex: Callout using Named Credential
    public class MigrationValidatorCallout {
        private static final String NAMED_CRED = 'callout:Migration_Orchestration_API';
        
        public static Map<String, Object> validateBatch(String batchId) {
            HttpRequest req = new HttpRequest();
            req.setEndpoint(NAMED_CRED + '/v1/batches/' + batchId + '/validate');
            req.setMethod('GET');
            req.setHeader('Content-Type', 'application/json');
            req.setTimeout(30000); // 30-second timeout
            
            Http http = new Http();
            HttpResponse res = http.send(req);
            // Platform automatically injects: Authorization: Bearer <token>
            
            if (res.getStatusCode() != 200) {
                throw new CalloutException('Validation API returned: ' + res.getStatusCode());
            }
            return (Map<String, Object>) JSON.deserializeUntyped(res.getBody());
        }
    }
    
    				
    			

    🔍 Also Read: How to Write a Salesforce Post Implementation Review That Actually Improves Your Next Project

    Which Flow Fits Which Scenario

    ScenarioRecommended Pattern
    Automated bulk load from external appClient Credentials Flow
    Regulated industry, no stored secrets allowedJWT Bearer Token Flow
    Post-migration Apex validation calloutsNamed Credentials
    Admin-triggered or interactive migration toolWeb Server Flow (user context required)

    Security Checklist Before You Run Anything

    A few things to confirm before the first migration job starts:

    • Create a dedicated integration user with only the permissions the migration needs — not a full System Administrator profile
    • Store client_secret and private keys in a secret manager, never in .env files or source code repositories
    • Enable Salesforce Event Monitoring before migration starts, so you capture API-level audit logs from day one
    • Confirm the Connected App’s Permitted Users setting is locked to the migration user
    • Document the Connected App’s expiry settings and add a post-cutover task to deactivate it
    • Run a test token acquisition and a single test API call against a sandbox before going anywhere near production

    That last point sounds obvious, but it’s easy to skip when the project timeline is tight. An authentication failure at T-zero of your cutover window is not where you want to diagnose a scope misconfiguration.

    What’s Next in This Series

    Getting your OAuth setup right is table stakes. The next article is where things get interesting.

    Part 3 will cover the Bulk API 2.0 job lifecycle, how to create jobs, stream CSV data at scale, poll for completion without hammering the API, and handle partial failures without losing records or corrupting your load state. If you’ve ever watched a migration job finish and had no idea whether it actually succeeded, that article is for you.

    Frequently Asked Questions (FAQ)

    What is the difference between Client Credentials Flow and JWT Bearer Token Flow in Salesforce?

    Client Credentials Flow authenticates using a client ID and client secret, a shared secret model. JWT Bearer Token Flow uses a signed JWT assertion backed by an RSA key pair, so no shared secret is involved. JWT is the better choice when your security policy prohibits stored secrets or requires certificate-based trust. For most automation scenarios, Client Credentials Flow is simpler to operate.

    Can Named Credentials be used from Python or Node.js migration scripts?

    No. Named Credentials are Apex-native and can only be referenced from Apex code running inside the Salesforce platform. External applications need to handle their own OAuth token management using Client Credentials or JWT Bearer Token flows.

    What OAuth scopes does a Salesforce migration Connected App need?

    For a Bulk API 2.0 migration, api, bulk_api, and refresh_token are sufficient. Avoid broader scopes like full unless you have a specific reason for them.

    What happens if the OAuth access token expires during a long migration job?

    If your token expires mid-job, the API calls return a 401 Unauthorized response. The solution is proactive token caching: check the token’s expiry timestamp before each API call and refresh it about 60 seconds before expiry. Bulk API jobs themselves are not interrupted by token expiry; the job runs server-side, but your polling and result-retrieval calls will fail without a valid token.

    Should I deactivate or delete the Connected App after migration?

    Deactivate it. Deletion removes the audit record along with the Connected App itself. Deactivation blocks any further token issuance while preserving the configuration and history for compliance purposes.

    Kiran Sreeram Prathi
    Kiran Sreeram Prathi
    Sr. Salesforce Developer – kiransreeram8@live.com

    I’m Kiran Sreeram Prathi, a Salesforce Developer dedicated to building scalable, intelligent, and user-focused CRM solutions. Over the past five years, I’ve delivered Salesforce implementations across healthcare, finance, and service industries—focusing on both technical precision and user experience. My expertise spans Lightning Web Components (LWC), Apex, OmniStudio, and Experience Cloud, along with CI/CD automation using GitHub Actions and integrations with platforms such as DocuSign, Conga, and Zpaper. I take pride in transforming complex workflows into seamless digital journeys and implementing clean DevOps strategies that reduce downtime and accelerate delivery. Recognized by organizations like Novartis, WILCO, and Deloitte, I enjoy solving problems that make Salesforce work smarter and scale better. I’m always open to connecting with professionals who are passionate about process transformation, architecture design, and continuous innovation in the Salesforce ecosystem.

      This author does not have any more posts.
    Named Credentials OAuth 2.0 salesforce Salesforce Connected App salesforce data migration Salesforce Migration Architecture
    Share. Facebook LinkedIn Email Telegram WhatsApp Copy Link

    Related Posts

    15 Salesforce Career Tips Nobody Tells You Until It’s Too Late

    May 27, 2026

    Salesforce Data Migration: Org Readiness Assessment & What Most Teams Get Wrong

    May 25, 2026

    How to Write a Salesforce Business Requirements Document That Developers Can Actually Use

    May 22, 2026
    Add A Comment
    Leave A Reply Cancel Reply

    Advertise with Salesforce Trail
    Connect with Salesforce Trail Community
    Latest Post

    Salesforce Consultant Career Path: From Junior Consultant to Practice Lead

    March 25, 2026

    How to Hire Salesforce Consultants: Practical Tips Every Business Should Know

    February 19, 2026

    6 Proven Principles to Drive Faster Salesforce CRM Adoption

    November 3, 2025

    Driving Revenue Efficiency with Sales Cloud in Product Companies

    October 30, 2025
    Top Review
    Designer

    Customizing Salesforce: Tailor the CRM to Fit Your Business Needs

    By Aryan SahuAugust 6, 20240

    Salesforce is an adaptable, powerful customer relationship management (CRM) software that businesses can customize, and…

    Sales Professional

    Unlock 10 Powerful Sales Pitches to Boost Your Revenue by 30X

    By Mayank SahuJuly 4, 20240

    Sales is a very competitive arena, and it is followed by one must have a…

    Salesforce Trail
    Facebook X (Twitter) Instagram LinkedIn WhatsApp Telegram
    • Home
    • About Us
    • Write For Us
    • Privacy Policy
    • Advertise With Us
    • Contact Us
    © 2026 SalesforceTrail.com All Right Reserved by SalesforceTrail

    Type above and press Enter to search. Press Esc to cancel.