fix: reject empty HMAC keys in audit sign/verify #460
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| push: | |
| branches: [ main, master, develop ] | |
| pull_request: | |
| branches: [ main, master, develop ] | |
| jobs: | |
| repo-policy: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Set up Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.11" | |
| - name: Enforce repo file policy | |
| run: | | |
| python scripts/release/check_repo_policy.py | |
| - name: Enforce dependency license policy | |
| run: | | |
| python scripts/release/check_license_policy.py | |
| lint: | |
| needs: repo-policy | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Set up Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.11" | |
| - name: Cache pip packages | |
| uses: actions/cache@v5 | |
| with: | |
| path: ~/.cache/pip | |
| key: ${{ runner.os }}-pip-lint-${{ hashFiles('**/pyproject.toml') }} | |
| restore-keys: | | |
| ${{ runner.os }}-pip-lint- | |
| ${{ runner.os }}-pip- | |
| - name: Install lint dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -e ".[dev]" | |
| - name: Lint with Ruff | |
| run: | | |
| ruff check --output-format=github . | |
| - name: Check Ruff formatting | |
| run: | | |
| ruff format --check . | |
| test: | |
| needs: [repo-policy, lint] | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| matrix: | |
| os: [ubuntu-latest, windows-latest, macos-latest] | |
| python-version: ["3.10", "3.11", "3.12"] | |
| exclude: | |
| # Exclude some combinations to reduce CI time | |
| - os: windows-latest | |
| python-version: "3.10" | |
| - os: macos-latest | |
| python-version: "3.10" | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Set up Python ${{ matrix.python-version }} | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| - name: Cache pip packages | |
| uses: actions/cache@v5 | |
| with: | |
| path: ~/.cache/pip | |
| key: ${{ runner.os }}-pip-${{ hashFiles('**/pyproject.toml') }} | |
| restore-keys: | | |
| ${{ runner.os }}-pip- | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -e ".[dev]" | |
| - name: Test with pytest | |
| run: | | |
| pytest --cov=openmed --cov-report=xml --cov-report=term-missing | |
| - name: Upload coverage to Codecov | |
| uses: codecov/codecov-action@v7 | |
| with: | |
| files: ./coverage.xml | |
| flags: unittests | |
| name: codecov-umbrella | |
| fail_ci_if_error: false | |
| security: | |
| needs: repo-policy | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Set up Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.11" | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -e ".[dev]" | |
| pip install bandit[toml] pip-audit | |
| - name: Run Bandit report | |
| run: | | |
| bandit -r openmed -f json -o bandit-report.json --exit-zero | |
| - name: Enforce high-severity Bandit findings | |
| run: | | |
| bandit -r openmed --severity-level high --confidence-level medium | |
| - name: Run pip-audit dependency gate | |
| run: | | |
| python scripts/security/pip_audit_gate.py | |
| - name: Upload security reports | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: security-reports | |
| path: | | |
| bandit-report.json | |
| pip-audit-report.json | |
| if: always() | |
| secret-scan: | |
| needs: repo-policy | |
| runs-on: ubuntu-latest | |
| env: | |
| GITLEAKS_VERSION: "8.30.1" | |
| GITLEAKS_LINUX_X64_SHA256: "551f6fc83ea457d62a0d98237cbad105af8d557003051f41f3e7ca7b3f2470eb" | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Install gitleaks | |
| run: | | |
| archive="/tmp/gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz" | |
| curl -sSfL \ | |
| "https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}/gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz" \ | |
| -o "$archive" | |
| echo "${GITLEAKS_LINUX_X64_SHA256} $archive" | sha256sum -c - | |
| tar -xzf "$archive" -C /tmp gitleaks | |
| sudo install -m 0755 /tmp/gitleaks /usr/local/bin/gitleaks | |
| gitleaks version | |
| - name: Verify secret scanner canary | |
| run: | | |
| canary_dir="$(mktemp -d)" | |
| cp tests/fixtures/secret_scan_canary.txt "$canary_dir/canary.txt" | |
| set +e | |
| gitleaks dir \ | |
| --config .gitleaks.toml \ | |
| --redact \ | |
| --no-banner \ | |
| --report-format json \ | |
| --report-path "$RUNNER_TEMP/gitleaks-canary.json" \ | |
| "$canary_dir" | |
| canary_status=$? | |
| set -e | |
| if [ "$canary_status" -eq 0 ]; then | |
| echo "::error title=Secret scanner canary was not detected::Expected the synthetic canary to fail outside its allowlisted fixture path" | |
| exit 1 | |
| fi | |
| if [ "$canary_status" -ne 1 ]; then | |
| echo "::error title=Secret scanner canary failed unexpectedly::Scanner exited with status $canary_status" | |
| exit "$canary_status" | |
| fi | |
| - name: Scan committed changes for secrets | |
| env: | |
| EVENT_NAME: ${{ github.event_name }} | |
| PR_BASE_SHA: ${{ github.event.pull_request.base.sha }} | |
| PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }} | |
| PUSH_BEFORE_SHA: ${{ github.event.before }} | |
| run: | | |
| zero_sha="0000000000000000000000000000000000000000" | |
| if [ "$EVENT_NAME" = "pull_request" ]; then | |
| scan_range="${PR_BASE_SHA}..${PR_HEAD_SHA}" | |
| elif [ -n "$PUSH_BEFORE_SHA" ] && [ "$PUSH_BEFORE_SHA" != "$zero_sha" ]; then | |
| scan_range="${PUSH_BEFORE_SHA}..${GITHUB_SHA}" | |
| else | |
| scan_range="${GITHUB_SHA}^..${GITHUB_SHA}" | |
| fi | |
| gitleaks git \ | |
| --config .gitleaks.toml \ | |
| --redact \ | |
| --no-banner \ | |
| --verbose \ | |
| --log-opts "$scan_range" \ | |
| . | |
| build: | |
| needs: [repo-policy, lint, test, security, secret-scan] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Set up Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.11" | |
| - name: Install build dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install build | |
| - name: Build package | |
| run: | | |
| python -m build | |
| - name: Upload build artifacts | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: dist-packages | |
| path: dist/ |