---
schema_version: "1"
id: 6239f5fb6170bccf1fcf5d39fe08db2955023a15d9ec3cc6bccc31617a597e8f
title: Authenticate a Salesforce Org in CI/CD
collection: developer
version: current
locale: en-us
portal_url: https://docs.salesforce.com/developer/current/en-us/code-analyzer/salesforce-code-analyzer/guides/authenticate-sforg.md
canonical_url: https://developer.salesforce.com/docs/platform/salesforce-code-analyzer/guide/authenticate-sforg.html
source_site: developer.salesforce.com
content_type: documentation
content_hash: 00260fe02866f0c4fca0b64b5f12382a912b80df80b7f192c04652f8ec4ca870
products:
  - Salesforce Code Analyzer
---
# Authenticate a Salesforce Org in CI/CD 

Set up automated authentication between CI/CD platform and your Salesforce org to continuously scan your code in Salesforce Code Analyzer. Choose the authentication method that best fits your environment.

* **JSON Web Token Bearer Flow:** This approach is recommended for enterprise pipelines and team repositories. It uses a Connected App and an X.509 digital certificate to authenticate without storing static access tokens.  
* [**SFDX Auth URL**](https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_auth_web_flow.htm)**:** This lightweight, quick-start method is ideal for solo developers, rapid prototyping, or temporary sandboxes. It captures an existing authenticated CLI session URL into a single repository secret.

This workflow uses GitHub for source control, GitHub Actions to automate CI/CD, and ApexGuru to scan the code for potential issues.

## Prerequisites

Before configuring the authentication method, complete these steps on your local workstation.

