Skip to content

Commit 58f2ab5

Browse files
nullvariantclaude
andauthored
chore(security): add gitleaks secret detection and .gitignore security baseline (#493)
* chore(security): add gitleaks secret detection and .gitignore security baseline Introduces gitleaks v8.30.1 for multi-layered secret scanning: - pre-commit hook via .pre-commit-config.yaml - CI job in security.yml with SHA256 checksum verification Applies .gitignore security baseline template with !extensions/*/.vscode/ negation for extension dev configs. Also hardens all 8 checkout steps with persist-credentials: false. Signed-off-by: Null;Variant <null@nullvariant.com> 🖥️ IDE: [VS Code](https://code.visualstudio.com/) 🔌 Extension: [Claude Code](https://claude.ai/download) Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Model-Raw: claude-opus-4-6 * chore(security): add .gitleaks.toml to allowlist test fixtures and PEM header constants Gitleaks correctly detects dummy API keys in test fixtures and PEM header strings in sshAgent.ts, but these are intentional: test fixtures use fake secrets for security testing, and sshAgent.ts uses PEM headers as format detection constants (not actual keys). Signed-off-by: Null;Variant <null@nullvariant.com> 🖥️ IDE: [VS Code](https://code.visualstudio.com/) 🔌 Extension: [Claude Code](https://claude.ai/download) Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Model-Raw: claude-opus-4-6 * fix(ci): switch gitleaks to --no-git mode for working tree scan Git history scanning triggers false positives on test fixture dummy secrets and PEM header constants across past commits. Working tree scan with .gitleaks.toml allowlist is sufficient — GitHub Secret Scanning + Push Protection already covers history. Signed-off-by: Null;Variant <null@nullvariant.com> 🖥️ IDE: [VS Code](https://code.visualstudio.com/) 🔌 Extension: [Claude Code](https://claude.ai/download) Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Model-Raw: claude-opus-4-6 * fix(ci): correct .gitleaks.toml syntax and allowlist paths Fix TOML syntax error (paths must be string array, not table array). Add allowlist for compiled output (out/), .vscode-test/, and node_modules/. Use regex alternation for src/out variants. Signed-off-by: Null;Variant <null@nullvariant.com> 🖥️ IDE: [VS Code](https://code.visualstudio.com/) 🔌 Extension: [Claude Code](https://claude.ai/download) Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Model-Raw: claude-opus-4-6 --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 3ac7ae2 commit 58f2ab5

36 files changed

Lines changed: 250 additions & 56 deletions

.github/workflows/security.yml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ jobs:
3434

3535
- name: Checkout repository
3636
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
37+
with:
38+
persist-credentials: false
3739

3840
- name: Setup Node.js
3941
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
@@ -77,6 +79,8 @@ jobs:
7779

7880
- name: Checkout repository
7981
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
82+
with:
83+
persist-credentials: false
8084

8185
- name: Setup Node.js
8286
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
@@ -126,6 +130,8 @@ jobs:
126130

127131
- name: Checkout repository
128132
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
133+
with:
134+
persist-credentials: false
129135

130136
- name: Setup Node.js
131137
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
@@ -163,6 +169,8 @@ jobs:
163169

164170
- name: Checkout repository
165171
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
172+
with:
173+
persist-credentials: false
166174

167175
- name: Initialize CodeQL
168176
uses: github/codeql-action/init@e46ed2cbd01164d986452f91f178727624ae40d7 # v4
@@ -195,6 +203,8 @@ jobs:
195203

196204
- name: Checkout repository
197205
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
206+
with:
207+
persist-credentials: false
198208

199209
- name: Run Semgrep
200210
uses: semgrep/semgrep-action@713efdd345f3035192eaa63f56867b88e63e4e5d # v1 (v0.58.0, verified 2026-03-17)
@@ -204,6 +214,38 @@ jobs:
204214
p/security-audit
205215
p/secrets
206216
217+
gitleaks:
218+
name: Gitleaks Secret Scan
219+
runs-on: ubuntu-latest
220+
permissions:
221+
contents: read
222+
223+
steps:
224+
- name: Harden Runner
225+
uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1
226+
with:
227+
egress-policy: audit
228+
229+
- name: Checkout repository
230+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
231+
with:
232+
persist-credentials: false
233+
234+
- name: Install gitleaks
235+
env:
236+
GITLEAKS_VERSION: "8.30.1"
237+
GITLEAKS_SHA256: "551f6fc83ea457d62a0d98237cbad105af8d557003051f41f3e7ca7b3f2470eb"
238+
run: |
239+
curl -sSfL "https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}/gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz" \
240+
-o gitleaks.tar.gz
241+
echo "${GITLEAKS_SHA256} gitleaks.tar.gz" | sha256sum -c -
242+
tar -xz -C /usr/local/bin gitleaks < gitleaks.tar.gz
243+
rm gitleaks.tar.gz
244+
gitleaks version
245+
246+
- name: Run gitleaks
247+
run: gitleaks detect --source . --no-git --verbose
248+
207249
socket-security:
208250
name: Socket.dev Security
209251
runs-on: ubuntu-latest
@@ -221,6 +263,8 @@ jobs:
221263

222264
- name: Checkout repository
223265
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
266+
with:
267+
persist-credentials: false
224268

225269
- name: Socket Security Review
226270
uses: SocketDev/action@ba6de6cc0565af1f42295590380973573297e31f # v1.3.2

.gitignore

Lines changed: 118 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,128 @@
1-
# Dependencies
2-
node_modules/
1+
# ============================================================
2+
# Security baseline (SSOT: _meta/_templates/infra/gitignore-security-baseline.md)
3+
# ============================================================
34

4-
# Build output
5-
out/
6-
dist/
5+
# --- Secret insurance (STD-00020 R3) ---
6+
**/.env
7+
**/.env.local
8+
**/.env.*.local
9+
**/.envrc
10+
**/.envrc.local
711

8-
# Coverage reports
9-
coverage/
12+
**/*.pem
13+
**/*.key
14+
**/*.p12
15+
**/*.pfx
16+
**/*.jks
17+
**/*.keystore
18+
**/*.gpg
1019

11-
# VS Code extension packages
12-
*.vsix
20+
**/id_rsa
21+
**/id_rsa.*
22+
**/id_dsa
23+
**/id_ecdsa
24+
**/id_ecdsa.*
25+
**/id_ed25519
26+
**/id_ed25519.*
1327

14-
# VS Code test downloads
15-
.vscode-test/
28+
**/credentials
29+
**/credentials.json
30+
**/credentials.yaml
31+
**/credentials.yml
32+
**/*.credentials.json
33+
**/.git-credentials
34+
**/.netrc
35+
**/.npmrc
36+
**/.pgpass
37+
**/.htpasswd
38+
**/.vault_pass
39+
**/vault_pass.txt
40+
41+
**/service_account*.json
42+
**/*-service-account*.json
43+
**/firebase-adminsdk*.json
44+
**/gcp-credentials*.json
45+
**/aws-credentials*.json
46+
**/client_secret*.json
47+
48+
**/secret.yaml
49+
**/secret.yml
50+
**/secrets.yaml
51+
**/secrets.yml
52+
**/private.asc
53+
**/privkey.asc
54+
**/secret.asc
55+
56+
**/.aws/config
57+
**/.config/gcloud/application_default_credentials.json
58+
**/.config/gcloud/credentials.db
59+
**/.credentials/
60+
**/sensitive/
61+
**/kubeconfig
62+
**/*.kubeconfig
63+
64+
# --- OS generated files ---
65+
**/.DS_Store
66+
**/.DS_Store?
67+
**/._*
68+
**/.Spotlight-V100
69+
**/.Trashes
70+
**/Thumbs.db
71+
**/ehthumbs.db
72+
**/Desktop.ini
1673

17-
# TypeScript cache
18-
*.tsbuildinfo
74+
# --- Editor / IDE ---
75+
**/.vscode/
76+
**/.idea/
77+
**/*.swp
78+
**/*.swo
79+
**/*~
80+
**/.project
81+
**/.classpath
82+
**/.settings/
1983

20-
# ESLint cache
21-
.eslintcache
84+
# --- Node.js / TypeScript ---
85+
**/node_modules/
86+
**/.npm/
87+
**/*.tsbuildinfo
88+
**/.eslintcache
2289

23-
# OS files
24-
.DS_Store
90+
# --- Python ---
91+
**/__pycache__/
92+
**/*.py[cod]
93+
**/*$py.class
94+
**/*.egg-info/
95+
**/.mypy_cache/
96+
**/.ruff_cache/
97+
**/.pytest_cache/
98+
**/venv/
99+
**/.venv/
25100

26-
# IDE
27-
.idea/
101+
# --- Build output / coverage ---
102+
**/dist/
103+
**/coverage/
104+
**/.nyc_output/
28105

29-
# Logs
30-
*.log
31-
npm-debug.log*
106+
# --- Logs / temp files ---
107+
**/*.log
108+
**/npm-debug.log*
109+
**/yarn-debug.log*
110+
**/yarn-error.log*
111+
**/*.tmp
112+
**/*.temp
32113

33-
# Environment
34-
.env
35-
.env.local
114+
# ============================================================
115+
# Project-specific exclusions (add below)
116+
# ============================================================
117+
118+
# VS Code workspace configs (intentionally tracked for extension development)
119+
!extensions/*/.vscode/
120+
121+
# Build output
122+
out/
123+
124+
# VS Code extension packages
125+
*.vsix
126+
127+
# VS Code test downloads
128+
.vscode-test/

.gitleaks.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[extend]
2+
useDefault = true
3+
4+
[allowlist]
5+
paths = [
6+
'''(src|out)/test/''',
7+
'''(src|out)/ssh/sshAgent\.(ts|js)''',
8+
'''\.vscode-test/''',
9+
'''node_modules/''',
10+
]

.pre-commit-config.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,9 @@ repos:
2626
args: ['--maxkb=1000']
2727
- id: mixed-line-ending
2828
args: ['--fix=lf']
29+
30+
# Secret detection
31+
- repo: https://github.com/gitleaks/gitleaks
32+
rev: v8.30.1
33+
hooks:
34+
- id: gitleaks

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
[![Snyk monitored](https://img.shields.io/badge/Snyk-monitored-4C4A73?logo=snyk&logoColor=white)](https://snyk.io/)
1313
[![Socket.dev](https://img.shields.io/badge/Socket.dev-monitored-7042F5)](https://socket.dev/dashboard/org/null-variant/repo/nullvariant-vscode-extensions)
1414
[![GitGuardian](https://img.shields.io/badge/GitGuardian-monitored-7042F5?logo=gitguardian)](https://www.gitguardian.com/)
15+
[![Gitleaks](https://img.shields.io/badge/Gitleaks-enabled-blue?logo=git&logoColor=white)](https://github.com/gitleaks/gitleaks)
1516
[![Renovate](https://img.shields.io/badge/renovate-enabled-brightgreen?logo=renovatebot)](https://renovatebot.com)
1617
[![FOSSA License](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fnullvariant%2Fnullvariant-vscode-extensions.svg?type=shield&issueType=license)](https://app.fossa.com/projects/git%2Bgithub.com%2Fnullvariant%2Fnullvariant-vscode-extensions?ref=badge_shield&issueType=license)
1718
[![FOSSA Security](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fnullvariant%2Fnullvariant-vscode-extensions.svg?type=shield&issueType=security)](https://app.fossa.com/projects/git%2Bgithub.com%2Fnullvariant%2Fnullvariant-vscode-extensions?ref=badge_shield&issueType=security)

SECURITY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ This repository contains VS Code extensions with the following security measures
6767
- **Fork Protection**: Sensitive workflows skip on fork repositories
6868
- **SAST (Snyk Code)**: [Snyk](https://snyk.io/) runs static analysis; test fixtures are excluded via `.snyk` policy
6969
- **License & Vulnerability Scanning**: [FOSSA](https://app.fossa.com/) runs license compliance, dependency quality, and security analysis on every commit (GitHub App integration)
70+
- **Secret Detection**: [Gitleaks](https://github.com/gitleaks/gitleaks) scans for hardcoded secrets in both CI (`security.yml`) and pre-commit hooks (`.pre-commit-config.yaml`)
7071
- **Runtime Security Monitoring**: [StepSecurity Harden-Runner](https://github.com/step-security/harden-runner) monitors all workflow runs for suspicious network egress, file access, and process execution
7172
- **Branch Protection**: Main branch requires PR approval (1 reviewer minimum). All PRs are automatically approved by nullvariant-justice[bot] after CI passes (solo-developer workflow for [OpenSSF Scorecard](https://securityscorecards.dev/) compliance). Dependency bot PRs receive additional safety review before approval. Enforced by [Allstar](https://github.com/ossf/allstar/)
7273

extensions/git-id-switcher/CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [0.19.5] - 2026-05-09
11+
12+
### Added
13+
14+
- **Gitleaks secret detection**: Added gitleaks v8.30.1 for multi-layered secret scanning via pre-commit hook and CI job with SHA256 checksum verification
15+
- **Gitleaks badge**: Added Gitleaks badge to the root README, extension README, and all 26 localized READMEs
16+
17+
### Changed
18+
19+
- **.gitignore security baseline**: Rewrote .gitignore with comprehensive secret insurance patterns (`**/` prefix, credential files, key files) and project-specific negation for extension `.vscode/` dev configs
20+
- **Workflow hardening**: Added `persist-credentials: false` to all 8 checkout steps in `security.yml`
21+
1022
## [0.19.4] - 2026-04-16
1123

1224
### Removed

extensions/git-id-switcher/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
<a href="https://codecov.io/gh/nullvariant/nullvariant-vscode-extensions"><img src="https://codecov.io/gh/nullvariant/nullvariant-vscode-extensions/graph/badge.svg" alt="codecov"></a>
2626
<a href="https://sonarcloud.io/summary/new_code?id=nullvariant_nullvariant-vscode-extensions"><img src="https://sonarcloud.io/api/project_badges/measure?project=nullvariant_nullvariant-vscode-extensions&metric=alert_status" alt="Quality Gate Status"></a>
2727
<a href="https://snyk.io/"><img src="https://img.shields.io/badge/Snyk-monitored-4C4A73?logo=snyk&logoColor=white" alt="Snyk monitored"></a>
28+
<a href="https://github.com/gitleaks/gitleaks"><img src="https://img.shields.io/badge/Gitleaks-enabled-blue?logo=git&logoColor=white" alt="Gitleaks"></a>
2829
<a href="https://github.com/step-security/harden-runner"><img src="https://img.shields.io/badge/Harden--Runner-enabled-7037F5" alt="Harden-Runner"></a>
2930
<a href="https://github.com/nullvariant/nullvariant-vscode-extensions/blob/main/extensions/git-id-switcher/docs/DESIGN_PHILOSOPHY.md"><img src="https://img.shields.io/badge/🪨_Karesansui-Architecture-4a5568" alt="Karesansui Architecture"></a>
3031
<br>

extensions/git-id-switcher/docs/i18n/ain/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
<a href="https://codecov.io/gh/nullvariant/nullvariant-vscode-extensions"><img src="https://codecov.io/gh/nullvariant/nullvariant-vscode-extensions/graph/badge.svg" alt="codecov"></a>
4444
<a href="https://sonarcloud.io/summary/new_code?id=nullvariant_nullvariant-vscode-extensions"><img src="https://sonarcloud.io/api/project_badges/measure?project=nullvariant_nullvariant-vscode-extensions&metric=alert_status" alt="Quality Gate Status"></a>
4545
<a href="https://snyk.io/"><img src="https://img.shields.io/badge/Snyk-monitored-4C4A73?logo=snyk&logoColor=white" alt="Snyk monitored"></a>
46+
<a href="https://github.com/gitleaks/gitleaks"><img src="https://img.shields.io/badge/Gitleaks-enabled-blue?logo=git&logoColor=white" alt="Gitleaks"></a>
4647
<a href="https://github.com/step-security/harden-runner"><img src="https://img.shields.io/badge/Harden--Runner-enabled-7037F5" alt="Harden-Runner"></a>
4748
<a href="../../DESIGN_PHILOSOPHY.md"><img src="https://img.shields.io/badge/🪨_Karesansui-Architecture-4a5568" alt="Karesansui Architecture"></a>
4849
<br>

extensions/git-id-switcher/docs/i18n/bg/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
<a href="https://codecov.io/gh/nullvariant/nullvariant-vscode-extensions"><img src="https://codecov.io/gh/nullvariant/nullvariant-vscode-extensions/graph/badge.svg" alt="codecov"></a>
2222
<a href="https://sonarcloud.io/summary/new_code?id=nullvariant_nullvariant-vscode-extensions"><img src="https://sonarcloud.io/api/project_badges/measure?project=nullvariant_nullvariant-vscode-extensions&metric=alert_status" alt="Quality Gate Status"></a>
2323
<a href="https://snyk.io/"><img src="https://img.shields.io/badge/Snyk-monitored-4C4A73?logo=snyk&logoColor=white" alt="Snyk monitored"></a>
24+
<a href="https://github.com/gitleaks/gitleaks"><img src="https://img.shields.io/badge/Gitleaks-enabled-blue?logo=git&logoColor=white" alt="Gitleaks"></a>
2425
<a href="https://github.com/step-security/harden-runner"><img src="https://img.shields.io/badge/Harden--Runner-enabled-7037F5" alt="Harden-Runner"></a>
2526
<a href="../../DESIGN_PHILOSOPHY.md"><img src="https://img.shields.io/badge/🪨_Karesansui-Architecture-4a5568" alt="Karesansui Architecture"></a>
2627
<br>

0 commit comments

Comments
 (0)