Static security auditor for CI/CD pipelines (GitLab CI today; GitHub Actions + Jenkins in development).
Project description
ciguard
Static security auditor for CI/CD pipelines. Scans pipeline configuration files for misconfigurations, supply-chain risks, and compliance gaps. Produces prioritised reports with mappings to ISO 27001, SOC 2, and NIST CSF.
Supported today: GitLab CI (.gitlab-ci.yml) and GitHub Actions (.github/workflows/*.yml)
In development: Jenkins (Declarative Pipeline), SARIF output
New to ciguard? USAGE.md is a practical walkthrough — who benefits, five-minute integrations for GitLab CI / GitHub Actions / Docker, organisational policy patterns, and what the audit-grade reports actually contain.
Why
CI/CD pipelines are increasingly the highest-value attack surface in software delivery. Common misconfigurations — hardcoded secrets, unpinned images, unprotected production deployments, privileged runners — are routinely exploited (SolarWinds, Codecov, 3CX). Existing SAST tools scan application code but miss pipeline-level risks. Manual review is slow and inconsistent.
ciguard runs in seconds, produces actionable reports with compliance mapping, and is auditable enough for regulated environments.
Install
pip install ciguard
Or from source:
git clone https://github.com/Jo-Jo98/ciguard.git
cd ciguard
pip install -e .
Quick start
# Scan a pipeline (terminal summary)
ciguard scan --input .gitlab-ci.yml
# HTML report
ciguard scan --input .gitlab-ci.yml --output report.html
# JSON report (CI/API consumption)
ciguard scan --input .gitlab-ci.yml --output report.json --format json
# PDF report (audits, executive review)
ciguard scan --input .gitlab-ci.yml --output report.pdf --format pdf
# Apply organisational policies
ciguard scan --input .gitlab-ci.yml --policies policies/ --output report.html
# Scan a GitHub Actions workflow (auto-detected; --platform overrides)
ciguard scan --input .github/workflows/release.yml --output report.html
# AI-enriched executive summary (optional, requires API key)
ANTHROPIC_API_KEY=sk-ant-... ciguard scan --input .gitlab-ci.yml --llm --output report.html
Exit codes: 0 clean, 2 critical findings, 1 error.
Features
- Two platforms — GitLab CI (19 rules) and GitHub Actions (7 rules covering supply-chain, IAM, runner, deploy-governance). Format auto-detected from the YAML;
--platformoverride available. - 26 deterministic security rules across 6 categories (Pipeline Integrity, Identity & Access, Runner Security, Artifact Handling, Deployment Governance, Supply Chain)
- Policy engine — 7 built-in organisational policies + custom YAML policies (built-ins are GitLab-specific in v0.2; GHA-aware built-ins on the v0.2.x roadmap)
- Scanner integrations — Semgrep CE, OpenSSF Scorecard, GitLab native security artifacts (all optional, graceful when unavailable)
- AI enrichment — optional Claude / OpenAI executive summaries and remediation plans
- Three report formats — HTML (dark, self-contained, no CDN), JSON (API-ready), PDF (8 sections, audit-grade)
- Web UI — drag-and-drop upload, live results, downloadable reports
- REST API — FastAPI with OpenAPI docs at
/api/docs - Risk scoring — weighted A–F grade with per-category breakdown
- Compliance mapping — ISO 27001, SOC 2, NIST CSF on every finding
Validated against real-world pipelines
ciguard 0.1 has been validated against 17 public GitLab CI files including the
GitLab project itself, Inkscape, Wireshark, Meltano, fdroid, BuildStream, and
Graphviz. PRD acceptance criteria as of v0.1:
- Recall on labelled bad fixture: 100% (14/14 expected rules fire)
- False positives on labelled good fixture: 0
- Performance: 166 ms mean parse + analyse on a synthetic 500-job pipeline (5-run mean)
Regenerate locally with python scripts/validate_corpus.py and python scripts/validate_fixtures.py.
Custom policies
Create YAML files in a policies/ directory:
# policies/my_org.yml
policies:
- id: "ORG-001"
name: "No Critical Findings"
description: "Zero critical findings required before merge"
severity: critical
condition:
type: no_severity
severity: Critical
remediation: "Resolve all Critical findings before merging"
tags: [org, gate]
Supported condition types: no_rule_findings, max_findings, min_risk_score, no_severity, min_category_score, pipeline_check. See policies/example_org_policies.yml for a full example.
Risk scoring
Weighted score across 6 categories — each contributes a percentage of the overall score:
| Category | Weight |
|---|---|
| Pipeline Integrity | 25% |
| Identity & Access | 20% |
| Deployment Governance | 20% |
| Supply Chain | 20% |
| Runner Security | 7.5% |
| Artifact Handling | 7.5% |
Grades: A (90–100), B (80–89), C (70–79), D (60–69), F (<60).
Running with Docker
# Build
docker compose build
# Web UI on :8080
docker compose up web
# CLI scan
docker compose run --rm cli --input /pipeline/.gitlab-ci.yml --output /reports/report.html
Roadmap
- v0.1 — GitLab CI parser, 19 rules, policy engine, scanner integrations, HTML/JSON/PDF reports, AI enrichment, web UI
- v0.2 — GitHub Actions parser + 7 GHA rules (
usesSHA pinning,permissions: write-all, hardcoded env secrets, privileged services, deploy-without-environment, dangerous shell, unpinned containers) - v0.2.x — GHA-aware built-in policies, additional GHA rules (matrix-aware checks, reusable-workflow trust)
- v0.3 — Jenkins (Declarative Pipeline only) + SARIF output
- v0.4 — Baseline / delta reports, GitHub Actions Marketplace listing
See PRD.md for the full reconciled scope and current task list.
Development
# Run tests
pytest tests/ -v
# Coverage
pytest tests/ --cov=src/ciguard --cov-report=html
# Validate against the public real-world corpus
python scripts/validate_corpus.py
# Validate the labelled fixtures (PRD acceptance criteria 1 & 2)
python scripts/validate_fixtures.py
Contributing
Issues and PRs welcome. Please run the full test suite and the fixture validator (python scripts/validate_fixtures.py) before submitting — both must pass.
License
Apache 2.0 — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ciguard-0.2.0.tar.gz.
File metadata
- Download URL: ciguard-0.2.0.tar.gz
- Upload date:
- Size: 94.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3353045934f30da3b7a6724c29733ee5fc5b610b38d82a2cbe35d7e721d7952c
|
|
| MD5 |
79c88c73e48d9dc10ad96cd3a8858642
|
|
| BLAKE2b-256 |
6b2fb874358b013f893e3e3ce8dc7d6de73a0d8db517a3fa28bdfbe26019c68e
|
Provenance
The following attestation bundles were made for ciguard-0.2.0.tar.gz:
Publisher:
release.yml on Jo-Jo98/ciguard
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ciguard-0.2.0.tar.gz -
Subject digest:
3353045934f30da3b7a6724c29733ee5fc5b610b38d82a2cbe35d7e721d7952c - Sigstore transparency entry: 1381789973
- Sigstore integration time:
-
Permalink:
Jo-Jo98/ciguard@1f452c0f431a629158457355d41bda9466649893 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/Jo-Jo98
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@1f452c0f431a629158457355d41bda9466649893 -
Trigger Event:
push
-
Statement type:
File details
Details for the file ciguard-0.2.0-py3-none-any.whl.
File metadata
- Download URL: ciguard-0.2.0-py3-none-any.whl
- Upload date:
- Size: 90.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d8d4f8b05ea32993640feabff209b4c194efd9986b4e332af445a00dd1ddb959
|
|
| MD5 |
f3563fe444c258a4d37e024c4c6428c3
|
|
| BLAKE2b-256 |
43fc6a3bb2c2a55c537eef46020903805dcfb49861258189ff1340726ac43284
|
Provenance
The following attestation bundles were made for ciguard-0.2.0-py3-none-any.whl:
Publisher:
release.yml on Jo-Jo98/ciguard
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ciguard-0.2.0-py3-none-any.whl -
Subject digest:
d8d4f8b05ea32993640feabff209b4c194efd9986b4e332af445a00dd1ddb959 - Sigstore transparency entry: 1381789980
- Sigstore integration time:
-
Permalink:
Jo-Jo98/ciguard@1f452c0f431a629158457355d41bda9466649893 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/Jo-Jo98
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@1f452c0f431a629158457355d41bda9466649893 -
Trigger Event:
push
-
Statement type: