---
name: "Endor Labs"
description: "Run endorctl in Buildkite CI — SCA, SAST, secrets, containers, and policy gating for the Endor Labs platform."
author: "endorlabs"
repo: "endorlabs-buildkite-plugin"
stars: 0
official: false
version: "v0.1.4"
lastUpdated: "2026-06-03T19:08:09.000Z"
---

# Endor Labs Buildkite Plugin

[![CI](https://github.com/endorlabs/endorlabs-buildkite-plugin/actions/workflows/ci.yml/badge.svg)](https://github.com/endorlabs/endorlabs-buildkite-plugin/actions/workflows/ci.yml)

Buildkite plugin to run [endorctl](https://docs.endorlabs.com/developers-api/cli/commands/scan) after your step `command` — aligned with the [Endor Labs GitHub Action](https://github.com/endorlabs/github-action) for scan flags and outputs.

## Documentation

- **Endor Labs** — [scan](https://docs.endorlabs.com/scan), [exit codes](https://docs.endorlabs.com/best-practices/troubleshooting/endorctl-exitcodes)
- **Buildkite** — [writing plugins](https://buildkite.com/docs/pipelines/integrations/plugins/writing), [cluster secrets](https://buildkite.com/docs/agent/v3/clusters/secrets)
- **This plugin** — [docs index](https://github.com/endorlabs/endorlabs-buildkite-plugin/blob/HEAD/docs/README.md): [setup](https://github.com/endorlabs/endorlabs-buildkite-plugin/blob/HEAD/docs/setup.md) · [examples](https://github.com/endorlabs/endorlabs-buildkite-plugin/blob/HEAD/docs/examples.md) · [troubleshooting](https://github.com/endorlabs/endorlabs-buildkite-plugin/blob/HEAD/docs/troubleshooting.md)

## Quick example (vendored plugin)

```yaml
secrets:
  - ENDOR_NAMESPACE
  - ENDOR_API_CREDENTIALS_KEY
  - ENDOR_API_CREDENTIALS_SECRET

steps:
  - label: ":hammer: Build and scan"
    command: "make build"
    plugins:
      - ./.buildkite/vendor/endorlabs-buildkite-plugin:
          namespace: "${ENDOR_NAMESPACE}"
          api_key_env: ENDOR_API_CREDENTIALS_KEY
          api_secret_env: ENDOR_API_CREDENTIALS_SECRET
          scan_dependencies: true
          annotate: true
```

Vendor with [`scripts/sync-vendor-endorlabs-plugin.sh`](https://github.com/endorlabs/endorlabs-buildkite-plugin/blob/HEAD/scripts/sync-vendor-endorlabs-plugin.sh). Public git ref: `https://github.com/endorlabs/endorlabs-buildkite-plugin.git#v0.1.4` (or `endorlabs#v0.1.4` after [directory sync](https://buildkite.com/docs/integrations/buildkite-plugins)). Demo: [repro-sandbox](https://github.com/endorlabs/repro-sandbox).

## How it works

- Single **`post-command`** hook — your `command` runs first, then install/auth/scan (avoids replacing the user command).
- **`plugin.yml`** — full JSON Schema; validated by [plugin-linter](https://github.com/buildkite-plugins/buildkite-plugin-linter) in CI (`additionalProperties: false`).
- **Credentials** — `api_key_env` / `api_secret_env` (or pre-exported `ENDOR_API_CREDENTIALS_*`); never passed as `--api-key` on the CLI. See [SECURITY.md](https://github.com/endorlabs/endorlabs-buildkite-plugin/blob/HEAD/SECURITY.md).
- **Build tools** — plugin installs endorctl only; put Bazel/Node/etc. on the agent or in `command`. See [docs/setup.md §2](https://github.com/endorlabs/endorlabs-buildkite-plugin/blob/HEAD/docs/setup.md#2-agent-and-cluster-build-tool-prerequisites).
- **Windows** — `post-command.bat` / `.ps1` delegate to Bash; requires Git Bash on the agent ([writing plugins](https://buildkite.com/docs/pipelines/integrations/plugins/writing)).

## Annotations

With `annotate: true` (and `jq` on the agent for JSON output), the plugin posts an HTML summary: severity counts, admission policy status, and a findings table filtered to the scan kinds enabled on that step. Use `annotate_scope: job` for per-step annotations in parallel scan pipelines.

![Endor Labs dependency scan annotation in Buildkite — severity counts, policy status, and critical/high findings table](https://raw.githubusercontent.com/endorlabs/endorlabs-buildkite-plugin/main/docs/images/buildkite-plugin-demo.png)

Example from [repro-sandbox](https://github.com/endorlabs/repro-sandbox) (`dev` branch): parallel secrets, dependencies, SAST, and AI-SAST steps each with job-scoped annotations.

## Common options

| Option | Default | Notes |
|--------|---------|--------|
| `namespace` | (required) | Endor tenant |
| `scan_dependencies` | `true` | SCA |
| `scan_secrets` / `scan_sast` | `false` | Enable per need |
| `scan_container` | `false` | Requires `image` or `image_tar`; separate from repo scans |
| `annotate` | `false` | HTML summary after scan (severity counts, top findings table, artifact link) |
| `annotate_scope` | `build` | `job` shows annotation on the step job drawer (agent v3.112+) |
| `annotate_findings_limit` | `-1` | `-1` = all critical/high in table; `N>0` adds up to N medium/low rows; `0` = counts only (needs `jq` + JSON output) |
| `fail_on_policy` | `true` | Exit `128` fails the step |
| `soft_fail` | `false` | Softens other exits; does not bypass `128` when `fail_on_policy` is true |
| `mode` | `scan` | `sign` / `verify` for artifact signing |

All keys, validation rules, and cloud keyless auth: [`plugin.yml`](https://github.com/endorlabs/endorlabs-buildkite-plugin/blob/HEAD/plugin.yml). Copy-paste pipelines: [docs/examples.md](https://github.com/endorlabs/endorlabs-buildkite-plugin/blob/HEAD/docs/examples.md).

## Buildkite context mapping

| Buildkite env | endorctl |
|---------------|----------|
| `BUILDKITE_BRANCH` | `--detached-ref-name=` |
| `BUILDKITE_PULL_REQUEST` (numeric) | `--pr=true`, `--scm-pr-id=` (unless `pr: false`) |
| `BUILDKITE_PULL_REQUEST_BASE_BRANCH` | `--pr-baseline=` |

PR comments need `enable_pr_comments` + `scm_token_env` — see [docs/troubleshooting.md](https://github.com/endorlabs/endorlabs-buildkite-plugin/blob/HEAD/docs/troubleshooting.md).

## Developing

```bash
docker compose run --rm tests
```

See [CONTRIBUTING.md](https://github.com/endorlabs/endorlabs-buildkite-plugin/blob/HEAD/CONTRIBUTING.md). E2E validation: vendored plugin in [repro-sandbox](https://github.com/endorlabs/repro-sandbox).

## License

[Apache License 2.0](https://github.com/endorlabs/endorlabs-buildkite-plugin/blob/HEAD/LICENSE).