CI and GitHub Actions
Run free catalog adversaries on pull requests and mainline pipelines. Prefer the official run action; the same CLI works in any CI.
CI is the same product as local: install the CLI, authenticate, pull catalog packages, and adversary run against the checkout. Official free-catalog packages are signed, so host execution is trusted without --allow-unsafe-host-execution.
Recommended integration: adversarylabs/actions/run. It installs a release CLI, exchanges CI OIDC when requested, and maps the common adversary run flags. Works on GitHub Actions and Depot CI (runs-on: depot-ubuntu-latest).
Prerequisites
- Trusted CI identity configured on the Team page for your repository. For GitHub Actions or Depot CI, add
id-token: writeand useauth-mode: oidc. - Model provider key when packages set
permissions.model: true(most catalog reviewers). Pass via the action'smodel-api-keyor the usual env vars (OPENAI_API_KEY,ANTHROPIC_API_KEY,FIREWORKS_API_KEY). - Full git history for PRs —
fetch-depth: 0so base/head merge bases resolve.
Token creation and scopes: Registry authentication.
Pull request workflow
Pass PR base/head SHAs so the CLI reviews the change set (not the whole tree). Catalog ids use domain/name form.
name: Adversary review
on:
pull_request:
permissions:
contents: read
id-token: write
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Run adversaries
id: review
uses: adversarylabs/actions/run@v1
with:
adversaries: |
go/security
security/secrets
path: .
base: ${{ github.event.pull_request.base.sha }}
head: ${{ github.event.pull_request.head.sha }}
auth-mode: oidc
registry-namespace: your-team
# Optional model-backed packages:
# model-provider: openai
# model: gpt-4o
# model-api-key: ${{ secrets.OPENAI_API_KEY }}
format: json
- name: Report outcome
if: always()
run: |
echo "outcome=${{ steps.review.outputs.outcome }}"
echo "findings=${{ steps.review.outputs.findings-count }}"Pin adversarylabs/actions/run to a release tag or full commit SHA for reproducible CI. Optionally set cli-version to an exact CLI CalVer tag (for example 2026.7.30).
Full-tree scan on main
name: Adversary full scan
on:
push:
branches: [main]
permissions:
contents: read
id-token: write
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: adversarylabs/actions/run@v1
with:
adversaries: go/security
path: .
all-files: true
auth-mode: oidc
registry-namespace: your-teamall-files: true cannot be combined with base/head.
Authentication modes
| auth-mode | When to use |
|---|---|
| oidc | Recommended for private CI pulls and publishing. GitHub Actions and native Depot CI exchange the job identity for a ten-minute team credential; no registry secret is stored. |
| token | Fallback when OIDC is unavailable. Pass token from secrets; the action runs adversary login --token-stdin. |
| none | Default of the action. Skips login — only for local path adversaries or registries that need no Adversary Labs session. Free catalog pull requires auth. |
| oauth | Interactive device login (rarely useful in non-interactive CI). |
| existing | Runner already has a CLI profile; the action never logs in or out. |
Findings and exit codes
By default the action fails the step when the review reports findings (fail-on-findings: true). Set it to false to keep the job green while still publishing findings-count and result-file (with format: json).
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | Findings reported |
| 2 | Usage / configuration error |
| 3 | Execution failure |
| 4 | Network / auth failure |
Outputs: exit-code, findings-count, result-file, outcome (success/ findings/ failure).
Generic CI (CLI only)
Any runner with a release CLI can do the same without the composite action. Install from CLI install, then:
# Install a release CLI (or use adversarylabs/actions/run which does this)
# Then authenticate with a pull-scoped service account token:
printf '%s\n' "$ADVERSARY_SERVICE_ACCOUNT_TOKEN" | \
adversary login --token-stdin --registry-namespace adversarylabs
# Pull-request style scope (set refs from your CI system):
adversary run go/security security/secrets \
--path . \
--base "$BASE_SHA" \
--head "$HEAD_SHA" \
--format json \
--output-file review.json
# Full-tree scan (for example on main):
adversary run go/security --path . --all-files --format jsonWithout explicit --base/--head, the CLI may still pick up PR scope from environment variables such as GitHub GITHUB_BASE_REF / head SHA pairs when present — but passing SHAs from the workflow is more reliable. You can also set ADVERSARY_BASE_REF and ADVERSARY_HEAD_REF.
Auto-select in CI
The run action requires an adversaries input (explicit list). For detection-based selection of every accessible catalog package, use the CLI directly:
printf '%s\n' "$ADVERSARY_SERVICE_ACCOUNT_TOKEN" | \
adversary login --token-stdin --registry-namespace adversarylabs
adversary run --path . --base "$BASE_SHA" --head "$HEAD_SHA" --format json
# or: adversary run --dry-run --explain --path . --base "$BASE_SHA" --head "$HEAD_SHA"Security notes
- OIDC pull bindings cannot publish; publishing must be explicitly enabled and is never issued to pull-request events.
- The action checksum-verifies the CLI archive before running.
- Tokens and model keys are passed via secrets / stdin / env — never as plain CLI flags in logs.
- Unsigned private packages still need
allow-unsafe-host-execution: true(or a sandbox) for host execution. Official free-catalog packages do not.
Related: Getting started, CLI, Official signatures, adversarylabs/actions.