circuitshield
v0.2.5
Published
CI security gate for Circom/ZK projects. Detects invariant, verifier-binding, and proving-artifact drift against a trusted audited baseline.
Maintainers
Readme
CircuitShield
World-50 guardrail validation: CircuitShield was tested across public ZK/Circom repositories, showcasing 43 circuit-bearing repos, 1,187 Circom circuits scanned, and 1,180 release-review signals generated. See the showcase report.
Post-audit drift detection for Circom/ZK systems.
CircuitShield is a CI guardrail for teams that already have, or are preparing for, a ZK audit. It compares the current repository state against a trusted audited baseline and highlights security-relevant drift in circuits, public inputs, verifier bindings, declared invariants, dependencies, and proving artifacts.
It returns a release decision you can enforce in CI:
PASS | WARN | MANUAL_REVIEW | REBASELINE_REQUIRED | BLOCK_CICircuitShield does not replace a professional audit, formal verification, trusted setup review, or protocol design review. It helps make post-audit changes visible before they ship.
Why CircuitShield
ZK audits are usually performed against a specific commit. After that commit, teams keep changing circuits, verifiers, dependencies, and proving artifacts. Small changes can invalidate audit assumptions even when the pull request looks routine.
CircuitShield answers one practical release question:
Has this change drifted from the audited baseline enough to require review or CI blocking?Use it to:
- detect verifier, public-input, invariant, and artifact drift before release
- require manual review when no trusted baseline is available
- generate Markdown, JSON, SARIF, and GitHub PR-comment evidence
- add a ZK-aware release gate to GitHub Actions
- keep audit assumptions visible as the codebase evolves
Live Validation Proof
CircuitShield has been live-tested against public ZK/Circom ecosystem repositories.
Latest larger validation run:
| Evidence | Result |
| --- | ---: |
| Public targets checked | 15 |
| Circuit-bearing repositories scanned | 10 |
| Circom circuits detected | 336 |
| Candidate review findings emitted | 241 |
| Expected third-party gate | MANUAL_REVIEW |
Representative scanned projects include iden3/circomlib,
semaphore-protocol/semaphore, privacy-scaling-explorations/maci,
0xPARC/circom-ecdsa, zkemail/zk-email-verify, zkemail/zk-regex,
and personaelabs/spartan-ecdsa.
See the full evidence report:
docs/validation/world-level-live-test.md.
These results are compatibility and signal-quality evidence, not an audit or
confirmed vulnerability disclosure. Third-party repositories normally do not
ship CircuitShield-specific configs or audited baselines, so MANUAL_REVIEW
is the correct conservative gate.
Install
Run without installing:
npx circuitshield@latest --helpInstall in a repository:
npm install --save-dev circuitshield
npx circuitshield --helpRequirements:
- Node.js
20.19+or22.12+ - A Circom/ZK project to scan
- Optional:
circom,snarkjs, andcircomspectfor deeper artifact and static-analysis coverage
Quick Start
From the root of your Circom/ZK repository:
npx circuitshield initReview the generated circuitshield.yml, then create a baseline from the last
audited or manually reviewed commit:
npx circuitshield baseline create \
--ref audited-v1.0.0 \
--target . \
--config circuitshield.ymlScan the current release candidate:
npx circuitshield scan . \
--config circuitshield.yml \
--baseline audited-v1.0.0 \
--format markdown \
--out circuitshield-report.mdFail CI when the gate reaches manual-review or blocking severity:
npx circuitshield ci . \
--config circuitshield.yml \
--baseline audited-v1.0.0 \
--fail-on manualGitHub Action
name: CircuitShield
on:
pull_request:
push:
branches: [main, master]
jobs:
circuitshield:
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write
steps:
- uses: actions/checkout@v5
- uses: MohdKamranAlam/[email protected]
with:
target: .
config: circuitshield.yml
baseline: audited-v1.0.0
fail-on: manualBy default, the action writes:
circuitshield-report.mdcircuitshield-report.jsoncircuitshield-comment.md
What It Checks
CircuitShield is Circom-first and focuses on post-audit drift signals.
| Area | Examples |
| --- | --- |
| Circuits | unsafe witness assignment, weak constraints, public-input mismatch |
| Invariants | missing or weakened nullifier, domain, range, Merkle, and value-conservation checks |
| Verifiers | missing verifyProof, weak proof-result enforcement, public-input binding issues |
| Baselines | circuit drift, verifier-key drift, artifact drift, dependency drift |
| Artifacts | .r1cs, .zkey, .wasm, .sym, and .ptau hash/header tracking |
| Reports | Markdown, JSON, SARIF, and GitHub PR-comment output |
Optional tool integrations:
circomfor temporary compilation and artifact extractionsnarkjsfor deeper R1CS inspectioncircomspectfor additional static findings
If an optional tool is missing, CircuitShield reports that state explicitly instead of silently pretending the check ran.
Audit Gates
| Gate | Meaning |
| --- | --- |
| PASS | No configured check requires review or blocking. |
| WARN | Evidence is incomplete or a low-risk issue should be reviewed. |
| MANUAL_REVIEW | A reviewer should approve the change before release. |
| REBASELINE_REQUIRED | The project changed enough that a new audited baseline should be created. |
| BLOCK_CI | A high-risk configured finding should fail CI. |
Control CI behavior with --fail-on:
npx circuitshield ci . --fail-on block
npx circuitshield ci . --fail-on manual
npx circuitshield ci . --fail-on warn
npx circuitshield ci . --fail-on neverConfiguration
circuitshield.yml declares the protocol intent that generic scanners cannot
infer.
version: 1
project:
name: private-withdraw-protocol
baseline:
type: git
ref: audited-v1.0.0
circuits:
- id: withdraw
path: circuits/withdraw.circom
framework: circom
verifier: contracts/WithdrawVerifier.sol
public_inputs:
- merkleRoot
- nullifierHash
- recipient
- amount
- chainId
- assetId
invariants:
- id: nullifier_unique
type: nullifier_unique
signal: nullifierHash
severity: critical
- id: amount_range
type: range_bound
signal: amount
bits: 64
severity: highGenerate a starter config with:
npx circuitshield initThen review it and add project-specific invariants. A generated config is a starting point, not an audit model.
CLI Reference
Common commands:
circuitshield init
circuitshield doctor . --config circuitshield.yml
circuitshield scan . --config circuitshield.yml
circuitshield scan . --config circuitshield.yml --baseline audited-v1.0.0
circuitshield ci . --config circuitshield.yml --baseline audited-v1.0.0 --fail-on manual
circuitshield baseline create --ref audited-v1.0.0 --target . --config circuitshield.yml
circuitshield diff . --config circuitshield.yml --baseline audited-v1.0.0
circuitshield evidence . --config circuitshield.yml --baseline audited-v1.0.0 --format mermaid
circuitshield scan . --config circuitshield.yml --format sarif --out circuitshield.sarifAdvanced commands:
circuitshield intel . --config circuitshield.yml
circuitshield knowledge . --config circuitshield.yml
circuitshield formal . --config circuitshield.yml
circuitshield benchmark benchmarks
circuitshield validate-corpus validation-corpusUse --help on any command for its options:
circuitshield scan --helpReports
Markdown reports include:
- audit gate decision
- risk summary
- detected findings
- baseline drift status
- invariant coverage
- verifier binding checks
- optional toolchain status
- suggested next actions
Generate SARIF for GitHub code scanning:
npx circuitshield scan . \
--config circuitshield.yml \
--baseline audited-v1.0.0 \
--format sarif \
--out circuitshield.sarifValidation Evidence
CircuitShield includes a labeled validation corpus with seeded vulnerable and safe Circom cases:
npx circuitshield validate-corpus validation-corpus --format markdownThe harness reports rule-level precision, recall, and false-positive rate for tracked checks. This is bounded validation against the included corpus, not a claim of universal vulnerability detection.
Evidence:
Optional Toolchain
CircuitShield runs without external ZK tools, but coverage improves when these tools are available:
npm install -g snarkjs
cargo install circomspectVerify:
snarkjs --help
circomspect --versionLimitations
CircuitShield does not prove that a protocol is secure.
It does not replace:
- a professional ZK audit
- formal verification
- trusted setup review
- cryptographic design review
- manual review of economic or protocol-level assumptions
Use accurate release language:
No critical findings detected by configured checks.
Manual review required.
Audit baseline drift detected.Avoid unsupported claims:
Secure.
Bug-free.
AI certified.Documentation
Development
npm ci
npm run build
npm testBuild the bundled GitHub Action:
npm run action:buildLicense
Apache-2.0
