> For the complete documentation index, see [llms.txt](https://docs.heeler.com/mrecEO40m5D6bt7Pq5pE/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.heeler.com/mrecEO40m5D6bt7Pq5pE/get-started/set-up-developer-tooling/cli.md).

# Install the CLI

Install heelercli locally and in CI for GitHub, GitLab, Bitbucket, and Azure DevOps repositories.

Use `heelercli` to run secrets, SAST, dependency-vulnerability, license, malicious-package, and agent-file checks locally or in CI.

The CLI works with repositories hosted on all four SCMs supported by Heeler:

| Repository host                                                                                    | Supported editions                                                                                  |
| -------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| [GitHub](/mrecEO40m5D6bt7Pq5pE/get-started/source-code-scm/github.md)                              | Cloud and GitHub Enterprise Server                                                                  |
| [GitLab](/mrecEO40m5D6bt7Pq5pE/get-started/source-code-scm/gitlab.md)                              | SaaS and self-managed                                                                               |
| [Bitbucket](/mrecEO40m5D6bt7Pq5pE/get-started/source-code-scm/bitbucket-cloud.md)                  | Cloud and [Data Center](/mrecEO40m5D6bt7Pq5pE/get-started/source-code-scm/bitbucket-data-center.md) |
| [Azure DevOps](/mrecEO40m5D6bt7Pq5pE/get-started/source-code-scm/azure-devops-app-registration.md) | Cloud                                                                                               |

{% hint style="info" %}
The CLI scans a local directory or Git working tree. The repository does not need to be hosted on GitHub or connected to Heeler. Heeler publishes the CLI and pre-commit hook through GitHub Releases; that download location does not restrict the repository's SCM provider.

SCM connections are required for platform features such as repository harvesting, pull or merge request guardrails, and remediation pull requests.
{% endhint %}

## Choose a setup

| Goal                                                | Setup                                                      |
| --------------------------------------------------- | ---------------------------------------------------------- |
| Scan staged changes before each commit              | [Pre-commit hook](#install-the-pre-commit-hook)            |
| Scan every local Git repository                     | [Global Git hook](#install-a-global-git-hook)              |
| Run scans manually                                  | [Direct binary installation](#install-the-binary-directly) |
| Enforce checks on pushes and pull or merge requests | [CI](#run-in-ci)                                           |
| Share the same commands between developers and CI   | [Make](#use-make-optional)                                 |

## Requirements

| Requirement               | When it is needed                                                                              |
| ------------------------- | ---------------------------------------------------------------------------------------------- |
| Git                       | Pre-commit and staged-file scans. `sast`, `secrets`, and `ci` can also scan plain directories. |
| Python 3 and `pip`        | The pre-commit framework only.                                                                 |
| Heeler API key            | SAST and checks that call Heeler services. Secrets scanning requires no Heeler authentication. |
| Ecosystem toolchains      | Dependency checks may require tools such as `go`, `mvn`, `npm`, `dotnet`, or `cargo`.          |
| Access to GitHub Releases | Automatic and direct downloads, unless your organization mirrors the CLI internally.           |

Supported binaries:

| OS                    | Architectures | Archive |
| --------------------- | ------------- | ------- |
| Linux                 | amd64, arm64  | `.tgz`  |
| macOS                 | amd64, arm64  | `.tgz`  |
| Windows with Git Bash | amd64         | `.zip`  |

See the [CLI Command Reference](/mrecEO40m5D6bt7Pq5pE/reference/cli-command-reference.md) for command-specific authentication, ecosystem, and toolchain requirements.

## Install the pre-commit hook

This configuration is the same for GitHub, GitLab, Bitbucket, and Azure DevOps repositories.

{% stepper %}
{% step %}

### Install pre-commit

```bash
python3 -m pip install pre-commit
```

{% endstep %}

{% step %}

### Add the Heeler hook

Create `.pre-commit-config.yaml` in the repository root:

```yaml
repos:
  - repo: https://github.com/Heeler-Security/heelercli
    rev: 1.0.24
    hooks:
      - id: heelercli-auto
```

`rev` selects the hook revision required by the pre-commit framework. Run `pre-commit autoupdate` regularly to update it.

The hook downloads the latest CLI binary on first use and reuses the cached binary. Set `HEELERCLI_VERSION` to a release tag if your organization requires an exact CLI version.
{% endstep %}

{% step %}

### Activate the hook

```bash
pre-commit install
pre-commit run --all-files
```

`pre-commit install` affects the current clone. CI remains the enforcement layer because developers can bypass local hooks with `git commit --no-verify`.
{% endstep %}
{% endstepper %}

If `heelercli` is already on `PATH`, use `id: heelercli` instead of `id: heelercli-auto`.

## Install a global Git hook

Use the global installer to scan staged changes in every local Git repository. Install `heelercli` on `PATH` first.

```bash
curl -fsSL https://raw.githubusercontent.com/Heeler-Security/heelercli/main/install-heelercli-precommit.sh \
  -o install-heelercli-precommit.sh
chmod +x install-heelercli-precommit.sh
./install-heelercli-precommit.sh --global
```

The installer:

* Runs `heelercli secrets --pre-commit`.
* Preserves and runs an existing global pre-commit hook.
* Continues to run repository-specific `.git/hooks/pre-commit` hooks when it configures the global hooks path.
* Restores the previous hook and Git configuration during uninstall.
* Refuses to overwrite a hook that is not managed by Heeler.

Uninstall:

```bash
./install-heelercli-precommit.sh --global --uninstall
```

## Install the binary directly

The examples download the latest release and verify its checksum before extraction. Replace `latest` in the URL with a release tag when you need a fixed version.

{% tabs %}
{% tab title="Linux" %}

```bash
asset=heelercli-linux-amd64.tgz
base=https://github.com/Heeler-Security/heelercli/releases/latest/download

curl -fsSLO "$base/$asset"
curl -fsSLO "$base/$asset.sha256"
sha256sum -c "$asset.sha256"
tar -xzf "$asset"
chmod +x heelercli
./heelercli version
```

Use `heelercli-linux-arm64.tgz` on Linux arm64.
{% endtab %}

{% tab title="macOS" %}

```bash
asset=heelercli-darwin-arm64.tgz
base=https://github.com/Heeler-Security/heelercli/releases/latest/download

curl -fsSLO "$base/$asset"
curl -fsSLO "$base/$asset.sha256"
shasum -a 256 -c "$asset.sha256"
tar -xzf "$asset"
chmod +x heelercli
./heelercli version
```

Use `heelercli-darwin-amd64.tgz` on an Intel Mac. Run the terminal natively on Apple Silicon rather than through Rosetta.
{% endtab %}

{% tab title="Windows" %}
Run these commands in Git Bash:

```bash
asset=heelercli-windows-amd64.zip
base=https://github.com/Heeler-Security/heelercli/releases/latest/download

curl -fsSLO "$base/$asset"
curl -fsSLO "$base/$asset.sha256"
sha256sum -c "$asset.sha256"
unzip -q "$asset"
./heelercli.exe version
```

{% endtab %}
{% endtabs %}

<details>

<summary>Verify release provenance with Sigstore</summary>

Each release includes a Sigstore bundle. After downloading the archive and matching `.bundle` file, verify the build identity:

```bash
cosign verify-blob \
  --bundle heelercli-linux-amd64.tgz.bundle \
  --certificate-identity-regexp '^https://github\.com/heelerai/heeler-cli/\.github/workflows/release\.yml@refs/tags/.*$' \
  --certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \
  heelercli-linux-amd64.tgz
```

Replace the archive and bundle names for your operating system and architecture.

</details>

## Authenticate

Secrets scanning requires no Heeler account or API key. For authenticated commands, use one of these methods:

{% tabs %}
{% tab title="Local" %}

```bash
heelercli login https://app.heeler.com YOUR_HEELER_API_KEY
```

The CLI saves its configuration in the operating system's user configuration directory.
{% endtab %}

{% tab title="CI" %}
Store `HEELER_API_KEY` in the CI provider's protected secret store. The CLI reads it from the environment:

```bash
export HEELER_API_KEY="<secret supplied by CI>"
```

Set `HEELER_BASE_URL` only when the CLI should use a Heeler deployment other than `https://app.heeler.com`.
{% endtab %}
{% endtabs %}

Forked pull or merge request pipelines may not receive protected secrets. Run `heelercli secrets` without authentication in those pipelines, or use the SCM provider's approved workflow for trusted contributions.

## Verify the installation

```bash
heelercli version
heelercli secrets
```

`heelercli version` confirms that the binary can run. A secrets scan exits `0` when no finding violates policy and non-zero when it finds a violation. A policy failure means the installation worked.

## Run in CI

Each example:

1. Downloads and checksum-verifies the latest Linux amd64 release.
2. Reads `HEELER_API_KEY` from the provider's secret store.
3. Runs `heelercli ci` and writes SARIF.
4. Retains the report when the security gate fails.

{% tabs %}
{% tab title="GitHub Actions" %}
Save as `.github/workflows/heeler.yml`:

```yaml
name: Heeler security checks

on:
  pull_request:
  push:
    branches: [main]

permissions:
  contents: read
  security-events: write

jobs:
  heeler:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install heelercli
        run: |
          asset=heelercli-linux-amd64.tgz
          base=https://github.com/Heeler-Security/heelercli/releases/latest/download
          curl -fsSLO "$base/$asset"
          curl -fsSLO "$base/$asset.sha256"
          sha256sum -c "$asset.sha256"
          tar -xzf "$asset"
          chmod +x heelercli

      - name: Run Heeler
        id: heeler
        continue-on-error: true
        env:
          HEELER_API_KEY: ${{ secrets.HEELER_API_KEY }}
        run: ./heelercli ci --format sarif --output results.sarif -q

      - name: Upload SARIF artifact
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: heeler-results
          path: results.sarif

      - name: Upload to GitHub code scanning
        if: always()
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: results.sarif

      - name: Enforce Heeler result
        if: steps.heeler.outcome == 'failure'
        run: exit 1
```

{% endtab %}

{% tab title="GitLab CI" %}
Save as `.gitlab-ci.yml` and define `HEELER_API_KEY` as a masked CI/CD variable:

```yaml
heeler:
  image: ubuntu:24.04
  before_script:
    - apt-get update
    - apt-get install -y ca-certificates curl
    - asset=heelercli-linux-amd64.tgz
    - base=https://github.com/Heeler-Security/heelercli/releases/latest/download
    - curl -fsSLO "$base/$asset"
    - curl -fsSLO "$base/$asset.sha256"
    - sha256sum -c "$asset.sha256"
    - tar -xzf "$asset"
    - chmod +x heelercli
  script:
    - ./heelercli ci --format sarif --output results.sarif -q
  artifacts:
    when: always
    paths:
      - results.sarif
```

{% endtab %}

{% tab title="Bitbucket Pipelines" %}
Save as `bitbucket-pipelines.yml` and define `HEELER_API_KEY` as a secured repository or workspace variable:

```yaml
image: ubuntu:24.04

pipelines:
  default:
    - step:
        name: Heeler security checks
        script:
          - apt-get update
          - apt-get install -y ca-certificates curl
          - asset=heelercli-linux-amd64.tgz
          - base=https://github.com/Heeler-Security/heelercli/releases/latest/download
          - curl -fsSLO "$base/$asset"
          - curl -fsSLO "$base/$asset.sha256"
          - sha256sum -c "$asset.sha256"
          - tar -xzf "$asset"
          - chmod +x heelercli
          - rc=0; ./heelercli ci --format sarif --output results.sarif -q || rc=$?; exit "$rc"
        artifacts:
          - name: heeler-results
            type: scoped
            paths:
              - results.sarif
            capture-on: always
```

{% endtab %}

{% tab title="Azure Pipelines" %}
Save as `azure-pipelines.yml` and define `HEELER_API_KEY` as a secret pipeline variable:

```yaml
trigger:
  - main

pr:
  - main

pool:
  vmImage: ubuntu-latest

steps:
  - checkout: self

  - bash: |
      asset=heelercli-linux-amd64.tgz
      base=https://github.com/Heeler-Security/heelercli/releases/latest/download
      curl -fsSLO "$base/$asset"
      curl -fsSLO "$base/$asset.sha256"
      sha256sum -c "$asset.sha256"
      tar -xzf "$asset"
      chmod +x heelercli
    displayName: Install heelercli

  - bash: |
      rc=0
      ./heelercli ci --format sarif --output results.sarif -q || rc=$?
      echo "##vso[task.setvariable variable=heelerExitCode]$rc"
    displayName: Run Heeler
    env:
      HEELER_API_KEY: $(HEELER_API_KEY)

  - publish: results.sarif
    artifact: heeler-results
    condition: always()

  - bash: exit "$(heelerExitCode)"
    displayName: Enforce Heeler result
    condition: ne(variables['heelerExitCode'], '0')
```

{% endtab %}
{% endtabs %}

The default `ci` checks do not include agent files. To include repository agent instructions, skills, hooks, and MCP configuration, use:

```bash
heelercli ci --checks vulnerabilities,dependency-policy,malicious-packages,secrets,agent-files
```

Agent-file scanning requires CLI 1.0.21 or later and Heeler authentication.

{% hint style="info" %}
Self-hosted or restricted CI runners need outbound access to GitHub Releases and the configured Heeler endpoint. If that is not allowed, mirror the release archive and checksum in an approved internal artifact repository and update the download URL.
{% endhint %}

## Use Make (optional)

<details>

<summary>Define shared local and CI targets</summary>

Save as `heeler.mk` and include it from the repository's `Makefile`:

```make
HEELERCLI ?= heelercli
HEELER_DIR ?= .heeler

.PHONY: heeler heeler-secrets heeler-sast heeler-report

heeler:
	$(HEELERCLI) ci --exclude-dir $(HEELER_DIR)

heeler-secrets:
	$(HEELERCLI) secrets --exclude-dir $(HEELER_DIR)

heeler-sast:
	$(HEELERCLI) sast --fail-on critical,high --exclude-dir $(HEELER_DIR)

heeler-report:
	@mkdir -p $(HEELER_DIR)
	@rc=0; \
	 $(HEELERCLI) ci --format sarif --output $(HEELER_DIR)/heeler.sarif --exclude-dir $(HEELER_DIR) || rc=$$?; \
	 exit $$rc
```

```make
include heeler.mk
```

Keep the CLI binary and other compiled artifacts outside the scan root. If they must be inside the repository, exclude their directory.

</details>

## Roll out across an organization

* Add `.pre-commit-config.yaml` and `.heeler.yaml` to repository templates or bootstrap tooling.
* Store `HEELER_API_KEY` in each SCM provider's organization, group, workspace, or project secret store.
* Publish a reusable GitHub workflow, GitLab CI include, Bitbucket pipeline definition, or Azure Pipelines template.
* Use the global Git hook for developer-wide local coverage.
* Keep CI enabled because local hooks can be bypassed.

## Troubleshooting

| Symptom                                       | Resolution                                                                                                   |
| --------------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| `heelercli` is not on `PATH`                  | Use `heelercli-auto`, install the binary, or add its directory to `PATH`.                                    |
| Authentication fails                          | Set `HEELER_API_KEY`. Set `HEELER_BASE_URL` only for a non-default Heeler endpoint.                          |
| macOS reports an incompatible binary          | Check `uname -m` and use `darwin-arm64` or `darwin-amd64`. Do not run an arm64 installation through Rosetta. |
| Dependency detection is incomplete            | Install the ecosystem toolchain required by the discovered manifests.                                        |
| A compiled file produces many secret findings | Move build artifacts outside the repository or exclude their directory.                                      |
| CI cannot download the CLI                    | Allow access to GitHub Releases or mirror the release internally.                                            |

## Related

* [CLI workflows and policy](/mrecEO40m5D6bt7Pq5pE/prevent/cli.md)
* [CLI Command Reference](/mrecEO40m5D6bt7Pq5pE/reference/cli-command-reference.md)
* [Create and manage API keys](/mrecEO40m5D6bt7Pq5pE/get-started/users-and-access/api-keys.md)
* [Install Agent Skills](/mrecEO40m5D6bt7Pq5pE/get-started/set-up-developer-tooling/agent-skills.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.heeler.com/mrecEO40m5D6bt7Pq5pE/get-started/set-up-developer-tooling/cli.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
