> ## Documentation Index
> Fetch the complete documentation index at: https://docs.switchagents.ai/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> These docs moved from docs.flintai.dev to docs.switchagents.ai. Use docs.switchagents.ai for every link and request.
> To search these docs from an AI tool, connect the MCP server at https://docs.switchagents.ai/mcp. The page index is at https://docs.switchagents.ai/llms.txt.

# CI/CD integration

> Integrate flintai-cli into your continuous integration pipeline

Save scan and eval results as build artifacts to prove validation before deployment.

<Tip>
  **API keys required.** Add your LLM provider API key (Gemini, OpenAI, or Anthropic) to your CI system's secrets/environment variables. Never commit API keys to your repository.
</Tip>

<Warning>
  **Install OpenGrep in your pipeline.** `flintai scan` uses OpenGrep for pattern analysis, and `pip install flintai-cli` doesn't include it. Without it the scan still succeeds and writes results, but skips the pattern layer — a passing build that checked less than you think. Each example below installs it and puts it on `PATH`.
</Warning>

<Tabs>
  <Tab title="GitHub Actions">
    Add `flintai-cli` to your GitHub Actions workflow:

    ```yaml theme={null}
    name: Agent validation

    on: [pull_request]

    jobs:
      scan:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v6
          
          - name: Set up Python
            uses: actions/setup-python@v6
            with:
              python-version: '3.11'
          
          - name: Install flintai-cli
            run: pip install flintai-cli
          
          - name: Install OpenGrep
            run: |
              curl -fsSL https://raw.githubusercontent.com/opengrep/opengrep/main/install.sh | bash
              echo "$HOME/.opengrep/cli/latest" >> "$GITHUB_PATH"
          
          - name: Scan agent code
            env:
              GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
            run: flintai scan ./agent --output scan-results.json
          
          - name: Upload scan results
            uses: actions/upload-artifact@v7
            with:
              name: flintai-scan-results
              path: scan-results.json
    ```

    **Attach the artifact to your PR** as proof you validated before merge.

    [GitHub Actions documentation →](https://docs.github.com/en/actions)
  </Tab>

  <Tab title="GitLab CI">
    Add `flintai-cli` to your `.gitlab-ci.yml`:

    ```yaml theme={null}
    stages:
      - validate

    scan-agent:
      stage: validate
      image: python:3.11
      script:
        - pip install flintai-cli
        - curl -fsSL https://raw.githubusercontent.com/opengrep/opengrep/main/install.sh | bash
        - export PATH="$HOME/.opengrep/cli/latest:$PATH"
        - flintai scan ./agent --output scan-results.json
      artifacts:
        paths:
          - scan-results.json
        expire_in: 30 days
      variables:
        GEMINI_API_KEY: $GEMINI_API_KEY
    ```

    **The artifact is automatically attached to your merge request.**

    [GitLab CI documentation →](https://docs.gitlab.com/ee/ci/)
  </Tab>

  <Tab title="CircleCI">
    Add `flintai-cli` to your `.circleci/config.yml`:

    ```yaml theme={null}
    version: 2.1

    jobs:
      scan:
        docker:
          - image: cimg/python:3.11
        steps:
          - checkout
          
          - run:
              name: Install flintai-cli
              command: pip install flintai-cli
          
          - run:
              name: Install OpenGrep
              command: |
                curl -fsSL https://raw.githubusercontent.com/opengrep/opengrep/main/install.sh | bash
                echo 'export PATH="$HOME/.opengrep/cli/latest:$PATH"' >> $BASH_ENV
          
          - run:
              name: Scan agent code
              command: flintai scan ./agent --output scan-results.json
              environment:
                GEMINI_API_KEY: ${GEMINI_API_KEY}
          
          - store_artifacts:
              path: scan-results.json
              destination: flintai-scan-results

    workflows:
      validate:
        jobs:
          - scan
    ```

    **Access artifacts from the job's Artifacts tab.**

    [CircleCI documentation →](https://circleci.com/docs/)
  </Tab>
</Tabs>

## Output formats

Switch Trust CLI writes results as **JSON** or as **SARIF** (Static Analysis Results Interchange Format), an open standard for reporting analysis findings.

| Format | Extension | Use it for |
| - | - | - |
| `json` | `.json` | Build artifacts, dashboards, your own tooling |
| `sarif` | `.sarif` | Security tools that read SARIF, including GitHub code scanning |

Tools that read SARIF ingest results from any SARIF-producing tool without a custom parser, so your findings land alongside the rest of your security results instead of in a file nobody opens. Switch Trust CLI writes [SARIF 2.1.0](https://docs.oasis-open.org/sarif/sarif/v2.1.0/sarif-v2.1.0.html).

### Set the format

`flintai scan` and `flintai eval run` write JSON unless you ask for something else. Pass `--format sarif` (short form `-f`) to write SARIF instead. The output filename follows the format you choose:

| Command | Default | With `--format sarif` |
| - | - | - |
| `flintai scan` | `scan_<timestamp>.json` | `scan_<timestamp>.sarif` |
| `flintai eval run` | `eval_<timestamp>.json` | `eval_<timestamp>.sarif` |

### What SARIF output contains

<Tabs>
  <Tab title="flintai scan">
    Findings map to file locations with line numbers, and severity maps to SARIF levels: critical and high findings become `error`, medium becomes `warning`, and everything else becomes `note`.

    This is the output GitHub code scanning is built to read.

    **Upload to GitHub code scanning:**

    ```yaml theme={null}
    jobs:
      scan:
        runs-on: ubuntu-latest
        permissions:
          security-events: write   # required to upload SARIF
        steps:
          - uses: actions/checkout@v6

          - name: Set up Python
            uses: actions/setup-python@v6
            with:
              python-version: '3.11'

          - name: Install flintai-cli
            run: pip install flintai-cli

          - name: Install OpenGrep
            run: |
              curl -fsSL https://raw.githubusercontent.com/opengrep/opengrep/main/install.sh | bash
              echo "$HOME/.opengrep/cli/latest" >> "$GITHUB_PATH"

          - name: Scan agent code
            env:
              GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
            run: flintai scan ./agent --format sarif --output scan-results.sarif

          - name: Upload to code scanning
            uses: github/codeql-action/upload-sarif@v4
            with:
              sarif_file: scan-results.sarif
    ```

    Findings then appear in the **Security** tab of your repository and as annotations on the pull request, so reviewers see them without downloading an artifact.
  </Tab>

  <Tab title="flintai eval run">
    Eval results identify the model that was tested rather than a file and line. That suits SARIF-aware tools generally, but tools built around source locations — GitHub code scanning among them — expect the file-and-line results that `flintai scan` produces.

    Reach for `--format sarif` here when your security tooling ingests SARIF and you want reliability scores in the same place as everything else. If your goal is annotations on a pull request, use `flintai scan`.
  </Tab>
</Tabs>

## Exit codes

Switch Trust Scan returns standard exit codes for CI/CD integration:

| Code | Meaning |
| - | - |
| `0` | Scan completed successfully |
| `1` | Scan failed — the path doesn't exist, or an error occurred during the scan |
| `130` | Interrupted with Ctrl+C |

<Note>
  Exit code `0` means the scan ran successfully, **not** that no issues were found. Check the results file to see findings.
</Note>

## Other CI systems

The core pattern works anywhere:

<Steps>
  <Step title="Provide Python 3.11 or later">
    Switch Trust CLI requires Python 3.11 or later. Use a prebuilt image where you can, such as `python:3.11`.
  </Step>

  <Step title="Install Switch Trust CLI">
    ```bash theme={null}
    pip install flintai-cli
    ```
  </Step>

  <Step title="Install OpenGrep and put it on PATH">
    ```bash theme={null}
    curl -fsSL https://raw.githubusercontent.com/opengrep/opengrep/main/install.sh | bash
    ```

    Add `$HOME/.opengrep/cli/latest` to `PATH`. This is the part that differs most between systems, because most of them run each step in a fresh shell: GitHub Actions writes the path to `$GITHUB_PATH`, CircleCI appends an `export` to `$BASH_ENV`, and GitLab CI runs the whole job in one shell, so a plain `export` carries. Find your system's equivalent for persisting environment changes between steps.
  </Step>

  <Step title="Set your LLM API key">
    Store the key as a secret and expose it to the job as an environment variable: `GEMINI_API_KEY`, `OPENAI_API_KEY`, or `ANTHROPIC_API_KEY`.
  </Step>

  <Step title="Run the scan">
    ```bash theme={null}
    flintai scan /path/to/agent --output results.json
    ```

    <Tip>
      Add `--format sarif` to write SARIF instead. See [Output formats](#output-formats).
    </Tip>
  </Step>

  <Step title="Save the results as a build artifact">
    Use your CI system's artifact mechanism so the file outlives the job and reviewers can reach it from the pull request.
  </Step>
</Steps>
