Skip to main content

Integration

CI/CD Integration

Gate deployments on Sigil scan results. Block PRs that introduce risky dependencies. Automated supply chain security in every pipeline.

GitHub Actions

Add Sigil to any GitHub Actions workflow. Scans run on every push or pull request and block merges when findings exceed your threshold.

Basic setup

.github/workflows/sigil.yml
1name: Sigil Security Scan
2on:
3 pull_request:
4 push:
5 branches: [main]
6
7jobs:
8 sigil:
9 runs-on: ubuntu-latest
10 steps:
11 - uses: actions/checkout@v4
12
13 - name: Run Sigil scan
14 uses: NOMARJ/sigil@main
15 with:
16 path: "."
17 threshold: medium
18 fail-on-findings: true

Inputs

InputDefaultDescription
path.Directory to scan
thresholdmediumMinimum verdict level to trigger a failure
fail-on-findingstrueExit with non-zero code when findings exceed threshold
phasesallComma-separated list of phases to run, or all
upload-sariffalseRun a second pass in SARIF format and upload it to GitHub Code Scanning. The workflow must grant security-events: write. The SARIF pass never fails the job on its own
sarif-filesigil-results.sarifPath (relative to the workspace) where the SARIF report is written when upload-sarif is true
api-keyCloud API key for threat-intelligence enrichment. Key issuance is not yet available — leave unset; all scan phases run offline without it

Outputs

OutputDescription
verdictScan verdict: clean, low, medium, high, critical
risk-scoreNumeric risk score from the scan
findings-countTotal number of findings detected
gradeLetter grade A–F derived from the verdict (A no findings, B low-severity only, C medium, D high, F critical); empty on older CLI versions
badgeReady-to-paste shields.io Markdown badge for the grade; empty when no grade was produced
sarif-filePath of the SARIF report written by the scan (only set when upload-sarif is true)

SARIF upload

Enable upload-sarif to push results to GitHub Code Scanning. Findings appear as inline annotations on pull requests. The upload step needs security-events: write in the job's permissions (plus actions: read on private repos).

.github/workflows/sigil-sarif.yml
1name: Sigil Security Scan
2on:
3 pull_request:
4 push:
5 branches: [main]
6
7jobs:
8 sigil:
9 runs-on: ubuntu-latest
10 permissions:
11 contents: read
12 security-events: write
13 steps:
14 - uses: actions/checkout@v4
15
16 - name: Run Sigil scan
17 uses: NOMARJ/sigil@main
18 with:
19 path: "."
20 threshold: medium
21 fail-on-findings: true
22 upload-sarif: true
SARIF integration
Upload SARIF results to GitHub Advanced Security for inline PR annotations. Findings appear directly on the changed files in your pull request.

Scan only changed files

Speed up PR scans by only analyzing files that changed in the pull request. The action takes a single path, so copy the changed files into one directory first. Findings are reported relative to that directory.

.github/workflows/sigil-diff.yml
1name: Sigil Diff Scan
2on:
3 pull_request:
4
5jobs:
6 sigil:
7 runs-on: ubuntu-latest
8 steps:
9 - uses: actions/checkout@v4
10 with:
11 fetch-depth: 0
12
13 - name: Collect changed files
14 run: |
15 mkdir -p .sigil-changed
16 git diff --name-only --diff-filter=ACMR "origin/${GITHUB_BASE_REF}" HEAD \
17 | xargs -r -I{} cp --parents {} .sigil-changed/
18
19 - name: Run Sigil scan on changed files
20 uses: NOMARJ/sigil@main
21 with:
22 path: .sigil-changed
23 threshold: medium
24 fail-on-findings: true

Block merge on high-risk

Add the Sigil scan as a required status check in your branch protection rules. PRs cannot merge until the scan passes.

Required status check
Go to Settings → Branches → Branch protection rules and add the Sigil job name (e.g. sigil) as a required status check. PRs with HIGH or CRITICAL findings will be blocked from merging.

Authenticated scans

The action accepts an api-key input for cloud threat-intelligence enrichment. API key issuance is not yet available from the dashboard, so leave it unset for now — every scan phase runs fully offline without it.

GitLab CI

Include the remote Sigil template to add scanning to any GitLab pipeline. The template defines a sigil-scan job in a security stage and keeps .sigil-reports/ (scan output, sigil-results.json,metrics.txt) as job artifacts for 30 days. Override its variables from your own file.

Basic setup

.gitlab-ci.yml
1include:
2 - remote: "https://raw.githubusercontent.com/NOMARJ/sigil/main/.gitlab-ci-template.yml"
3
4variables:
5 SIGIL_SCAN_PATH: "."
6 SIGIL_THRESHOLD: "medium"
7 SIGIL_FAIL_ON_FINDINGS: "true"

Variables

