Nx CLI and CI Access Tokens

The permissions and membership define what developers can access on nx.app, but they don't affect what happens when you run Nx commands in CI. To manage that, you need to provision CI access tokens in your workspace settings, under the Access Control tab. Learn more about cache security best practices.

Access Control Settings Page

Access Types

Use Caution With Read-Write Tokens

The read-write tokens allow full write access to your remote cache. They should only be used in trusted environments.

There are currently two (2) types of CI Access Token for Nx Cloud's runner that you can use with your workspace. Both support distributed task execution and allow Nx Cloud to store metadata about runs.

  • read-only
  • read-write

Read Only Access

The read-only access tokens can only read from the global remote cache. Task results produced with this type of access token will be stored in an isolated remote cache accessible only by that specific branch in a CI context, and cannot influence the global shared cache.
The isolated remote cache produced with a read-only token is accessible to all machines or agents in the same CI execution, enabling cache sharing during distributed task execution.

Read & Write Access

The read-write access tokens allow task results to be stored in the remote cache for other machines or CI pipelines to download and replay. This access level should only be used for trusted environments such as protected branches within your CI Pipeline.

Setting CI Access Tokens

You can configure an access token in CI by setting the NX_CLOUD_ACCESS_TOKEN environment variable.

The NX_CLOUD_ACCESS_TOKEN takes precedence over any authentication method in your nx.json.

We recommend setting up a read-write token for you protected branches in CI and a read-only token for unprotected branches. You can leverage your CI provider's environment variables management to accomplish this.

Azure DevOps

Azure DevOps provides various mechanisms to limit access to secrets. We'll be using Variable groups in this process, but you can achieve the same result leveraging Azure Key Vault.

  1. In your project, navigate to Pipelines > Library. Variable group settings page
  2. Create a new Variable group called protected.
    • If you already have a variable group for protected environments, we recommend reusing that variable group.
  3. Add the NX_CLOUD_ACCESS_TOKEN environment variable with the read-write token from Nx Cloud. create protected variable group
  4. In Pipeline permissions, add your current pipeline configuration. variable group pipeline permission settings
  5. In Approvals and checks, add a new Branch control check. variable group branch control settings
  6. Create the Branch control check with only allowing your protected branches and checking Verify branch protection option. variable group branch control settings
  7. Create another variable group called unprotected.
  8. Add the NX_CLOUD_ACCESS_TOKEN environment variable with the read-only token from Nx Cloud.
  9. In Pipeline permissions, add your current pipeline configuration.
  10. In Approvals and checks, add a new Branch control check with the * wildcard for branches and leaving Verify branch protection unchecked. unprotected variable group settings
  11. Now you should see 2 Variable groups for protected and unprotected usage. completed variable group setup
  12. Update your pipeline to include the 2 variable groups, with conditional access for the protected variable group.

Example usage:

azure-pipelines.yml
1variables: 2 - group: unprotected 3 - ${{ if eq(variables['Build.SourceBranchName'], 'main') }}: 4 - group: protected 5
Can't someone change the variable group?

Since we use the Verify branch protection option, CI can only read the variable when running in a protected branch. If a developer tries to edit the pipeline to use the protected variable group, the pipeline will error out since permissions require running in on a protected branch.

Take caution though, if you allow team members to have direct write access to a protected branch, then they could modify the pipeline to write to the nx cache without having a code review first.

BitBucket Cloud

BitBucket Cloud supports setting environment variables per environment called Deployment variables. You can read the official BitBucket Pipelines documentation for more details.

  1. In your repository, navigate to the Repository settings > Deployment.
  2. Select an environment you have configured for protected branches, or create a new one and protect your primary branches.
    • Note: selecting branch protection rules is a premium feature of BitBucket Cloud. Use deployments variables to provide protected environment variable access
  3. Set the environment variable NX_CLOUD_ACCESS_TOKEN with the read-write token from Nx Cloud.
  4. Navigate to the Repository settings > Repository variables tab and set the variable NX_CLOUD_ACCESS_TOKEN with the read-only token from Nx Cloud. add read-only nx cloud access token to bitbucket
  5. Update the bitbucket-pipelines.yml file to include the deployment name mentioned in step 2.

Example usage:

bitbucket-pipelines.yml
1pipelines: 2 branches: 3 main: 4 - step: 5 name: 'main checks' 6 deployment: Production 7 ... 8

CircleCI

Circle CI allows creating contexts and restricting those based on various rules. You can read the official CircleCI documentation for more details.

  1. In your organization, navigate to Organization settings > Contexts and create a new context.
    • If you already have a context for protected environments, we recommend reusing that context. create a new context for protected environments
  2. Click on Add Expression Restriction that restricts the context to protected branches only such as only the main branch, e.g., pipeline.git.branch == "main". restrict context to protected branches
  3. Click on Add Environment Variable and add the NX_CLOUD_ACCESS_TOKEN environment variable with the read-write token from Nx Cloud.
  4. Back on the organization home page, navigate to your projects, then view the pipeline settings.
  5. Navigate to Environment Variables and click Add Environment Variable and add the NX_CLOUD_ACCESS_TOKEN environment variable with the read-only token from Nx Cloud. add read-only nx cloud access token to circleci
  6. Update your pipeline to include steps where you want to write to the nx cache with the correct contexts.

Example usage:

