From d82d2d5b409121d08e37dddf878de8db0a0c0779 Mon Sep 17 00:00:00 2001 From: Ramesh Padmanabhaiah <22363102+codeforester@users.noreply.github.com> Date: Thu, 27 Aug 2026 13:17:18 +0530 Subject: [PATCH 1/2] ci: add base-demo security scanners --- .github/workflows/tests.yml | 29 +++++++++++++++++++++++++++++ docs/contracts.md | 1 + tests/validate.sh | 17 +++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 51cd055..2e33335 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -257,6 +257,35 @@ jobs: -m unittest lib.python.base_demo_cli.tests.test_cli + security: + name: Security scanners + runs-on: ubuntu-latest + timeout-minutes: 20 + + steps: + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + + - name: Install ShellCheck + run: | + sudo apt-get update + sudo apt-get install -y shellcheck + + - name: Run Bandit + run: | + uv run --no-project --with bandit==1.9.4 \ + bandit -q -r bin lib -x '*/tests/*' --severity-level medium + + - name: Run pip-audit + run: | + uv export --locked --no-dev --no-emit-project --format requirements-txt \ + | uv run --no-project --with pip-audit==2.10.1 \ + pip-audit --cache-dir "$RUNNER_TEMP/pip-audit" -r /dev/stdin + + - name: Run ShellCheck + run: | + git ls-files -z '*.sh' 'bin/base-demo-python-info' \ + | xargs -0 shellcheck --severity=error + validate-ubuntu: runs-on: ubuntu-latest timeout-minutes: 35 diff --git a/docs/contracts.md b/docs/contracts.md index 91ff1c9..00546ad 100644 --- a/docs/contracts.md +++ b/docs/contracts.md @@ -36,6 +36,7 @@ depend on. | `compose-local-isolation` | Every published Compose port binds to loopback, Compose owns container names, and every Compose operation uses a stable checkout-and-environment project identity unless automation supplies a validated override. | `infra/compose.yaml`, `bin/base-demo-services` | `tests/infra_test.bats`, `tests/validate.sh` | Disposable credentials can become remotely reachable, or one worktree's lifecycle and log commands can target another worktree's containers. | Security | | `frontend-setup-path` | `basectl setup base-demo` installs Node 22.22.0 with bundled npm 10.9.4 through mise, and `basectl test base-demo` delegates to a mise task that runs locked `npm ci` when frontend inputs change or dependencies are absent. | `.mise.toml`, `base_manifest.yaml`, `services/demo-console/package.json`, `services/demo-console/package-lock.json` | `tests/demo_console_test.bats`, `tests/validate.sh`, Base's external base-demo E2E | A clean checkout can pass setup but fail the supported test path because Node, npm, Vite, or `node_modules` was never provisioned. | Setup | | `demo-console-build-gate` | macOS and Ubuntu CI install the locked frontend dependencies with Node 22.22.0/npm 10.9.4, compile the production console, assert entry artifacts, and fail the audit at moderate severity or higher. | `services/demo-console/package.json`, `services/demo-console/package-lock.json`, `.github/workflows/tests.yml` | `services/demo-console/build.sh`, `tests/demo_console_test.bats`, `tests/validate.sh` | Green validation can skip Vite, omit production artifacts, or retain a known dependency advisory. | CI | +| `security-scanners` | Required CI runs pinned Bandit 1.9.4 over project Python sources, pip-audit 2.10.1 against the locked uv export, and ShellCheck over tracked shell entrypoints. | `.github/workflows/tests.yml`, `pyproject.toml`, `uv.lock` | `tests/validate.sh`, GitHub Actions `security` | Shell or Python security regressions and vulnerable locked dependencies can merge without a dedicated required signal. | Security | | `ci-trigger-deduplication` | Feature-branch commits run the validation workflow through `pull_request` only, `push` validation remains enabled for `main`, superseded runs cancel only within the same PR number or ref, and the `validate`, `validate-base-cli-source`, and `validate-ubuntu` job IDs remain stable. | `.github/workflows/tests.yml` | `tests/validate.sh`, GitHub Actions | A PR commit can consume two full validation runs, unrelated branches can cancel one another, default-branch validation can disappear, or check names can drift. | CI | | `release-identity` | `VERSION` is the authoritative stable SemVer identity; Python/uv metadata, frontend package metadata, the Base-style top README badge strip and release links, and the changelog heading agree, and only an explicit matching `vX.Y.Z` tag can publish a GitHub Release. | `VERSION`, `pyproject.toml`, `uv.lock`, `services/demo-console/package.json`, `README.md`, `CHANGELOG.md`, `.github/workflows/release.yml` | `bin/base-demo-release-check`, `tests/validate.sh`, GitHub Actions | Users, automation, or release provenance can disagree about the base-demo version, the current release can be hard to discover, the project-status strip can drift, or an unreviewed branch can publish a release. | Release | | `ci-pinned-dependencies` | CI uses immutable full commits for the published Base v1.8.0 and base-bash-libs v2.0.0 contracts, plus full SHA-pinned GitHub Actions. | `.github/workflows/tests.yml` | `tests/validate.sh` | CI can drift with Base `main`, an older base-bash-libs release, or mutable action tags instead of validating the intended release capability contract. | CI | diff --git a/tests/validate.sh b/tests/validate.sh index 9143c77..e23c4e8 100755 --- a/tests/validate.sh +++ b/tests/validate.sh @@ -262,6 +262,23 @@ for job_id in ("validate", "validate-base-cli-source", "validate-ubuntu"): ) PY +security_workflow_contracts=( + ' security:' + 'name: Security scanners' + 'timeout-minutes: 20' + 'uv run --no-project --with bandit==1.9.4' + 'uv run --no-project --with pip-audit==2.10.1' + 'uv export --locked --no-dev --no-emit-project --format requirements-txt' + "git ls-files -z '*.sh' 'bin/base-demo-python-info'" + 'shellcheck --severity=error' +) +for security_contract in "${security_workflow_contracts[@]}"; do + grep -Fq "$security_contract" .github/workflows/tests.yml || { + printf '.github/workflows/tests.yml is missing security contract: %s\n' "$security_contract" >&2 + exit 1 + } +done + grep -Fq 'pull_request_target:' .github/workflows/issue-branch-policy.yml || { printf '.github/workflows/issue-branch-policy.yml does not validate pull_request_target events.\n' >&2 exit 1 From e7590e20978d7a97258b59d0d5e0bc528d3d206f Mon Sep 17 00:00:00 2001 From: Ramesh Padmanabhaiah <22363102+codeforester@users.noreply.github.com> Date: Thu, 27 Aug 2026 13:19:52 +0530 Subject: [PATCH 2/2] ci: install uv for security scanners --- .github/workflows/tests.yml | 7 +++++++ tests/validate.sh | 2 ++ 2 files changed, 9 insertions(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 2e33335..27ea748 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -265,6 +265,13 @@ jobs: steps: - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 + with: + python-version: "3.13" + + - name: Install uv + run: python -m pip install --disable-pip-version-check uv==0.12.5 + - name: Install ShellCheck run: | sudo apt-get update diff --git a/tests/validate.sh b/tests/validate.sh index e23c4e8..d3d7e33 100755 --- a/tests/validate.sh +++ b/tests/validate.sh @@ -266,6 +266,8 @@ security_workflow_contracts=( ' security:' 'name: Security scanners' 'timeout-minutes: 20' + 'actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065' + 'python -m pip install --disable-pip-version-check uv==0.12.5' 'uv run --no-project --with bandit==1.9.4' 'uv run --no-project --with pip-audit==2.10.1' 'uv export --locked --no-dev --no-emit-project --format requirements-txt'