VariableDefaultDescription
SIGIL_SCAN_PATH.Directory to scan
SIGIL_THRESHOLDmediumMinimum verdict level to trigger a failure
SIGIL_FAIL_ON_FINDINGStrueExit with non-zero code when findings exceed threshold
SIGIL_VERSIONlatestRelease to download (e.g. v1.3.6), or latest

Generic CI/CD

Sigil works in any CI environment that can run shell commands — Jenkins, CircleCI, Bitbucket Pipelines, or anything else. Three steps: install, scan, gate.

1. Install

bash
# Install via shell script
curl -fsSL https://sigilsec.ai/install.sh | sh

# Or pull the Docker image (tagged by release version; no latest tag)
docker pull nomark/sigil:1.3.6

2. Run scan

bash
sigil scan . --format json > sigil-report.json

3. Exit codes

Use exit codes to gate pipeline stages. sigil scan exits 1 when any finding is at or above --fail-on (low, medium, high, critical; default high). Exit 2 means the scan did not produce a usable verdict — never that the verdict was bad.

Exit CodeMeaningPipeline Action
0No finding at or above --fail-onPipeline passes
1Findings at or above --fail-on (default high)Fail pipeline
2Scan error — no usable verdict (e.g. path does not exist, invalid --fail-on)Fail pipeline, investigate the scanner

Exit code gate script

Redirecting stdout to a file leaves $? set by Sigil (no pipe in between). Branch on the exact code so findings and scanner errors both fail the job but stay distinguishable.

bash
sigil scan . --format json > sigil-report.json
EXIT_CODE=$?

case $EXIT_CODE in
  0) echo "Scan passed: no findings at or above --fail-on" ;;
  1) echo "Sigil found findings at or above --fail-on. Failing pipeline."; exit 1 ;;
  *) echo "Sigil scan error (exit $EXIT_CODE)"; exit 1 ;;
esac

Jenkins

Declarative pipeline example with Sigil scan and artifact archiving.

Jenkinsfile
1pipeline {
2 agent any
3
4 stages {
5 stage('Checkout') {
6 steps {
7 checkout scm
8 }
9 }
10 stage('Install Sigil') {
11 steps {
12 sh 'curl -fsSL https://sigilsec.ai/install.sh | sh'
13 }
14 }
15 stage('Sigil Scan') {
16 steps {
17 sh '''
18 sigil scan . --format json > sigil-report.json
19 EXIT_CODE=$?
20 case $EXIT_CODE in
21 0) ;;
22 1) echo "Sigil found findings at or above --fail-on."; exit 1 ;;
23 *) echo "Sigil scan error (exit $EXIT_CODE)"; exit 1 ;;
24 esac
25 '''
26 }
27 }
28 }
29 post {
30 always {
31 archiveArtifacts artifacts: 'sigil-report.json', allowEmptyArchive: true
32 }
33 }
34}

CircleCI

CircleCI config with Docker executor, Sigil install, scan, and artifact storage.

.circleci/config.yml
1version: 2.1
2
3jobs:
4 sigil-scan:
5 docker:
6 - image: cimg/base:stable
7 steps:
8 - checkout
9 - run:
10 name: Install Sigil
11 command: curl -fsSL https://sigilsec.ai/install.sh | sh
12 - run:
13 name: Run Sigil scan
14 command: |
15 sigil scan . --format json > sigil-report.json
16 EXIT_CODE=$?
17 case $EXIT_CODE in
18 0) ;;
19 1) echo "Sigil found findings at or above --fail-on."; exit 1 ;;
20 *) echo "Sigil scan error (exit $EXIT_CODE)"; exit 1 ;;
21 esac
22 - store_artifacts:
23 path: sigil-report.json
24 destination: sigil-report
25
26workflows:
27 security:
28 jobs:
29 - sigil-scan

Bitbucket Pipelines

Bitbucket Pipelines config with Sigil scan on every pull request.

bitbucket-pipelines.yml
1image: atlassian/default-image:4
2
3pipelines:
4 pull-requests:
5 '**':
6 - step:
7 name: Sigil Security Scan
8 script:
9 - curl -fsSL https://sigilsec.ai/install.sh | sh
10 - sigil scan . --format json > sigil-report.json
11 - EXIT_CODE=$?
12 - |
13 case $EXIT_CODE in
14 0) ;;
15 1) echo "Sigil found findings at or above --fail-on."; exit 1 ;;
16 *) echo "Sigil scan error (exit $EXIT_CODE)"; exit 1 ;;
17 esac
18 artifacts:
19 - sigil-report.json

Docker-Based CI

Run Sigil as a Docker container for hermetic, reproducible scans in any pipeline. Images are published as nomark/sigil:<version> from tagged releases. There is no latest tag — pin a version.

Volume mount

Mount your workspace into the container and scan it directly.

bash
docker run --rm -v "$(pwd):/workspace" nomark/sigil:1.3.6 scan /workspace

Multi-stage build

Scan your application as part of a multi-stage Docker build. The scanner stage gates the production image — a finding at or above --fail-on (default high) exits 1 and fails the build.

