> This page is for Brev, version Latest (default).
> For other versions, use one of these documentation indexes:
> - Latest (default): https://docs.nvidia.com/brev/latest/llms.txt

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.nvidia.com/brev/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.nvidia.com/brev/_mcp/server.

# Use Brev in CI/CD

> Authenticate the Brev CLI with an API key so a pipeline can create an instance, run a workload on it, and delete it.

A pipeline can create a Brev instance, run a workload on it, and delete it when the job ends. Any CI system that runs shell commands and stores secrets can drive the Brev CLI.

## Prerequisites

* An [API key](/guides/api-keys) with [**Read & Write**](/guides/api-keys#access-and-permissions) access for the organization the pipeline provisions into
* Available credits in that organization

Brev API keys are **Personal API keys**, not machine accounts. A key acts on behalf of the user who created it, so the pipeline runs with that user's permissions and stops working if they lose access to the organization. Create the key from an account that will remain in the organization.

## Set Up the CLI in a Pipeline

Your pipeline installs the CLI, signs in with the API key, and configures SSH:

```bash
# Install the CLI
bash -c "$(curl -fsSL https://raw.githubusercontent.com/brevdev/brev-cli/main/bin/install-latest.sh)"

# Sign in with the key
brev login --api-key "$BREV_API_KEY"

# Configure SSH for brev exec and brev copy
brev refresh
```

`brev login --api-key` selects the key's organization automatically. Run `brev refresh` after signing in to set up your SSH config, which the pipeline needs to reach the instance.

Once signed in, your pipeline can run any Brev command. See [CLI Overview](/cli) for the full command set.

## Store the Key as a CI Secret

Store the key in your CI system's secret store, never in the pipeline definition. Each system names this differently: GitHub Actions calls it a repository secret, GitLab CI calls it a CI/CD variable, and Jenkins calls it a credential.

## Example: GitHub Actions

#### Add the Key as a Repository Secret

In your project repository, open **Settings** → **Secrets and variables** → **Actions** → **New repository secret**, name it `BREV_API_KEY`, and paste the key.

#### Expose the Secret to the Job

Map the secret to the `BREV_API_KEY` environment variable, so the workflow holds only the secret's name:

```yaml
env:
  BREV_API_KEY: ${{ secrets.BREV_API_KEY }}
```

Your repository secret can use any name. The `env` entry is what the workflow steps reference, so keep the two consistent.

```yaml
name: GPU tests on Brev

on:
  workflow_dispatch:
  push:
    branches: [main]

jobs:
  gpu-test:
    runs-on: ubuntu-latest
    timeout-minutes: 30
    env:
      BREV_API_KEY: ${{ secrets.BREV_API_KEY }}
      INSTANCE_NAME: ci-${{ github.run_id }}-${{ github.run_attempt }}
    steps:
      - uses: actions/checkout@v4

      - name: Install Brev CLI
        run: |
          bash -c "$(curl -fsSL https://raw.githubusercontent.com/brevdev/brev-cli/main/bin/install-latest.sh)"
          echo "$HOME/.local/bin" >> "$GITHUB_PATH"

      - name: Sign in and configure SSH
        run: |
          brev login --api-key "$BREV_API_KEY"
          brev refresh

      - name: Create instance
        run: |
          brev create "$INSTANCE_NAME" \
            --gpu-name A100 \
            --startup-script @ci/setup.sh \
            --timeout 600

      - name: Copy project to the instance
        run: |
          brev exec "$INSTANCE_NAME" "mkdir -p ~/workspace"
          brev copy . "$INSTANCE_NAME:~/workspace"

      - name: Run tests
        run: brev exec "$INSTANCE_NAME" "cd ~/workspace && python3 -m pytest tests/ -v"

      - name: Delete instance
        if: always()
        run: brev delete "$INSTANCE_NAME"
```

Set the hardware selection on `brev create` and the workload command to the values your project requires. See [Instance Creation](/cli/instance-creation) for the available hardware flags.

> **Warning**
>
> Retain `if: always()` on the delete step. Without it, a failed run leaves the instance provisioned and billing.

## Troubleshooting

| Problem                                   | Resolution                                                                                                                                                         |
| ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Authentication fails                      | Check that the secret name matches your workflow, that `BREV_API_KEY` is set on the job, and that the key has not expired or been deleted.                         |
| Instance creation or deletion is denied   | Check that the key has **Read & Write** access and that its creator can perform the operation in the organization.                                                 |
| `brev exec` or `brev copy` cannot connect | The instance is usually not ready yet. `brev create` reports success even when it stops waiting, so check the instance state with `brev ls` and raise `--timeout`. |

## What's Next

#### [API Keys](/guides/api-keys)

Create, rotate, and delete the key your pipeline uses.

#### [Instance Creation](/cli/instance-creation)

Startup scripts, hardware selection, and create flags.