Static analysis and security auditing for Soroban smart contracts. Integrates into GitHub Actions to detect reentrancy, arithmetic overflow, access control flaws, storage collisions, and other vulnerabilities before they reach production.
- Features
- Prerequisites
- Quick start
- Usage
- Inputs
- Outputs
- Architecture
- Severity levels
- Integrations
- Contributing
- License
- Automated scanning — runs on every push or pull request with no configuration beyond a workflow file.
- Inline annotations — findings are annotated directly on the affected lines in the diff view.
- PR summaries — a formatted comment with score, severity breakdown, and top findings is posted on each pull request.
- Security score (0–100) — quantifies overall contract health and tracks regressions over time.
- SARIF upload — feeds results into GitHub's Security > Code Scanning tab for historical tracking.
- Configurable thresholds — CI failure can be gated on severity level or score value.
- Monorepo support — multiple contract workspaces can be scanned in parallel using a build matrix.
- Exclusion rules — test fixtures, generated code, and third-party contracts can be skipped via glob patterns.
- Multi-format output — results can be produced in human-readable, JSON, or SARIF format.
- A GitHub repository containing Soroban smart contracts written in Rust.
- GitHub Actions enabled on the repository.
Create .github/workflows/audit.yml:
name: Security Audit
on: [pull_request]
jobs:
audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: Soroban-Guard/Actions@v1
with:
path: contracts/On every pull request, Soroban Guard scans contracts/ and fails the check if high-severity findings are present.
name: Security Audit
on: [pull_request]
jobs:
audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: Soroban-Guard/Actions@v1
with:
path: contracts/name: Security Audit
on: [pull_request, push]
jobs:
audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: Soroban-Guard/Actions@v1
id: guard
with:
path: |
contracts/
src/
exclude: '**/test_*,**/fixtures/*'
format: sarif
min_severity: medium
fail_on: high
upload_sarif: true
token: ${{ secrets.GITHUB_TOKEN }}
- name: Check score
run: |
echo "Security score: ${{ steps.guard.outputs.score }}"
if [[ "${{ steps.guard.outputs.score }}" -lt 70 ]]; then
echo "Score below threshold!"
exit 1
finame: Security Audit
on: [pull_request]
jobs:
audit:
strategy:
matrix:
contract-path: [contracts/vault, contracts/nft, contracts/amm]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: Soroban-Guard/Actions@v1
with:
path: ${{ matrix.contract-path }}name: Pre-commit Security Scan
on:
pull_request:
types: [opened, synchronize, reopened]
jobs:
precommit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: Soroban-Guard/Actions@v1
id: guard
with:
path: contracts/
format: json
fail_on: critical
- name: Post summary
if: always()
run: |
echo "## Soroban Guard Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "- **Score**: ${{ steps.guard.outputs.score }}/100" >> $GITHUB_STEP_SUMMARY
echo "- **Critical**: ${{ steps.guard.outputs.critical_count }}" >> $GITHUB_STEP_SUMMARY
echo "- **High**: ${{ steps.guard.outputs.high_count }}" >> $GITHUB_STEP_SUMMARYfail_on value |
CI fails when |
|---|---|
critical |
One or more critical findings exist |
high |
One or more high findings exist (default) |
medium |
One or more medium or higher findings exist |
low |
Any finding exists |
Score-based gating can be added as a post-step:
- name: Enforce score threshold
if: always()
run: |
SCORE=${{ steps.guard.outputs.score }}
if [ "$SCORE" -lt 80 ]; then
echo "Score $SCORE is below minimum 80"
exit 1
fi| Input | Required | Default | Description |
|---|---|---|---|
path |
Yes | . |
Path(s) to Soroban contract source files or directories. Supports newline-separated list for multiple paths. |
format |
No | sarif |
Output format for report_path: human, json, or sarif. sarif is uploaded to code scanning when upload_sarif is enabled. |
min_severity |
No | high |
Minimum severity to report: critical, high, medium, low, info. Findings below this threshold are omitted from annotations and comments. |
exclude |
No | '' |
Comma-separated glob patterns of files to skip (e.g. **/test_*,**/fixtures/*). |
upload_sarif |
No | true |
Upload SARIF results to GitHub code scanning. |
token |
No | github.token |
GitHub token for SARIF upload and PR comment posting. |
fail_on |
No | high |
Severity level that causes the action to fail: critical, high, medium, low. Independent of min_severity. |
| Output | Description |
|---|---|
score |
Overall security score (0–100). Higher values indicate fewer or less severe findings. |
critical_count |
Number of critical-severity findings. |
high_count |
Number of high-severity findings. |
report_path |
Filesystem path to the generated SARIF or JSON report. |
Soroban Guard is a Docker-based action built in two stages:
- Builder stage — installs the published
soroban-guard-corecrate (v0.1.0) and copies the compiled Rust analyzer binary into anode:20-slimimage alongside the Node.js orchestrator (src/main.js). - Runtime stage —
entrypoint.shinvokesnode src/main.js, which runs the analyzer in JSON mode to compute the score and findings, sets outputs, posts PR comments, creates inline annotations, generates a SARIF artifact for code scanning, and enforces thefail_onthreshold.
The Node.js layer uses @actions/core, @actions/exec, and @actions/github for all GitHub API interactions.
The fixtures/ directory contains sample Soroban contracts used by the test suite and CI: vulnerable contracts (token, amm_pair, escrow) that should produce findings, and a secure baseline (vault) that should pass. See fixtures/README.md.
Soroban Guard consists of three repositories that work together:
| Repo | Description |
|---|---|
| Soroban-Guard/Actions | GitHub Action for CI/CD integration (this repo) |
| Soroban-Guard/Core | Rust static analyzer engine and CLI |
| Soroban-Guard/VS | VS Code extension for inline analysis |
This action vs. the Core CLI: this repository is the turnkey CI integration — it bundles the analyzer binary from Core, so you never install Rust or wire up SARIF, comments, or annotations yourself. Use the Core CLI directly when you want to run scans from a terminal, a pre-commit hook, or a pipeline that doesn't use GitHub Actions.
| Level | Description |
|---|---|
| critical | Exploitable vulnerabilities that can lead to loss of funds or contract compromise (e.g. reentrancy, missing access control). |
| high | Bugs likely exploitable or violating core security assumptions (e.g. arithmetic overflow, unsafe unwraps). |
| medium | Logic errors or design issues exploitable in edge cases. |
| low | Code quality or best-practice violations with limited security impact. |
| info | Suggestions and observations with no direct security impact. |
When upload_sarif: true (default), results are uploaded to GitHub's Security > Code Scanning tab, providing historical tracking and regression detection across branches.
In pull request contexts, a summary comment containing the security score, severity breakdown, and top 10 findings is posted and updated on subsequent pushes.
Each finding is mapped to a GitHub check annotation on the affected file and line:
critical/high→ errormedium→ warninglow/info→ notice
Annotations appear directly in the Files changed tab of a pull request.
See CONTRIBUTING.md for setup, style, and testing guidance.
Source files for the action logic are in src/. The Rust analyzer source is
maintained in the Soroban-Guard/Core
repository.
MIT