Endor Labs Buildkite Plugin
Buildkite plugin to run endorctl after your step command — aligned with the Endor Labs GitHub Action for scan flags and outputs.
Documentation
- Endor Labs — scan, exit codes
- Buildkite — writing plugins, cluster secrets
- This plugin — docs index: setup · examples · troubleshooting
Quick example (vendored plugin)
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. Public git ref: https://github.com/endorlabs/endorlabs-buildkite-plugin.git#v0.1.4 (or endorlabs#v0.1.4 after directory sync). Demo: repro-sandbox.
How it works
- Single
post-commandhook — yourcommandruns first, then install/auth/scan (avoids replacing the user command). plugin.yml— full JSON Schema; validated by plugin-linter in CI (additionalProperties: false).- Credentials —
api_key_env/api_secret_env(or pre-exportedENDOR_API_CREDENTIALS_*); never passed as--api-keyon the CLI. See SECURITY.md. - Build tools — plugin installs endorctl only; put Bazel/Node/etc. on the agent or in
command. See docs/setup.md §2. - Windows —
post-command.bat/.ps1delegate to Bash; requires Git Bash on the agent (writing plugins).
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.

Example from 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. Copy-paste pipelines: 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.
Developing
docker compose run --rm tests
See CONTRIBUTING.md. E2E validation: vendored plugin in repro-sandbox.