Compare commits

...

1 Commits

Author SHA1 Message Date
CI Bot a248883c8e feat(ci): 集成gitleaks + pip-audit + vulture安全扫描到Validate阶段
CI/CD Pipeline / Unit Tests (pull_request) Successful in 1m13s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 1m13s
CI/CD Pipeline / Validate Code Quality And Tests (pull_request) Successful in 9m35s
CI/CD Pipeline / Build & Push Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Build Production Runtime Images (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
CI/CD Pipeline / Integration Tests (pull_request) Successful in 2m26s
- gitleaks: 密钥检测(P0,阻断模式)
  - PR模式:增量扫描
  - Push模式:全量扫描
  - 双源下载(GitHub + Gitee镜像),失败优雅降级
- pip-audit: 依赖漏洞扫描(P1,告警模式,不阻断)
  - 扫描所有requirements文件
- vulture: 死代码检测(P2,告警模式,不阻断)
  - 置信度80%
  - 排除tests/migrations/scripts等
  - 框架代码白名单
2026-07-14 11:35:42 +08:00
4 changed files with 236 additions and 1 deletions
+92 -1
View File
@@ -101,6 +101,53 @@ jobs:
bandit --version
pytest --version
- name: Secret detection (gitleaks)
shell: sh
run: |
set -eu
echo "=== Installing gitleaks ==="
# 优先尝试 GitHub release,失败则用国内镜像
GITLEAKS_VERSION="8.18.4"
install_gitleaks() {
local url="$1"
curl -sSL -f -o /tmp/gitleaks.tar.gz "$url" || return 1
tar -xzf /tmp/gitleaks.tar.gz -C /tmp gitleaks || return 1
chmod +x /tmp/gitleaks || return 1
/tmp/gitleaks version || return 1
return 0
}
if ! install_gitleaks "https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}/gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz"; then
echo "GitHub release failed, trying mirror..."
if ! install_gitleaks "https://gitee.com/mirrors/gitleaks/releases/download/v${GITLEAKS_VERSION}/gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz"; then
echo "WARN: Failed to install gitleaks from all sources, skipping secret scan"
exit 0
fi
fi
echo ""
echo "=== Running gitleaks scan ==="
if [ "${{ github.event_name }}" = "pull_request" ]; then
# PR触发: 增量扫描
echo "PR mode: scanning changed files"
EXIT_CODE=0
/tmp/gitleaks detect --source . --config .gitleaks.toml --verbose --exit-code 1 --log-opts="origin/${{ github.base_ref }}..HEAD" || EXIT_CODE=$?
if [ "$EXIT_CODE" = "1" ]; then
echo "ERROR: Secrets detected! Check the scan report above."
echo "If these are false positives, add them to .gitleaks.toml allowlist."
exit 1
fi
else
# Push触发: 全量扫描
echo "Push mode: full repository scan"
EXIT_CODE=0
/tmp/gitleaks detect --source . --config .gitleaks.toml --verbose --exit-code 1 || EXIT_CODE=$?
if [ "$EXIT_CODE" = "1" ]; then
echo "ERROR: Secrets detected! Check the scan report above."
echo "If these are false positives, add them to .gitleaks.toml allowlist."
exit 1
fi
fi
echo "gitleaks scan completed - no secrets detected"
- name: Run code quality checks
shell: sh
run: |
@@ -110,12 +157,56 @@ jobs:
python3 -m isort --check-only alembic apps packages tests scripts
python3 -m flake8 apps packages tests --count --statistics
- name: Run security scan
- name: Run security scan (bandit)
shell: sh
run: |
set -eu
bandit -r apps packages -q -ll
- name: Python dependency vulnerability scan (pip-audit)
shell: sh
run: |
set -eu
echo "=== Installing pip-audit ==="
python3 -m pip install -q pip-audit
pip-audit --version
echo ""
echo "=== Scanning Python dependencies ==="
EXIT_CODE=0
for req_file in requirements.txt requirements-base.txt requirements-dev.txt; do
if [ -f "$req_file" ]; then
echo "--- Scanning $req_file ---"
pip-audit -r "$req_file" --desc on --format text 2>&1 | head -30 || EXIT_CODE=$?
echo ""
fi
done
# 告警模式,不阻断CI(待稳定后再考虑改为阻断)
echo "pip-audit scan completed (advisory mode - warnings only, not blocking CI)"
if [ "$EXIT_CODE" != "0" ]; then
echo "WARNING: Potential vulnerabilities found in dependencies."
fi
exit 0
- name: Dead code detection (vulture)
shell: sh
run: |
set -eu
echo "=== Installing vulture ==="
python3 -m pip install -q vulture
vulture --version
echo ""
echo "=== Running vulture dead code scan ==="
# 告警模式,不阻断CI(P2级别,仅供参考)
EXIT_CODE=0
vulture --config vulture.conf vulture_whitelist.py || EXIT_CODE=$?
echo ""
echo "vulture scan completed (advisory mode - P2, for reference only)"
if [ "$EXIT_CODE" != "0" ]; then
echo "NOTE: Potential dead code found. Review results above."
echo "False positives can be added to vulture_whitelist.py"
fi
exit 0
- name: Validate release scripts syntax
shell: sh
run: |
+52
View File
@@ -0,0 +1,52 @@
# .gitleaks.toml - gitleaks 白名单配置
# 仓库: xiaoxia/xiaoxia-saas
# 用途: 排除已知的测试密钥、示例配置等误报
# 允许路径/文件排除
[allowlist]
description = "全局白名单 - 排除示例配置和测试文件"
paths = [
# 环境配置示例(无真实密钥)
'.env.example',
'.env.sample',
'*.env.example',
'*.env.sample',
# 测试文件
'tests/',
'test/',
'*/tests/',
'*/test/',
# 文档
'docs/',
'*.md',
'*.rst',
# 前端依赖
'node_modules/',
# Python包
'site-packages/',
# 锁定文件(自动生成)
'poetry.lock',
'Pipfile.lock',
'requirements*.txt.lock',
# CI配置本身
'.gitea/',
# Docker相关
'docker-compose*.yml',
# gitleaks配置自身
'.gitleaks.toml',
]
# 允许的密钥值/占位符正则
regexes = [
# 占位符模式
'''(?i)(your[_-]?password|your[_-]?secret|your[_-]?key|your[_-]?token|changeme|change[_-]?me|placeholder|example[_-]?key|test[_-]?key|dummy|fake|mock|xxx|none|not[_-]?set|TODO|FIXME)''',
# 数据库连接字符串中的通用密码(PostgreSQL示例配置)
'''postgresql://[^:]+:changeme@''',
'''postgresql://[^:]+:your-password@''',
'''postgresql://[^:]+:password@localhost''',
# Redis示例配置
'''redis://:changeme@''',
'''redis://:your-redis-password@''',
# JWT示例密钥
'''(?i)jwt[_-]?secret\s*[:=]\s*["']?(your[_-]?jwt|change|placeholder|secret|example)''',
]
+35
View File
@@ -0,0 +1,35 @@
# vulture.conf - 死代码检测配置
# 仓库: xiaoxia/xiaoxia-saas
# 用途: 检测未使用的函数、变量、导入、类、方法、属性
# 扫描目录(空格分隔)
path = alembic apps packages scripts
# 排除路径(每个路径一行,相对于仓库根目录)
exclude =
tests
test
*/tests
*/test
site-packages
node_modules
migrations
.gitea
docs
scripts/check_*.py
scripts/init_*.py
# 最低置信度 (%)
# 0 = 报告所有可能的未使用代码
# 100 = 只报告确定未使用的代码
# 推荐从 80% 开始,逐步调高
min-confidence = 80
# 输出格式: string, json, yaml
format = text
# 按置信度排序
sort-by-size = False
# 显示置信度
show-uncertain = True
+57
View File
@@ -0,0 +1,57 @@
# vulture_whitelist.py - vulture 白名单文件
# 用途: 列出已知被框架/动态调用的代码,避免误报
# 参考: https://vulture.readthedocs.io/en/stable/whitelists.html
# FastAPI / Starlette 框架自动调用
# FastAPI route handlers (通过装饰器注册,vulture 可能无法识别)
apps.*.main.*
apps.*.api.*
apps.*.routes.*
apps.*.views.*
# SQLAlchemy ORM
# Model 类和字段通过 ORM 框架自动使用
apps.*.models.*
apps.*.schemas.*
packages.*.models.*
# Pydantic models
# Pydantic 字段通过序列化/反序列化使用
apps.*.schemas.*
packages.*.schemas.*
# Alembic migrations
# Migration 函数由 alembic 自动调用
alembic.versions.*.upgrade
alembic.versions.*.downgrade
# Celery tasks
# Task 函数通过 celery worker 调用
apps.*.tasks.*
packages.*.tasks.*
# CLI scripts / entry points
# 脚本通过命令行调用
scripts.*
# 中间件
apps.*.middleware.*
packages.*.middleware.*
# 异常类
apps.*.exceptions.*
packages.*.exceptions.*
# 配置类
apps.*.config.*
packages.*.config.*
# 工具函数(可能被多处间接调用,先白名单,后续清理)
apps.*.utils.*
packages.*.utils.*
apps.*.helpers.*
packages.*.helpers.*
# Dependencies (FastAPI Depends)
apps.*.dependencies.*
packages.*.dependencies.*