GitHub Actions
Review pull-request diffs with a repository-bound OIDC identity and a persistent package cache.
1. Trust the repository
- Open the project that owns the adversaries, then open CI / OIDC.
- Choose GitHub Actions and trust either
owner/repositoryorowner/*. - Choose Pull. Publishing uses a separate grant.
- For stronger rename protection, add the numeric GitHub repository or organization ID.
2. Add the workflow
name: Adversary review
on:
pull_request:
concurrency:
group: adversary-review-${{ github.event.pull_request.number }}
cancel-in-progress: true
jobs:
review:
# Fork PRs and Dependabot runs cannot read repository secrets.
if: github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]'
runs-on: ubuntu-24.04
timeout-minutes: 30
permissions:
contents: read
id-token: write
pull-requests: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: false
- name: Restore adversary packages
uses: actions/cache@v4
with:
path: ${{ runner.temp }}/adversary-data
key: adversary-${{ runner.os }}-${{ github.event.repository.id }}-v1-${{ github.sha }}
restore-keys: |
adversary-${{ runner.os }}-${{ github.event.repository.id }}-v1-
- name: Run adversaries
uses: doomerlabs/actions/run@v1
with:
adversaries: auto
path: .
data-dir: ${{ runner.temp }}/adversary-data
timeout-minutes: 20
auth-mode: oidc
registry-namespace: your-project-slug
model-provider: openai
model: your-model-id
model-api-key: ${{ secrets.OPENAI_API_KEY }}
fail-on-findings: falseid-token: writelets the job request the GitHub OIDC identity. It does not grant source write access.pull-requests: writelets the action submit inline review findings.fetch-depth: 0lets the CLI resolve the pull-request merge base.- The cache is repository-specific because it may contain private adversary package contents.
Service-account fallback
If OIDC is unavailable, create a service account under the project's Service accounts settings with registry:pull, save it as ADVERSARY_SERVICE_ACCOUNT_TOKEN, and replace the action's auth inputs:
- name: Run adversaries
uses: doomerlabs/actions/run@v1
with:
adversaries: auto
auth-mode: token
token: ${{ secrets.ADVERSARY_SERVICE_ACCOUNT_TOKEN }}
registry-namespace: your-project-slug
timeout-minutes: 20Service accounts are long-lived and are not repository-bound. They do not enable repository feedback memory.
Fork pull requests and Dependabot
GitHub does not pass repository secrets to workflows triggered by a fork, and Dependabot pull requests receive the same restricted treatment. The example skips the model-backed review job for both, so it does not fail with a missing model credential.
To review one of these changes, a maintainer can run the adversaries locally or inspect the change and reproduce it on a branch in the base repository. Approving and rerunning a fork workflow does not make repository secrets available. Do not switch this workflow to pull_request_target and check out the fork: that would expose privileged credentials while processing untrusted code.
What makes the check fail?
Findings are informational by default because fail-on-findings is false. Authentication, download, configuration, execution, and wall-clock timeout failures still fail the job. Increase timeout-minutes for cold caches or large automatic review sets.
Reviews without this workflow
Install the GitHub App from Repos to get hosted pull-request reviews with hosted inference. That path does not add a workflow file or a repository model key. See Hosted reviews.