CI/CD Integration
Gate your builds on agent security: run Humanbound's adversarial tests in your pipeline and
fail the build when findings cross a severity threshold. On GitHub, use the official
humanbound/actions
Action; on GitLab and other systems, run the hb CLI directly.
How it works
- Your pipeline boots the agent (or points at a running one) and hands its endpoint to Humanbound.
- Humanbound attacks it — multi-turn adversarial conversations (OWASP-aligned prompt injection, tool misuse, data exfiltration, and more).
- An LLM judge scores every response and records findings with severities.
- The result gates your build — exit
0on a clean pass,1whenfail-onmatches, and2when the scan itself failed (runFailed, or every conversation errored — a broken scan can never read as green). On GitHub, findings also land in the Security tab as SARIF, with a severity summary on the run page.
GitHub Actions
Use the humanbound/actions
Marketplace Action — it installs the CLI, runs the scan, gates the build, writes a severity
summary to the run page, and uploads findings to the Security tab as SARIF.
# .github/workflows/security-test.yml
name: AI Security Tests
on: [pull_request]
jobs:
security:
runs-on: ubuntu-latest
steps:
- run: docker compose up -d agent # boot your agent, reachable on localhost
- uses: humanbound/actions@v1
with:
# Your agent's config — inline here; a file or a build step also work.
endpoint: |
{
"streaming": null,
"chat_completion": {
"endpoint": "http://localhost:8000/chat",
"payload": { "content": "$PROMPT" }
}
}
# The attacker/judge LLM key (local mode). Use a repository secret.
provider-api-key: ${{ secrets.OPENAI_API_KEY }}
model: gpt-4.1
fail-on: high # fail the build on high-severity findings
Findings gate the build via fail-on, land in Security → Code scanning as SARIF, and are
summarized on the workflow run page.
Local mode vs platform mode
The Action runs in one of two modes — set exactly one credential:
| Mode | Credential | Where the engine runs | Results |
|---|---|---|---|
| Local | provider-api-key (your own LLM key) |
in the runner | job output + SARIF; no account needed |
| Platform | api-key (a Humanbound hb_… key) |
on humanbound.ai | your dashboard, plus SARIF |
Platform mode uses a user API key — no hb login, no browser:
- uses: humanbound/actions@v1
with:
api-key: ${{ secrets.HUMANBOUND_API_KEY }} # hb_… key
org-id: ${{ vars.HUMANBOUND_ORG_ID }}
project-id: ${{ vars.HUMANBOUND_PROJECT_ID }}
fail-on: high
Both ids are required — a headless run has no stored selection. Create the key with the least privilege the job needs, pinned to one project:
Requires humanbound ≥ 2.8.0
Headless HUMANBOUND_API_KEY auth ships in CLI 2.8.0. The Action checks the installed
version and fails with a clear message on older releases — pin version: or omit it to
get the latest.
Full reference
The Action supports many more inputs — scope discovery, test categories, SARIF controls, nightly deep scans, and artifacts. See the Marketplace listing for the complete inputs table and scenarios.
Fail-On Thresholds
Use fail-on (Action input) or --fail-on (CLI flag) to fail the build when vulnerabilities of
a certain severity are found:
| Threshold | Description |
|---|---|
critical |
Fail only on critical severity findings |
high |
Fail on high or critical findings |
medium |
Fail on medium, high, or critical findings |
low |
Fail on low, medium, high, or critical findings |
any |
Fail on any finding (including info) |
GitLab CI (and other CI systems)
Anywhere you can't use a GitHub Action, run the hb CLI directly. Install the engine extra
for local mode, point --endpoint at your agent, and gate with --fail-on:
# .gitlab-ci.yml
security-test:
stage: test
image: python:3.12
variables:
HB_PROVIDER: openai
HB_API_KEY: $OPENAI_API_KEY # attacker/judge LLM key (CI/CD variable)
HB_MODEL: gpt-4.1
script:
- pip install "humanbound[engine]"
- hb test --local --endpoint ./agent-config.json --wait --fail-on high
- hb logs --format json -o security-results.json
artifacts:
paths:
- security-results.json
when: always
The same pattern works on Jenkins, CircleCI, and others — install humanbound[engine], run
hb test --local --endpoint <config> --wait --fail-on <severity>, then export results with
hb logs. See the CLI reference and
Agent Configuration for the endpoint config format.
Tip
Always use --wait in CI/CD so the test completes before the job finishes (the GitHub
Action does this for you). Use --fail-on to enforce a security quality gate.
Other CI systems (via the Docker image)
These snippets run the official ghcr.io/humanbound/humanbound image directly in
local mode — no Python install needed on the runner. See the Docker page for mount
and networking details (workspace mounts, host.docker.internal, platform-auth mounts).
GitLab CI
adversarial-test:
image:
name: ghcr.io/humanbound/humanbound:2
entrypoint: [""]
script:
- hb test --endpoint ./endpoint.json --wait --fail-on high
variables:
HB_PROVIDER: openai
HB_MODEL: gpt-4o-mini
HB_API_KEY: $OPENAI_API_KEY
CircleCI
jobs:
adversarial-test:
docker:
- image: ghcr.io/humanbound/humanbound:2
steps:
- checkout
- run: hb test --endpoint ./endpoint.json --wait --fail-on high
Frequently asked questions
Is there a GitHub Action for Humanbound?
Yes. The official humanbound/actions Action wraps hb test — it installs the CLI, runs the scan, gates the build with fail-on, and uploads findings to the GitHub Security tab as SARIF. Reference it as uses: humanbound/actions@v1.
What does the --fail-on flag do in CI/CD?
The --fail-on flag causes the hb test command to exit with a non-zero status code when vulnerabilities at or above the specified severity are found. Thresholds are critical, high, medium, low, and any, allowing you to configure how strict your security gate is.
What exit codes does hb test return?
0 — the scan completed and no --fail-on condition matched. 1 — the scan completed and the --fail-on condition matched. 2 — the scan itself failed: the run ended with status Failed, or every conversation errored so nothing was actually tested. A scan failure exits 2 regardless of --fail-on, so a broken scan can never pass your gate.
What does --wait do and why should I use it in CI/CD?
--wait tells Humanbound to block until the test run completes before the command exits. Always use --wait in CI/CD pipelines to ensure results are available before the job finishes or artifacts are exported. (The GitHub Action passes --wait for you.)