Skip to content

Commit 3399aeb

Browse files
mudigalbkontur
andauthored
Security scan, dependency audit, and repo hygiene (#203)
* Add LICENSE files, fix workspace license to GPL-3.0-only, and add license metadata Add LICENSE-GPL3 and LICENSE-APACHE2 at the repo root. Set the workspace default to GPL-3.0-only (runtime/node crates) and override to Apache-2.0 for library/SDK crates. Fix the repository URL to paritytech/web3-storage. Add missing workspace metadata to file-system-primitives and file-system-client. Add license fields to all package.json files. * Add disclaimer, badges, security section, and fix license refs in READMEs Add prototype/PoC warning banner, CI and license badges, and a Security section pointing to the paritytech org-level policy to the root README. Rewrite the root license section to describe the dual-license setup. Update existing license references in sub-READMEs to link to the correct LICENSE file, and add license footers to the 7 READMEs that were missing them. * Revise warnings and enhance badge visibility Updated warning messages and added security and status badges. * Update badge from Polkadot SDK to Substrate * Update badge link from Polkadot SDK to Substrate * Fix security badge URL, trailing whitespace, and disclaimer text - Security badge now links to web3-storage/security (not polkadot-bulletin-chain) - Remove trailing whitespace on badge line - Tighten disclaimer: concise but retains "not audited" and "use at your own risk" * Add SPDX license headers to all source files GPL-3.0-only: provider-node, runtime, runtimes, user-interfaces (excl SDK) Apache-2.0: pallet, primitives, client, precompiles, storage-interfaces, user-interfaces/sdk/typescript, examples/papi Closes #198 (part 3/3) * Add CONTRIBUTING.md and sub-crate READMEs Add CONTRIBUTING.md with setup instructions, PR process, code style, dual-license table, and security policy. Add minimal READMEs to pallet/, primitives/, provider-node/, and runtime/. Simplify the Contributing section in the root README to point to CONTRIBUTING.md. Closes part of #198. * Add cargo-deny config, gitleaks baseline, and .gitignore fixes Add deny.toml allowing all licenses found in the dependency tree. Add .gitleaksignore to suppress false positives from well-known Substrate dev account addresses in chain specs and docs. Fix .gitignore: add desktop.ini, remove duplicate __pycache__ entry. Audit results (PR 5 of #198): - gitleaks: 9 findings, all false positives (Alice/Bob dev keys) - cargo deny: all dependencies use permissive or GPL-compatible licenses - JS deps: all permissive (MIT/Apache/ISC/BSD); 4 UNLICENSED are our own packages that already declare Apache-2.0 in source package.json - No git deps, no personal-namespace forks - No hardcoded secrets, internal URLs, or stale CI scripts - Google Doc link in docs/design/ is an intentionally public document Closes #198. * ci(security): add cargo-deny + gitleaks workflow Adds a standalone security workflow that runs license/dependency auditing (cargo-deny) and secret scanning (gitleaks) on push, PR, and weekly cron. cargo-deny runs in the ci-unified image; gitleaks installs its binary on a plain runner. Advisory checks are non-blocking on PRs to avoid DB drift. * ci(security): run security scan daily instead of weekly * ci(security): note daily cadence in schedule comment * ci(security): suppress zizmor unpinned-images for security.yml Same documented exception as check.yml — the container image is resolved at runtime from the trusted .github/env via the set-image reusable workflow and cannot be pinned to a digest in-line. * ci(security): install current cargo-deny for CVSS v4.0 support The cargo-deny bundled in the ci-unified image fails to load the advisory database because it cannot parse RUSTSEC advisories using CVSS v4.0. Install a current cargo-deny over the bundled one so the advisories check runs. * ci(security): move GITLEAKS_VERSION to .github/env Keep tool version pins centralized in .github/env like the other versions; the gitleaks job loads it via the standard 'cat .github/env >> GITHUB_ENV' step. * ci(security): run cargo-deny on ubuntu-latest, drop set-image cargo deny only reads the dependency graph (cargo metadata + Cargo.lock), so it needs no SDK toolchain or CI container. Running it on ubuntu-latest removes the set-image dependency and the zizmor unpinned-images exception; RUSTUP_TOOLCHAIN is set to stable so cargo metadata doesn't pull the pinned toolchain. * ci(security): install cargo-deny via taiki-e/install-action Use a prebuilt binary instead of 'cargo install' to avoid the ~2 min compile. taiki-e/install-action pulls the latest cargo-deny release, which supports CVSS v4.0 advisories. --------- Co-authored-by: Branislav Kontur <bkontur@gmail.com>
1 parent 1872810 commit 3399aeb

6 files changed

Lines changed: 149 additions & 10 deletions

File tree

.github/env

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ CI_IMAGE=docker.io/paritytech/ci-unified:bullseye-1.93.0-2026-01-27-v20260304235
88
NODE_VERSION=22
99
SOLC_VERSION=0.8.34
1010
RESOLC_VERSION=1.1.0
11+
GITLEAKS_VERSION=8.29.0

.github/workflows/security.yml

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
name: Security
2+
3+
on:
4+
push:
5+
branches: [main, dev]
6+
pull_request:
7+
branches: [main, dev]
8+
# Daily re-scan of unchanged code for newly-published advisories / leaks.
9+
schedule:
10+
- cron: '17 6 * * *' # daily at 06:17 UTC
11+
workflow_dispatch:
12+
13+
permissions:
14+
contents: read
15+
16+
concurrency:
17+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
18+
cancel-in-progress: true
19+
20+
jobs:
21+
cargo-deny:
22+
name: Dependency audit (cargo-deny)
23+
runs-on: ubuntu-latest
24+
timeout-minutes: 20
25+
# cargo deny only reads the dependency graph (cargo metadata + Cargo.lock),
26+
# so it needs no SDK toolchain — use stable rather than the pinned one.
27+
env:
28+
RUSTUP_TOOLCHAIN: stable
29+
steps:
30+
- name: Checkout sources
31+
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
32+
with:
33+
persist-credentials: false
34+
35+
- name: Install cargo-deny
36+
uses: taiki-e/install-action@15449e3094499af05d8d964a1c884208e4b8b595 # v2.81.11
37+
with:
38+
tool: cargo-deny
39+
40+
- name: Check licenses, bans, sources
41+
run: cargo deny --locked check licenses bans sources
42+
43+
# Advisory DB drifts over time, so keep it non-blocking on PRs.
44+
- name: Check advisories
45+
run: cargo deny --locked check advisories
46+
continue-on-error: ${{ github.event_name == 'pull_request' }}
47+
48+
# gitleaks is not in ci-unified and needs no Rust toolchain — run it standalone.
49+
gitleaks:
50+
name: Secret scan (gitleaks)
51+
runs-on: ubuntu-latest
52+
timeout-minutes: 15
53+
steps:
54+
- name: Checkout sources
55+
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
56+
with:
57+
fetch-depth: 0 # full history so every commit is scanned
58+
persist-credentials: false
59+
60+
- name: Load common environment variables via env file
61+
run: cat .github/env >> "$GITHUB_ENV"
62+
63+
- name: Cache gitleaks
64+
id: cache-gitleaks
65+
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
66+
with:
67+
path: ~/.local/bin/gitleaks
68+
key: gitleaks-${{ env.GITLEAKS_VERSION }}-${{ runner.os }}
69+
70+
# Install the binary, not the action — the action needs a license secret in an org.
71+
- name: Install gitleaks
72+
if: steps.cache-gitleaks.outputs.cache-hit != 'true'
73+
run: |
74+
mkdir -p ~/.local/bin
75+
curl -sSfL "https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}/gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz" \
76+
| tar -xz -C ~/.local/bin gitleaks
77+
chmod +x ~/.local/bin/gitleaks
78+
79+
# .gitleaksignore is honored automatically; --redact keeps matches out of logs.
80+
- name: Scan for secrets
81+
run: ~/.local/bin/gitleaks detect --source . --redact --no-banner --verbose
82+
83+
# Aggregate gate — require this in branch protection (mirrors `basic-checks`).
84+
security:
85+
name: Security
86+
needs: [cargo-deny, gitleaks]
87+
if: always()
88+
runs-on: ubuntu-latest
89+
steps:
90+
- name: Decide outcome
91+
if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')
92+
run: |
93+
echo "Security checks failed or were cancelled"
94+
exit 1

.gitignore

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
# OS
1313
.DS_Store
1414
Thumbs.db
15+
desktop.ini
1516

1617
# Test artifacts
1718
*.log
@@ -61,7 +62,4 @@ user-interfaces/**/test-results/
6162
*.docx
6263

6364
# Screenshots
64-
Screenshot.png
65-
66-
# Python
67-
__pycache__
65+
Screenshot.png

.gitleaksignore

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# All findings are well-known Substrate development accounts (Alice, Bob, etc.)
2+
# used in chain specs and documentation — not real secrets.
3+
4+
# Alice's SS58 address in genesis chain specs
5+
a8829e9e6e82f235be67103d3ced5f0be8e632fc:zombienet/storage-local-spec.json:generic-api-key:105
6+
ebab9789e0a12d49dc89713bf6d74f67d89c7460:chain-specs/storage-local.json:generic-api-key:26
7+
865d2deed77a4b2fdb5a28999e38eadeb5e7dc2b:chain-specs/storage-rococo.json:generic-api-key:58
8+
b8f1c040408903b47c8d1c2f42015a301f0d7c88:scripts/genesis-patch.json:generic-api-key:34
9+
d1c4b2d63a2c25136cc06e30495438f911d946d9:scripts/genesis-patch.json:generic-api-key:34
10+
dfb793c101c6a872ebed54701d1c4e339573f105:scripts/genesis-patch.json:generic-api-key:34
11+
b72a3d9f77f1257b3cee601a9bd096879c02e0d9:scripts/genesis-patch.json:generic-api-key:34
12+
13+
# Alice/Bob public keys in testing documentation
14+
d7234303b34d5b3f153ff5dbdc4a95555f6d707c:docs/testing/MANUAL_TESTING_GUIDE.md:generic-api-key:294
15+
d7234303b34d5b3f153ff5dbdc4a95555f6d707c:docs/testing/MANUAL_TESTING_GUIDE.md:generic-api-key:298

README.md

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -318,12 +318,6 @@ The security policy for this project is governed by the
318318
[paritytech organization-level security policy](https://github.com/paritytech/.github/blob/master/SECURITY.md).
319319
If you discover a vulnerability, please follow the responsible disclosure process described there.
320320

321-
## Security
322-
323-
The security policy for this project is governed by the
324-
[paritytech organization-level security policy](https://github.com/paritytech/.github/blob/master/SECURITY.md).
325-
If you discover a vulnerability, please follow the responsible disclosure process described there.
326-
327321
## License
328322

329323
This project is dual-licensed:

deny.toml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Configuration for cargo-deny (https://embarkstudios.github.io/cargo-deny/)
2+
#
3+
# Run: cargo deny check licenses
4+
5+
[licenses]
6+
version = 2
7+
allow = [
8+
"Apache-2.0",
9+
"Apache-2.0 WITH LLVM-exception",
10+
"BSD-1-Clause",
11+
"BSD-2-Clause",
12+
"BSD-3-Clause",
13+
"BSL-1.0",
14+
"CC0-1.0",
15+
"CDLA-Permissive-2.0",
16+
"GPL-3.0",
17+
"GPL-3.0-only",
18+
"ISC",
19+
"LGPL-2.1-or-later",
20+
"MIT",
21+
"MIT-0",
22+
"MPL-2.0",
23+
"Unicode-3.0",
24+
"Unlicense",
25+
"Zlib",
26+
"0BSD",
27+
]
28+
29+
# Some older crates use non-SPDX license expressions (e.g. "MIT/Apache-2.0"
30+
# or "Apache-2.0/GPL-3.0"). cargo-deny emits parse warnings for these but
31+
# the underlying licenses are all in the allow list above.
32+
33+
# r-efi (LGPL-2.1-or-later) is only compiled for UEFI targets, which are
34+
# outside our target set. It is allowed above for completeness.
35+
36+
[licenses.private]
37+
ignore = true

0 commit comments

Comments
 (0)