.circleci/config.yml
1jobs: 2 run-tests-protected: 3 - ... 4 run-tests-prs: 5 - ... 6 7workflows: 8 my-workflow: 9 jobs: 10 - run-tests-protected: 11 context: 12 - protected-branches 13 filters: 14 branches: 15 only: main 16 - run-tests-prs: 17 filters: 18 branches: 19 ignore: main 20

GitHub Actions

GitHub allows specifying different secrets for each environment, where an environment can be on a specific branch. You can read the official GitHub Actions documentation for more details.

  1. In your repository, navigate to Settings tab.
  2. Click on "Environments" and create an environment for your protected branches.
    • Typically, organizations already have some kind of 'release' or 'protected' environments that can be leveraged.
    • If you do not have any protected branches, it's recommended to make at least your default branch a protected branch i.e., main/master.
  3. Add a restriction for how the environment will be applied, and apply to all protected branches. Select protected branches for the environment restriction configuration
  4. Add the read-write access token with the name NX_CLOUD_ACCESS_TOKEN to your environment.
  5. Click the Secrets and variables > Actions tab in the sidebar.
  6. Add the read-only access token with the name NX_CLOUD_ACCESS_TOKEN to the repository secrets.
  7. Now you should see 2 secrets where 1 is a part of the protected environment and the other is the default repository secrets. overview of GitHub Action secret configuration settings with environments set

Example usage:

.github/workflows/ci.yml
1name: CI 2 3env: 4 NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} 5 6jobs: 7 main: 8 runs-on: ubuntu-latest 9 steps: ... 10

GitLab

GitLab allows creating variables scoped to specific environments. You can read the Official GitLab documentation for more details.

  1. In your project, navigate to Operate > Environments and create a new environment. You do not need to fill out the External Url or GitLab agent.
    • Most projects already have a production/protected environments, so we recommend using this one if it's already defined. define gitlab environment for protected branches
  2. In your project, navigate to Settings > CI/CD tab and expand the Variables section.
  3. Click on Add variable and fill in the following information:
    • Type: Variable
    • Environments: All
    • Visibility: Masked and hidden
    • Flags: uncheck Protected variable
    • Description: "read-only token for nx-cloud"
    • Key: NX_CLOUD_ACCESS_TOKEN
    • Value: Your read-only token from Nx Cloud
  4. Click Add variable. add read-only nx cloud access token to gitlab
  5. Click on Add variable again and fill in the following information:
    • Type: Variable
    • Environments: Your protected environment created in step 1
    • Visibility: Masked and hidden
    • Flags: check Protected variable
    • Description: "read-write token for nx-cloud"
    • Key: NX_CLOUD_ACCESS_TOKEN
    • Value: Your read-write token from Nx Cloud
  6. Click Add variable. add read-write nx cloud access token to gitlab
  7. Now you should see 2 secrets where 1 is a part of the protected & tagged to the environment and the other is not. GitLab project variable configuration screen
  8. Update your pipeline to include steps where you want to write to the nx cache with the correct contexts.

Example usage:

.gitlab-ci.yml
1<job-name>: 2 environment: 3 name: <environment-name> 4
Can't someone change the step environment?

Since we use the Protected variable flag, CI can only read the variable when running in a protected branch. If a developer tries to edit the steps to run a PR in the environment with the read-write token will, then the token will not be populated in CI since their branch is not marked as protected.

Take caution though, if you allow team members to have direct write access to a protected branch, then they could modify the steps to write to the nx cache without having a code review first.

Jenkins

Jenkins configuration can be quite extensive making each Jenkins instance unique. Because of this we can only provide a minimal viable approach, but there can be multiple ways to provide scoped access tokens to your pipelines. The goal is to create two areas within Jenkins, where one is the protected and the other is the unprotected. These specifically map to how you deem your branches should have read/write vs read permissions. We recommend making branches that developers cannot directly push to and require a code review to merge to, as the protected branches, and the rest being unprotected.

  1. Minimally, this can be achieved via the following Jenkins plugins:
  2. Create a folder for the unprotected and protected pipelines.
    • The names can be anything that makes sense for your organization, such as releases or PRs etc.
  3. Go into the unprotected folder and create a credential for NX_CLOUD_ACCESS_TOKEN with the read-only token from Nx Cloud.
  4. Go into the protected folder and create a credential for NX_CLOUD_ACCESS_TOKEN with the read-write token from Nx Cloud.
  5. Use the credential inside your pipeline Jenkinsfile with the Credential Binding plugin.

Example usage:

Jenkinsfile
1pipeline { 2 agent any 3 stages { 4 stage('Build') { 5 steps { 6 withCredentials([string(credentialsId: 'NX_CLOUD_ACCESS_TOKEN', variable: 'NX_CLOUD_ACCESS_TOKEN')]) { 7 sh 'echo "nx cloud access token is now set in this context"' 8 } 9 } 10 } 11 } 12} 13

Legacy methods of setting CI Access Tokens

Using CI Access Tokens in nx.json

We do not recommend that you commit an access token to your repository but older versions of Nx do support this and if you open your nx.json, you may see something like this:

1{ 2 "nxCloudAccessToken": "SOMETOKEN" 3} 4
Nx Cloud authentication is changing

From Nx 19.7 new workspaces are connected to Nx Cloud with a property called nxCloudId instead, and we recommend developers use nx login to provision their own local personal access tokens for user based authentication.

Using nx-cloud.env

You can set an environment variable locally via the nx-cloud.env file. Nx Cloud CLI will look in this file to load custom configuration like NX_CLOUD_ACCESS_TOKEN. These environment variables will take precedence over the configuration in nx.json.