Skip to main content
Version: Latest

GitHub Actions Integration

Integrate Codeward into GitHub workflows for diff-aware policy gating on every PR.

Quick Start

Create .github/workflows/codeward-scan.yml:

name: Codeward
on:
pull_request:
push:
branches: [main]
workflow_dispatch:

jobs:
scan:
runs-on: ubuntu-latest
permissions:
contents: read
packages: read
pull-requests: write
issues: write
steps:
- uses: codeward-io/[email protected]
with:
event: ${{ github.event_name }}
repository: ${{ github.repository }}
current_branch: ${{ github.ref }}
pr_number: ${{ github.event.number }}
token: ${{ github.token }}

PR events perform a diff (base vs head). Non-PR events scan the default branch.

Permissions

PermissionWhy Needed
contents: readCheckout repository
packages: readPull scanner image from GHCR
pull-requests: writePost PR comments (remove if not using git:pr)
issues: writeCreate/update issues (remove if not using git:issue)

Advanced: Dependency Installation

Installing dependencies enriches vulnerability & license detection.

PR Workflow with Dependency Installs
name: Codeward (PR with deps)
on: pull_request

jobs:
scan:
runs-on: ubuntu-latest
permissions:
contents: read
packages: read
pull-requests: write
steps:
- uses: actions/checkout@v4
with: { ref: "${{ github.base_ref }}", path: main }
- uses: actions/checkout@v4
with: { ref: "${{ github.head_ref }}", path: branch }

- uses: actions/setup-node@v4
with:
node-version: '24'
cache: npm
cache-dependency-path: |
main/package-lock.json
branch/package-lock.json
- run: npm ci
working-directory: main
if: hashFiles('main/package-lock.json') != ''
- run: npm ci
working-directory: branch
if: hashFiles('branch/package-lock.json') != ''

- run: |
echo ${{ secrets.GITHUB_TOKEN }} | docker login ghcr.io -u ${{ github.actor }} --password-stdin
docker pull ghcr.io/codeward-io/scan:v0.4.0
- run: |
mkdir -p results cache
docker run --rm \
-v ${PWD}/main:/main:rw \
-v ${PWD}/branch:/branch:rw \
-v ${PWD}/results:/results:rw \
-v ${PWD}/cache:/tmp/.cache:rw \
-e CODEWARD_GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }} \
-e CODEWARD_GITHUB_OWNER=${{ github.repository_owner }} \
-e CODEWARD_GITHUB_REPOSITORY=${{ github.event.repository.name }} \
-e CODEWARD_GITHUB_PR_NUMBER=${{ github.event.number }} \
-e CODEWARD_MODE=diff \
ghcr.io/codeward-io/scan:v0.4.0

Intel Configuration

The scanner runs on signed Intel snapshots by default — no key needed. Supply a key to switch to live API queries:

- uses: codeward-io/[email protected]
with:
token: ${{ secrets.GITHUB_TOKEN }}
intel_token: ${{ secrets.CODEWARD_INTEL_TOKEN }}
InputDefaultPurpose
intel_tokenIntel API key (query:batch scope). Switches the default mode to api
intel_modeautoapi, download, local, disabled
intel_apihttps://intel.codeward.ioOverride for self-hosted Intel
intel_requiredtrueFail the scan if no vulnerability data was obtained

The action caches the snapshot directory between runs, so only the first scan on a runner pays the full download. See Intel for sizes and freshness.

Binary Mode

Unavailable on v0.4.0

Binary mode downloads its scanner from the codeward-io/scan release assets, and the v0.4.0 release has none attached yet — the step fails with a 404. Stay on the default docker runtime until the assets are published.

Run the scanner without Docker — no daemon, no registry login. Useful on macOS and Windows runners and on locked-down self-hosted fleets:

- uses: codeward-io/[email protected]
with:
token: ${{ secrets.GITHUB_TOKEN }}
runtime: binary

The action resolves the right binary for the runner's OS and architecture, verifies it against the release's SHA256SUMS before making it executable, and caches it by version and platform.

InputDefaultPurpose
runtimedockerdocker or binary
versionaction versionScanner version to download in binary mode

Supported on Linux and macOS runners, x64 and arm64. Windows resolves a .exe asset but that path is untested — treat it as unsupported for now.

Outputs

OutputDescription
results_pathDirectory containing the scan result JSON files

Webhook Secrets

Pass sensitive values for custom webhooks:

- uses: codeward-io/[email protected]
with:
webhook_secrets: |
SLACK_TOKEN=${{ secrets.SLACK_TOKEN }}
JIRA_API_KEY=${{ secrets.JIRA_API_KEY }}

Scheduled Scans

on:
schedule:
- cron: '30 2 * * *' # Daily at 2:30 AM

Ensure issues: write permission for git:issue destinations.

Recommendations

  • Pin action version (@v0.4.0) for reproducibility
  • Start with warn actions, promote to block after review
  • Use combined JSON + markdown for human + automation channels