*  [Install the Salesforce CLI](https://developer.salesforce.com/docs/atlas.en-us.sfdx_setup.meta/sfdx_setup/sfdx_setup_install_cli.htm#sfdx_setup_install_cli)  
*  Identify the target Salesforce org  
*  Create a dedicated integration user to prevent pipeline failures when team members change roles or leave. We recommend not binding CI/CD pipelines to individual user accounts

## Authorize a Salesforce Org by Using a JWT Bearer Flow

This approach is recommended for enterprise pipelines and team repositories. It uses a Connected App and an X.509 digital certificate to authenticate without storing static access tokens.

1. In your local workspace, generate an RSA private key and a self-signed digital certificate using OpenSSL.  
    OpenSSL is pre-installed on macOS and available via Git Bash on Windows. See [Create a Private Key and Self-Signed Digital Certificate](https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_auth_key_and_cert.htm).

    Retain `server.key` (Private key — store in GitHub) and `server.crt` (Public cert — upload to Salesforce).

    Remove `server.pass.key` and `server.csr`.

2. In your target org, create an external client app to authorize the incoming JWT requests.

    1. In your Salesforce org, click **Setup App Manager** or **External Client Apps** and create an external client app.  
   
    2. Select **Enable OAuth Settings**.  
   
    3. Set the callback URL to http://localhost:1717/OauthRedirect.  
   
    4. Select **Enable JWT Bearer Flow** and upload your `server.crt` file.  
   
    5. Add these OAuth scopes.  
   
        1. Manage user data via APIs (api) 
   
        2. Perform requests at any time (refresh\_token, offline\_access)  
   
        3. Manage user data via Web browsers (web)  
   
    6. Configure pre-authorization policies.  
   
    7. Under **OAuth Policies**, for Permitted Users, select **Admin approved users are pre-authorized**.
     
    8. Under App Policies, add your Integration User’s profile or permission set to the Selected list.  
   
    9. For IP Restrictions, select **Relax IP restrictions**.  
   
    10. Save the app, and copy the generated Consumer Key (Client ID).

3. Store the credentials in GitHub.

    1. In your GitHub repository, click **Settings,** click **Secrets and variables**, and then click **Actions**.

    2.  Click **New repository secret** and add these key-value pairs.

| Secret Name | Value |
| :---- | :---- |
| SF\_CLIENT\_ID | The consumer key copied from your external client app. |
| SF\_PRIVATE\_KEY | The content of server.key, including \-----BEGIN/END PRIVATE KEY-----. |
| SF\_USERNAME | The dedicated integration user for example, ci-codeanalyzer@yourcompany.com. |
| SF\_INSTANCE\_URL | Your Salesforce My Domain URL (for example, \[https://yourcompany.my.salesforce.com\](https://yourcompany.my.salesforce.com). |



4. In your `.github/workflows/ci.yml` pipeline file, add the authentication step before running the Code Analyzer scan.  
  
  ```
   `name: Authenticate to Salesforce Org`  
    `run: |`  
      `echo "${{ secrets.SF_PRIVATE_KEY }}" > server.key`  
      `sf org login jwt \`  
        `--client-id ${{ secrets.SF_CLIENT_ID }} \`  
        `--jwt-key-file server.key \`  
        `--username ${{ secrets.SF_USERNAME }} \`  
        `--instance-url ${{ secrets.SF_INSTANCE_URL }} \`  
        `--set-default`  
      `rm server.key`
  ```
## Authorize a Salesforce Org by Using an SFDX Auth URL

This lightweight, quick-start method is ideal for solo developers, rapid prototyping, or temporary sandboxes. It captures an existing authenticated CLI session URL into a single repository secret.

1. Log in to your machine using your dedicated integration user, and then print the auth URL.

      ```
      # Log in interactively (opens a browser)
      sf org login web --alias ci-org
      # Print the SFDX Auth URL for that org
      sf org display --verbose --target-org ci-org
      ```
      Copy the value of the `Sfdx Auth Url` field, which starts with `force://...`.

      Alternatively, export directly as JSON.

      ```
      sf org display --verbose --json --target-org ci-org
      ```
      Copy the value under `result.sfdxAuthUrl`.

      **Note**: You need the `--verbose` flag to display the auth URL. To revoke access later, from Setup, in the Quick Find box, enter `Connected Apps OAuth Usage`, and then select **Connected Apps OAuth Usage**. Revoke the Salesforce CLI app for that user.

2. Store the credentials in GitHub.  
   
      In your GitHub repository, click **Settings,** click **Secrets and variables,** and then click **Actions**. 

      Click **New repository secret** and add the value that you copied in the `Sfdx Auth Url` field.
      
3. Create or update your pipeline file at `.github/workflows/code-analyzer.yml`.
      
      ```
      `name: Test run-code-analyzer@v2 (ApexGuru)`

      `on:`  
        `pull_request:`  
          `branches: [main]`  
        `workflow_dispatch:`

      `jobs:`  
        `code-analysis:`  
          `permissions:`  
            `pull-requests: write`  
            `contents: read`  
            `actions: read`  
          `runs-on: ubuntu-latest`  
          `steps:`  
            `- name: Check out files`  
              `uses: actions/checkout@v5`

            `- name: Setup Java`  
              `uses: actions/setup-java@v5`  
              `with:`  
                `distribution: 'zulu'`  
                `java-version: '>=11'`

            `- name: Install Salesforce CLI`  
              `run: npm install -g @salesforce/cli@latest`

            `- name: Install Code Analyzer Plugin`  
              `run: sf plugins install @salesforce/plugin-code-analyzer@latest`

            `- name: Authenticate to Salesforce`  
              `env:`  
                `SFDX_AUTH_URL: ${{ secrets.SFDX_AUTH_URL }}`  
              `run: echo "$SFDX_AUTH_URL" | sf org login sfdx-url --set-default --sfdx-url-stdin`

            `- name: Run Salesforce Code Analyzer`  
              `id: run-code-analyzer`  
              `uses: forcedotcom/run-code-analyzer@v2`  
              `with:`  
                `run-arguments: --workspace . --rule-selector apexguru --output-file sfca_results.html --output-file sfca_results.json`  
                `results-artifact-name: code-analyzer-results`  
                `github-token: ${{ github.token }}`

            `- name: Print results`  
              `run: |`  
                `echo "Exit code: ${{ steps.run-code-analyzer.outputs.exit-code }}"`  
                `echo "Total violations: ${{ steps.run-code-analyzer.outputs.num-violations }}"`  
                `echo "Sev1: ${{ steps.run-code-analyzer.outputs.num-sev1-violations }}"`  
                `echo "Sev2: ${{ steps.run-code-analyzer.outputs.num-sev2-violations }}"`  
                `echo "Sev3: ${{ steps.run-code-analyzer.outputs.num-sev3-violations }}"`
      ```
    The `--sfdx-url-stdin` reads the URL from standard input (piped from `echo`), preventing sensitive tokens from writing to disk. `--set-default` targets this org for the Code Analyzer execution that follows.

### Troubleshooting

* If several repositories share credentials, don’t duplicate secrets manually. In your GitHub repository, click **Settings,** click **Secrets and variables,** and then click **Actions**. Click **New repository secret**. Set repository access to **All repositories** or **Selected repositories** for centralized management and rotation.  
* GitHub-hosted runners draw from a large, dynamic pool of public IP addresses. If your org enforces strict login IP restrictions, apply these resolution steps:  
  * **JWT:** Make sure that the external client app is configured to **Relax IP restrictions** under OAuth Policies.  
  * **SFDX Auth URL:** Relax the Login IP Ranges, In the Integration User's profile or org Network Access settings, relax the login IP ranges.  
    Alternatively, if your organizational policies forbid relaxing IP rules, use self-hosted GitHub runners with fixed static IP addresses and allowlist those IP addresses in Salesforce.

## See Also

- [ApexGuru](https://developer.salesforce.com/docs/platform/salesforce-code-analyzer/guides/engine-apexguru.md)
- [CI/CD Integration](https://developer.salesforce.com/docs/platform/salesforce-code-analyzer/guides/ci-cd.md)