Dockerfile
1# Stage 1: Build
2FROM node:20-alpine AS builder
3WORKDIR /app
4COPY package*.json ./
5RUN npm ci
6COPY . .
7RUN npm run build
8
9# Stage 2: Sigil Scan
10FROM nomark/sigil:1.3.6 AS scanner
11COPY --from=builder /app /workspace
12RUN sigil scan /workspace --format json > /sigil-report.json
13
14# Stage 3: Production
15FROM node:20-alpine AS production
16WORKDIR /app
17COPY --from=builder /app/dist ./dist
18COPY --from=builder /app/node_modules ./node_modules
19COPY --from=scanner /sigil-report.json ./sigil-report.json
20EXPOSE 3000
21CMD ["node", "dist/index.js"]

Alert Notifications

Register notification channels for your team with POST /v1/alerts (Team plan). Each channel is a channel_type of slack, email or webhook plus a channel_config. Webhook URLs must be public HTTPS.

Slack webhook

bash
curl -X POST https://api.sigilsec.ai/v1/alerts \
  -H "Authorization: Bearer $SIGIL_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "channel_type": "slack",
    "channel_config": { "webhook_url": "https://hooks.slack.com/services/T00/B00/xxxxx" }
  }'

Email alerts

bash
curl -X POST https://api.sigilsec.ai/v1/alerts \
  -H "Authorization: Bearer $SIGIL_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "channel_type": "email",
    "channel_config": { "recipients": ["security@yourcompany.com"] }
  }'

Generic webhook

bash
curl -X POST https://api.sigilsec.ai/v1/alerts \
  -H "Authorization: Bearer $SIGIL_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "channel_type": "webhook",
    "channel_config": {
      "webhook_url": "https://yourcompany.com/webhooks/sigil",
      "headers": { "X-Sigil-Token": "your_shared_secret" }
    }
  }'
Test a channel
POST /v1/alerts/test takes the same channel_type and channel_config and sends a one-off test notification without saving the channel. List, update and remove channels with GET /v1/alerts, PUT /v1/alerts/{id} and DELETE /v1/alerts/{id}.

Output Formats

Sigil supports four output formats: text, json, sarif and html. Use --format to select the one that fits your pipeline.

Text (default)

Human-readable output with colored verdicts. Best for terminal use and quick triage.

bash
sigil scan . --format text

JSON

Machine-readable JSON output for scripting, dashboards, and CI/CD integration. One document on stdout with findings, profile, scanner and summary keys; progress lines go to stderr. Below is real output from sigil 1.3.6 scanning a two-file npm fixture (exit code 1), abridged: one of two findings shown, remediation shortened and scanner.rule_ids omitted.

bash
sigil scan . --format json
json
1{
2 "findings": [
3 {
4 "behavior": "dynamic_execution",
5 "file": "src/loader.js",
6 "fingerprint": "610195f7d8a5efacf64ed1c17b41d9d8",
7 "line": 2,
8 "phase": "CodePatterns",
9 "references": ["CWE-95", "MITRE T1059"],
10 "remediation": "eval() in Python, JavaScript, PHP or Ruby compiles and runs a string as code, so read the string it receives. ...",
11 "rule": "CODE-001",
12 "severity": "High",
13 "snippet": "eval() call — arbitrary code execution: eval(atob(payload));",
14 "tags": ["execution", "eval", "dynamic-code"],
15 "title": "eval() call — arbitrary code execution",
16 "weight": 5
17 }
18 ],
19 "profile": {
20 "behaviors": ["dynamic_execution", "uses_obfuscation"],
21 "key_risks": [
22 "HIGH: eval() call — arbitrary code execution (CODE-001) — src/loader.js:2",
23 "HIGH: JavaScript atob() — base64 decoding (OBFUSC-002) — src/loader.js:2"
24 ]
25 },
26 "scanner": {
27 "corpus_digest": "sha256:8b90afea47ef024192e5440fe2e2863c3106d194db1c14ea37a930d60d1b5839",
28 "corpus_rule_count": 267,
29 "engine_version": "1.3.6"
30 },
31 "summary": {
32 "duration_ms": 1620,
33 "files_scanned": 2,
34 "findings_count": 2,
35 "grade": "D",
36 "inline_suppressed_count": 0,
37 "platform": "npm",
38 "recommendation": "Dangerous patterns — do not run outside a sandbox until reviewed.",
39 "score": 30,
40 "suppressed_count": 0,
41 "verdict": "HIGH RISK"
42 }
43}

SARIF

Static Analysis Results Interchange Format (SARIF 2.1.0). Compatible with GitHub Code Scanning, VS Code SARIF Viewer, and other SARIF-compatible tools.

bash
sigil scan . --format sarif > results.sarif

HTML

Self-contained HTML report on stdout. Redirect it to a file and attach it as a pipeline artifact.

bash
sigil scan . --format html > sigil-report.html

Need help?

Ask a question in GitHub Discussions or check the troubleshooting guide.