Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Dependabot configuration (#554)
#
# Keeps Cargo dependencies and GitHub Actions up to date, which is the
# front line of dependency-vulnerability management: most advisories are
# resolved by upgrading to a patched release.
version: 2
updates:
# Rust workspace (contracts + path deps resolve via the root lockfile).
- package-ecosystem: cargo
directory: "/"
schedule:
interval: weekly
day: monday
open-pull-requests-limit: 10
labels:
- dependencies
- rust
commit-message:
prefix: "deps"
include: scope

# Standalone api-server crate (its own lockfile).
- package-ecosystem: cargo
directory: "/api-server"
schedule:
interval: weekly
day: monday
open-pull-requests-limit: 10
labels:
- dependencies
- rust
commit-message:
prefix: "deps(api-server)"
include: scope

# GitHub Actions used across the workflows.
- package-ecosystem: github-actions
directory: "/"
schedule:
interval: weekly
day: monday
labels:
- dependencies
- ci
commit-message:
prefix: "ci"
19 changes: 4 additions & 15 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,24 +31,13 @@ jobs:
- name: Clippy
run: cargo clippy --workspace --all-targets -- -D warnings

- name: Security audit
run: |
cargo install cargo-audit
cargo audit
# Security audit and dependency vulnerability scanning now live in
# security.yml (#553) and dependency-scan.yml (#554).
# Code coverage enforcement lives in coverage.yml (#555).
# Mutation testing lives in mutation.yml (#556).

- name: Test
run: cargo test --workspace

- name: Regression tests
run: cargo test --workspace regression_tests

- name: Code coverage
run: |
cargo install cargo-tarpaulin
cargo tarpaulin --workspace --out Xml --output-dir coverage

- name: Upload coverage
uses: codecov/codecov-action@v4
with:
files: ./coverage/cobertura.xml
fail_ci_if_error: true
65 changes: 65 additions & 0 deletions .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
name: Coverage

# Code coverage enforcement (#555).
#
# Runs cargo-tarpaulin over the workspace and FAILS the build if line
# coverage drops below the threshold below. Results are also uploaded to
# Codecov, whose own gates are configured in codecov.yml.

on:
push:
branches: [main]
pull_request:
workflow_dispatch:

permissions:
contents: read

env:
# Minimum acceptable line coverage (percent). Raise as coverage improves.
COVERAGE_THRESHOLD: 70

concurrency:
group: coverage-${{ github.ref }}
cancel-in-progress: true

jobs:
coverage:
name: Enforce coverage
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: dtolnay/rust-toolchain@stable

- uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-coverage-${{ hashFiles('**/Cargo.lock') }}
restore-keys: ${{ runner.os }}-cargo-

- name: Install cargo-tarpaulin
run: cargo install cargo-tarpaulin --locked

- name: Run coverage with enforcement
run: |
cargo tarpaulin --workspace \
--out Xml --out Lcov --output-dir coverage \
--fail-under ${{ env.COVERAGE_THRESHOLD }}

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
with:
files: ./coverage/cobertura.xml
fail_ci_if_error: true
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

- name: Coverage summary
if: always()
run: |
echo "## Coverage" >> "$GITHUB_STEP_SUMMARY"
echo "Enforced minimum: **${{ env.COVERAGE_THRESHOLD }}%** line coverage." >> "$GITHUB_STEP_SUMMARY"
61 changes: 61 additions & 0 deletions .github/workflows/dependency-scan.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: Dependency Scan

# Dependency vulnerability scanning (#554).
#
# Scans the Cargo dependency tree for known vulnerabilities (RustSec) and
# yanked crates on every change to the lockfile/manifests, on a weekly
# schedule, and on demand. Complements the broader policy checks in
# security.yml.

on:
push:
branches: [main]
paths:
- '**/Cargo.toml'
- '**/Cargo.lock'
- 'deny.toml'
- '.github/workflows/dependency-scan.yml'
pull_request:
paths:
- '**/Cargo.toml'
- '**/Cargo.lock'
- 'deny.toml'
- '.github/workflows/dependency-scan.yml'
schedule:
# Daily so freshly disclosed advisories are caught quickly.
- cron: '0 5 * * *'
workflow_dispatch:

permissions:
contents: read
issues: write

concurrency:
group: dependency-scan-${{ github.ref }}
cancel-in-progress: true

jobs:
# ----------------------------------------------------------------------
# cargo-audit against the RustSec advisory database.
# ----------------------------------------------------------------------
cargo-audit:
name: cargo-audit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Audit dependencies
uses: rustsec/audit-check@v2
with:
token: ${{ secrets.GITHUB_TOKEN }}

# ----------------------------------------------------------------------
# cargo-deny advisories — second source of truth, fails the PR directly.
# ----------------------------------------------------------------------
cargo-deny-advisories:
name: cargo-deny advisories
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: EmbarkStudios/cargo-deny-action@v2
with:
command: check advisories
69 changes: 69 additions & 0 deletions .github/workflows/mutation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
name: Mutation Testing

# Mutation testing in CI/CD (#556, builds on #378).
#
# cargo-mutants injects small changes ("mutants") into the contracts and
# checks the test suite catches them. Configuration is in .cargo-mutants.toml.
#
# Two modes:
# * Pull requests — fast, only mutates lines changed in the PR diff.
# * Schedule/manual — full run over both contracts, uploaded as an artifact.

on:
pull_request:
schedule:
# Weekly full sweep.
- cron: '0 4 * * 1'
workflow_dispatch:

permissions:
contents: read

concurrency:
group: mutation-${{ github.ref }}
cancel-in-progress: true

jobs:
mutants:
name: cargo-mutants
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
# Need the base ref to compute the PR diff for incremental runs.
fetch-depth: 0

- uses: dtolnay/rust-toolchain@stable

- uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-mutants-${{ hashFiles('**/Cargo.lock') }}
restore-keys: ${{ runner.os }}-cargo-

- name: Install cargo-mutants
run: cargo install cargo-mutants --locked

# Incremental run on PRs: only mutate lines touched by this PR.
- name: Mutation test (PR diff)
if: github.event_name == 'pull_request'
run: |
git diff origin/${{ github.base_ref }}..HEAD > pr.diff
cargo mutants --no-shuffle -p ip_registry -p atomic_swap \
--in-diff pr.diff

# Full run on schedule / manual dispatch.
- name: Mutation test (full)
if: github.event_name != 'pull_request'
run: cargo mutants --no-shuffle -p ip_registry -p atomic_swap

- name: Upload mutation report
if: always()
uses: actions/upload-artifact@v4
with:
name: mutants-report
path: mutants.out/
if-no-files-found: ignore
84 changes: 84 additions & 0 deletions .github/workflows/security.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
name: Security Scan

# Security scanning for the AtomicIP contracts (#553).
#
# Combines several complementary scanners:
# * cargo-deny — supply-chain policy (bans, licenses, sources, advisories)
# * gitleaks — secret detection across the repo history
# * clippy — static analysis gate with warnings treated as errors
#
# Dedicated dependency vulnerability scanning lives in dependency-scan.yml (#554).

on:
push:
branches: [main]
pull_request:
schedule:
# Re-run weekly so newly disclosed issues surface even without a push.
- cron: '0 6 * * 1'
workflow_dispatch:

permissions:
contents: read
security-events: write

concurrency:
group: security-${{ github.ref }}
cancel-in-progress: true

jobs:
# ----------------------------------------------------------------------
# Supply-chain policy: licenses, banned crates, sources, advisories.
# ----------------------------------------------------------------------
cargo-deny:
name: cargo-deny (${{ matrix.checks }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
checks:
- advisories
- bans licenses sources
steps:
- uses: actions/checkout@v4
- name: Run cargo-deny
uses: EmbarkStudios/cargo-deny-action@v2
with:
command: check ${{ matrix.checks }}

# ----------------------------------------------------------------------
# Secret scanning: catch committed credentials / keys.
# ----------------------------------------------------------------------
secret-scan:
name: Secret scan (gitleaks)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Run gitleaks
uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

# ----------------------------------------------------------------------
# Static analysis: clippy as a security gate (denies all warnings).
# ----------------------------------------------------------------------
static-analysis:
name: Static analysis (clippy)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
components: clippy
- uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-security-${{ hashFiles('**/Cargo.lock') }}
restore-keys: ${{ runner.os }}-cargo-
- name: Clippy (deny warnings)
run: cargo clippy --workspace --all-targets -- -D warnings
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,10 @@ Latest testnet deployment addresses are published in GitHub Actions deployment s
- [Threat Model & Security](docs/threat-model.md)
- [Integration Guide for Wallet Providers](docs/integration-guide.md)
- [Security Policy](SECURITY.md)
- [Security Scanning (CI/CD)](docs/security-scanning.md)
- [Dependency Vulnerability Scanning](docs/dependency-scanning.md)
- [Code Coverage Enforcement](docs/code-coverage.md)
- [Mutation Testing](docs/mutation-testing.md)
- [Roadmap](docs/roadmap.md)

## 📦 Release Notes and Changelog
Expand Down
15 changes: 15 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,21 @@ When reporting a vulnerability, please include:
- 🔄 Time-locked commitments
- 🔄 Partial disclosure proofs

## Automated Security Scanning

Every push and pull request is scanned automatically in CI/CD:

- **Security scanning** — supply-chain policy (cargo-deny), secret detection
(gitleaks), and static analysis. See [Security Scanning](docs/security-scanning.md).
- **Dependency vulnerability scanning** — cargo-audit + cargo-deny against the
RustSec advisory database, plus Dependabot. See [Dependency Scanning](docs/dependency-scanning.md).
- **Code coverage enforcement** — a minimum coverage threshold is enforced in
CI. See [Code Coverage](docs/code-coverage.md).
- **Mutation testing** — verifies the test suite catches logic errors. See
[Mutation Testing](docs/mutation-testing.md).

Run all gates locally with `./scripts/security-checks.sh`.

## Security Audits

### Audit Status
Expand Down
Loading
Loading