Skip to main content

Using in CI / CD

cybrium is statically linked, ships as a single binary, and reads config from ~/.cybrium/config.yml or the CYBRIUM_API / CYBRIUM_TOKEN env vars. Drops into any pipeline with almost no setup.

Pattern — scan and gate

cyscan scan . --format sarif --fail-on high > out.sarif
cybrium findings upload out.sarif

If cyscan finds anything at the --fail-on threshold, the scan step exits non-zero and the pipeline fails before uploading. If everything's clean (or below the threshold), the upload records it for dashboard visibility.

Reverse the order if you want every finding recorded regardless of gate:

cyscan scan . --format sarif > out.sarif
cybrium findings upload out.sarif
# Separate gate — pipeline fails after upload
test "$(jq '[.[] | select(.severity == "critical" or .severity == "high")] | length' out.sarif)" -eq 0

GitHub Actions

name: Security
on: [push, pull_request]

jobs:
cybrium:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install cyscan + cybrium
run: |
# cyscan
curl -sSL "https://github.com/cybrium-ai/cyscan/releases/latest/download/cyscan_latest_x86_64-unknown-linux-gnu.tar.gz" \
| tar -xz -C /tmp
sudo mv /tmp/cyscan_*/cyscan /usr/local/bin/
sudo mv /tmp/cyscan_*/rules /opt/cyscan-rules
echo "CYSCAN_RULES=/opt/cyscan-rules" >> $GITHUB_ENV

# cybrium
curl -sSL "https://github.com/cybrium-ai/cli/releases/latest/download/cybrium_latest_linux_amd64.tar.gz" \
| tar -xz -C /usr/local/bin cybrium

- name: Scan + upload
env:
CYBRIUM_TOKEN: ${{ secrets.CYBRIUM_TOKEN }}
run: |
mkdir -p ~/.cybrium
cat > ~/.cybrium/config.yml <<YAML
api_url: https://app.cybrium.ai/api
token: $CYBRIUM_TOKEN
YAML
cyscan scan . --format sarif --fail-on high > out.sarif
cybrium findings upload out.sarif \
--title "${GITHUB_REPOSITORY} @ ${GITHUB_SHA::7}"

Storing the API key

Generate a CLI-scoped key on your laptop with:

cybrium login
cat ~/.cybrium/config.yml # copy the `token:` line

Or mint one through the UI: Settings → API Keys → Create with scan:upload + findings:write, then:

gh secret set CYBRIUM_TOKEN --repo <owner>/<repo>
# paste sk-... when prompted

GitLab CI

security:
image: alpine:3.20
stage: test
variables:
CYBRIUM_API: "https://app.cybrium.ai/api"
before_script:
- apk add --no-cache curl tar jq bash
- curl -sSL "https://github.com/cybrium-ai/cyscan/releases/latest/download/cyscan_latest_x86_64-unknown-linux-gnu.tar.gz" | tar -xz -C /tmp
- mv /tmp/cyscan_*/cyscan /usr/local/bin/
- export CYSCAN_RULES=/tmp/cyscan_*/rules
- curl -sSL "https://github.com/cybrium-ai/cli/releases/latest/download/cybrium_latest_linux_amd64.tar.gz" | tar -xz -C /usr/local/bin cybrium
- mkdir -p ~/.cybrium && printf "api_url: %s\ntoken: %s\n" "$CYBRIUM_API" "$CYBRIUM_TOKEN" > ~/.cybrium/config.yml
script:
- cyscan scan . --format sarif > out.sarif
- cybrium findings upload out.sarif
artifacts:
reports:
sast: out.sarif

Store CYBRIUM_TOKEN as a masked + protected CI/CD variable.

CircleCI

version: 2.1
jobs:
security:
docker:
- image: cimg/base:stable
steps:
- checkout
- run:
name: Install
command: |
curl -sSL "https://github.com/cybrium-ai/cyscan/releases/latest/download/cyscan_latest_x86_64-unknown-linux-gnu.tar.gz" | tar -xz -C /tmp
sudo mv /tmp/cyscan_*/cyscan /usr/local/bin/
sudo mv /tmp/cyscan_*/rules /opt/cyscan-rules
echo 'export CYSCAN_RULES=/opt/cyscan-rules' >> $BASH_ENV
curl -sSL "https://github.com/cybrium-ai/cli/releases/latest/download/cybrium_latest_linux_amd64.tar.gz" | tar -xz -C /usr/local/bin cybrium
- run:
name: Scan + upload
command: |
mkdir -p ~/.cybrium
printf "api_url: https://app.cybrium.ai/api\ntoken: %s\n" "$CYBRIUM_TOKEN" > ~/.cybrium/config.yml
cyscan scan . --format sarif > out.sarif
cybrium findings upload out.sarif
workflows:
main:
jobs:
- security:
context: cybrium

Jenkins (declarative)

pipeline {
agent any
environment {
CYBRIUM_TOKEN = credentials('cybrium-api-key')
}
stages {
stage('Install') {
steps {
sh '''
curl -sSL "https://github.com/cybrium-ai/cyscan/releases/latest/download/cyscan_latest_x86_64-unknown-linux-gnu.tar.gz" | tar -xz -C /tmp
sudo mv /tmp/cyscan_*/cyscan /usr/local/bin/
sudo mv /tmp/cyscan_*/rules /opt/cyscan-rules
curl -sSL "https://github.com/cybrium-ai/cli/releases/latest/download/cybrium_latest_linux_amd64.tar.gz" | tar -xz -C /usr/local/bin cybrium
mkdir -p ~/.cybrium
echo "api_url: https://app.cybrium.ai/api" > ~/.cybrium/config.yml
echo "token: ${CYBRIUM_TOKEN}" >> ~/.cybrium/config.yml
chmod 600 ~/.cybrium/config.yml
'''
}
}
stage('Security scan') {
steps {
sh '''
export CYSCAN_RULES=/opt/cyscan-rules
cyscan scan . --format sarif > out.sarif
cybrium findings upload out.sarif
'''
}
}
}
}

Release/tag-gated workflow

Run the full cybrium scan --type full_pentest only on release tags:

jobs:
pentest:
if: startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
steps:
- run: cybrium scan https://staging.example.com --type full_pentest --watch

--watch tails the scan to completion so your CI blocks until it's done.

Tips

  • Pin versions in production pipelines. latest is convenient but can surprise you — use v0.3.0 instead.
  • Rotate keys every 90 days. The CLI-minted keys already carry a 90-day expiry by default; match that cadence in CI secrets.
  • Scope the key to just scan:upload + findings:write for CI — your CLI key (with broader scopes) stays on your laptop.
  • Cache the binaries across runs. Both cyscan and cybrium are static binaries — caching the /usr/local/bin/* paths shaves 5-10s off every run.