From d4dfb9537c7e62102c842bdace7cad44973325d5 Mon Sep 17 00:00:00 2001 From: Jonathan Haas Date: Wed, 20 May 2026 20:39:53 -0700 Subject: [PATCH] ci: remove codeql control-plane workflow --- .github/workflows/codeql-guard.yml | 198 ------------------------ .github/workflows/codex-rails-check.yml | 20 +++ SECURITY.md | 21 ++- profile/GITHUB_ACTIONS_QUOTA.md | 53 ++----- profile/README.md | 2 +- 5 files changed, 48 insertions(+), 246 deletions(-) delete mode 100644 .github/workflows/codeql-guard.yml diff --git a/.github/workflows/codeql-guard.yml b/.github/workflows/codeql-guard.yml deleted file mode 100644 index 5661bf8..0000000 --- a/.github/workflows/codeql-guard.yml +++ /dev/null @@ -1,198 +0,0 @@ -name: codeql-guard - -on: - pull_request: - paths: - - ".github/workflows/**" - - ".github/workflow-templates/**" - push: - branches: [main] - paths: - - ".github/workflows/**" - - ".github/workflow-templates/**" - schedule: - # Daily org-wide drift sweep. - - cron: "17 9 * * *" - workflow_dispatch: - -permissions: - contents: read - issues: write - -jobs: - guard-self: - name: Forbid CodeQL in evalops/.github - if: ${{ github.event_name != 'schedule' }} - runs-on: ubuntu-latest - timeout-minutes: 5 - steps: - - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 - - - name: Forbid github/codeql-action references - shell: bash - run: | - set -euo pipefail - shopt -s globstar nullglob - targets=(.github/workflows .github/workflow-templates) - existing=() - for d in "${targets[@]}"; do - [ -d "$d" ] && existing+=("$d") - done - if [ "${#existing[@]}" -eq 0 ]; then - echo "no workflow directories present" - exit 0 - fi - if grep -RIn --include='*.yml' --include='*.yaml' --exclude='codeql-guard.yml' \ - 'github/codeql-action' "${existing[@]}" 2>/dev/null; then - echo "::error::EvalOps policy forbids github/codeql-action. See SECURITY.md (Code Scanning)." - exit 1 - fi - echo "ok: no codeql-action references in evalops/.github" - - guard-org: - name: Sweep evalops/* for CodeQL workflow drift - if: ${{ github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' }} - runs-on: ubuntu-latest - timeout-minutes: 15 - env: - GH_TOKEN: ${{ github.token }} - ORG_CODE_SEARCH_TOKEN: ${{ secrets.EVALOPS_ORG_READ_TOKEN }} - steps: - - name: Search org for github/codeql-action uses - shell: bash - run: | - set -euo pipefail - if [ -z "${ORG_CODE_SEARCH_TOKEN}" ]; then - echo "::error::Set secrets.EVALOPS_ORG_READ_TOKEN to a token with org-wide code search access." - exit 1 - fi - response="$( - GH_TOKEN="${ORG_CODE_SEARCH_TOKEN}" gh api -X GET search/code \ - -f q='org:evalops "uses: github/codeql-action" path:.github/workflows' \ - --jq '.items[] - | select(.repository.full_name != "evalops/.github" or .path != ".github/workflows/codeql-guard.yml") - | "\(.repository.full_name)\t\(.path)"' \ - )" - hits=() - while IFS=$'\t' read -r repo path; do - if [ -z "${repo}" ]; then - continue - fi - if [ "${repo}" = "evalops/.github" ] && [ "${path}" = ".github/workflows/codeql-guard.yml" ]; then - continue - fi - if ! content="$( - GH_TOKEN="${ORG_CODE_SEARCH_TOKEN}" gh api "repos/${repo}/contents/${path}" --jq '.content' | - base64 --decode - )"; then - echo "::warning::Could not verify ${repo}:${path}; preserving search hit." - hits+=("${repo}"$'\t'"${path}") - continue - fi - if grep -Eq '^[[:space:]]*(-[[:space:]]*)?uses:[[:space:]]*github/codeql-action([/@]|[[:space:]]|$)' <<< "${content}"; then - hits+=("${repo}"$'\t'"${path}") - else - echo "::notice::Skipping stale or non-use search hit ${repo}:${path}" - fi - done <<< "${response}" - : > /tmp/file-hits.tsv - (( ${#hits[@]} )) && printf '%s\n' "${hits[@]}" > /tmp/file-hits.tsv - if [ "${#hits[@]}" -eq 0 ]; then - echo "ok: no codeql-action workflow files found in any evalops repo" - fi - - - name: Sweep org for dynamic CodeQL default-setup workflows - shell: bash - run: | - set -euo pipefail - if [ -z "${ORG_CODE_SEARCH_TOKEN}" ]; then - echo "::error::Set secrets.EVALOPS_ORG_READ_TOKEN to a token with actions:read across the org." - exit 1 - fi - repos="$( - GH_TOKEN="${ORG_CODE_SEARCH_TOKEN}" gh api --paginate \ - '/orgs/evalops/repos?per_page=100' \ - --jq '.[] | select(.archived == false) | .name' - )" - dyn_hits=() - while IFS= read -r repo; do - [ -z "${repo}" ] && continue - wf_json="$( - GH_TOKEN="${ORG_CODE_SEARCH_TOKEN}" gh api \ - "/repos/evalops/${repo}/actions/workflows?per_page=100" 2>/dev/null || echo '{"workflows":[]}' - )" - matches="$( - jq -r '.workflows[]? - | select(.path == "dynamic/github-code-scanning/codeql" and .state == "active") - | "\(.id)"' <<< "${wf_json}" - )" - while IFS= read -r wid; do - [ -z "${wid}" ] && continue - dyn_hits+=("${repo}"$'\t'"${wid}") - done <<< "${matches}" - done <<< "${repos}" - : > /tmp/dynamic-hits.tsv - (( ${#dyn_hits[@]} )) && printf '%s\n' "${dyn_hits[@]}" > /tmp/dynamic-hits.tsv - if [ "${#dyn_hits[@]}" -eq 0 ]; then - echo "ok: no active dynamic CodeQL default-setup workflows in any evalops repo" - else - echo "::warning::Found ${#dyn_hits[@]} active dynamic CodeQL workflow(s)" - for h in "${dyn_hits[@]}"; do - echo " - ${h}" - done - fi - - - name: Aggregate findings and open tracking issue - shell: bash - run: | - set -euo pipefail - file_count=0 - dyn_count=0 - [ -s /tmp/file-hits.tsv ] && file_count="$(grep -c . /tmp/file-hits.tsv || true)" - [ -s /tmp/dynamic-hits.tsv ] && dyn_count="$(grep -c . /tmp/dynamic-hits.tsv || true)" - total=$(( file_count + dyn_count )) - if [ "${total}" -eq 0 ]; then - echo "ok: no CodeQL drift in any form" - exit 0 - fi - { - echo "## codeql-guard tripped" - echo - echo "EvalOps does not run GitHub CodeQL (see \`SECURITY.md\` and the org" - echo "code security configuration, which is now \`enforcement: enforced\`)." - echo - if [ "${file_count}" -gt 0 ]; then - echo "### Workflow files referencing \`github/codeql-action\`" - echo - while IFS=$'\t' read -r repo path; do - [ -z "${repo}" ] && continue - echo "- \`${repo}\` — \`${path}\`" - done < /tmp/file-hits.tsv - echo - fi - if [ "${dyn_count}" -gt 0 ]; then - echo "### Dynamic default-setup CodeQL workflows (active)" - echo - echo "These are installed by GitHub default code scanning, not by a file in the repo." - echo "They re-appear when GHAS or default setup is toggled. The org config has" - echo "\`code_scanning_default_setup: disabled\` and is now enforced — investigate why" - echo "these still show \`state: active\`." - echo - while IFS=$'\t' read -r repo wid; do - [ -z "${repo}" ] && continue - echo "- \`evalops/${repo}\` — workflow id \`${wid}\` at \`dynamic/github-code-scanning/codeql\`" - done < /tmp/dynamic-hits.tsv - echo - fi - } > /tmp/body.md - title="codeql-guard: CodeQL workflow drift detected" - if issue_number="$(gh issue list --repo evalops/.github --state open --search "\"${title}\" in:title" --limit 1 --json number --jq '.[0].number // empty')" && [ -n "${issue_number}" ]; then - echo "open tracking issue already exists: #${issue_number}" - gh issue comment "${issue_number}" --repo evalops/.github --body-file /tmp/body.md - else - gh issue create \ - --repo evalops/.github \ - --title "${title}" \ - --body-file /tmp/body.md - fi - exit 1 diff --git a/.github/workflows/codex-rails-check.yml b/.github/workflows/codex-rails-check.yml index a80595f..f277025 100644 --- a/.github/workflows/codex-rails-check.yml +++ b/.github/workflows/codex-rails-check.yml @@ -85,6 +85,26 @@ jobs: go run github.com/rhysd/actionlint/cmd/actionlint@v1.7.12 -shellcheck= -pyflakes= "${files[@]}" fi + - name: Reject prohibited code scanning actions + shell: bash + run: | + set -euo pipefail + shopt -s nullglob + files=(.github/workflows/*.yml .github/workflows/*.yaml .github/workflow-templates/*.yml .github/workflow-templates/*.yaml) + if [ "${#files[@]}" -eq 0 ]; then + echo "No workflow YAML files found." + exit 0 + fi + blocked_owner="github" + blocked_prefix="code" + blocked_suffix="ql-action" + blocked="${blocked_owner}/${blocked_prefix}${blocked_suffix}" + if grep -RInE "^[[:space:]]*(-[[:space:]]*)?uses:[[:space:]]*${blocked}([/@[:space:]]|$)" "${files[@]}"; then + echo "::error::EvalOps does not use GitHub default code scanning. Remove this workflow action and use bounded repo-owned checks instead." + exit 1 + fi + echo "ok: no prohibited GitHub default code-scanning action references" + - name: Validate workflow template metadata shell: bash run: | diff --git a/SECURITY.md b/SECURITY.md index 1ee3229..842cd66 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -25,21 +25,20 @@ This policy applies to all repositories in the [evalops](https://github.com/eval ## Code Scanning -EvalOps does not enable GitHub CodeQL. Every repository is attached to the -**EvalOps Blacksmith recommended** code security configuration -(`id=245233`), which sets `code_scanning_default_setup: disabled` and is the -default for new repositories. +EvalOps does not use GitHub CodeQL or GitHub default code scanning. Every +repository is attached to the **EvalOps Blacksmith recommended** code security +configuration (`id=245233`), which sets `code_scanning_default_setup: +disabled` and is the default for new repositories. -Equivalent static analysis lives elsewhere: +Security signal should come from bounded, owned checks: - `semgrep`-based custom rules in service repos (see `.semgrep/` directories and the `semgrep-custom` workflows). - Service-specific gates such as `architecture-review`, `contract-skew-check`, and `migration-check` in `evalops/platform`. -- The [`codeql-guard`](.github/workflows/codeql-guard.yml) workflow in this - repo enforces the policy: it rejects PRs that introduce - `github/codeql-action` here, and it sweeps every `evalops/*` repo daily, - opening an issue if a CodeQL workflow file appears anywhere in the org. +- Secret scanning, Dependabot, and targeted repository-owned analyzers with + explicit owners and runtime budgets. -To request a policy change, open a PR against this file and the guard -workflow. +Do not add CodeQL workflows, generated default-setup workflows, or required +checks backed by blanket code scanning. To request a policy change, open a PR +against this file and the engineering-practices contract. diff --git a/profile/GITHUB_ACTIONS_QUOTA.md b/profile/GITHUB_ACTIONS_QUOTA.md index ded6bf7..d0f3452 100644 --- a/profile/GITHUB_ACTIONS_QUOTA.md +++ b/profile/GITHUB_ACTIONS_QUOTA.md @@ -3,42 +3,23 @@ EvalOps repositories should keep CI evidence useful without letting GitHub Actions minute or artifact quotas block unrelated pull requests. -## CodeQL - -Run CodeQL on `main`, on a weekly schedule, and through manual dispatch. For -pull requests, scope CodeQL with `paths` so documentation, GitOps metadata, and -workflow-only changes do not spend full multi-language analysis capacity. - -Recommended PR path set: - -```yaml -on: - pull_request: - paths: - - ".github/workflows/codeql.yml" - - "go.mod" - - "go.sum" - - "**/*.go" - - "package.json" - - "package-lock.json" - - "pnpm-lock.yaml" - - "yarn.lock" - - "bun.lock" - - "bun.lockb" - - "**/*.js" - - "**/*.jsx" - - "**/*.mjs" - - "**/*.cjs" - - "**/*.ts" - - "**/*.tsx" - - "pyproject.toml" - - "poetry.lock" - - "requirements*.txt" - - "**/*.py" -``` - -Keep the checked-in CodeQL workflow explicit. Do not rely on generated CodeQL -runs when runner placement, matrix languages, or branch behavior matter. +## Blanket Static Analysis + +Do not add CodeQL or GitHub default code-scanning workflows. EvalOps does not +use them, and they should not become required checks, scheduled jobs, or +generated default-setup runs. + +Security checks need an owner and a runtime budget before they belong in CI. +Prefer narrow repository-owned checks that answer a concrete question: + +- Semgrep custom rules for known repo-local failure modes. +- Contract, migration, schema, and architecture checks with small inputs. +- Secret scanning and Dependabot alerts handled through the security SLO. +- One-shot diagnostic scripts that are not required merge gates unless the + signal is high-yield and fast. + +When a scanner is slow, noisy, or ownerless, remove it instead of tuning the +required status list around it. ## Artifacts diff --git a/profile/README.md b/profile/README.md index 05c839e..c8a0329 100644 --- a/profile/README.md +++ b/profile/README.md @@ -5,7 +5,7 @@ The organizational operating system for AI agent workforces — evaluation, gove ## Operating Conventions - [Agent authorship attribution](AGENT_AUTHORSHIP.md) — git trailers, PR labels, and audit indexing for Maestro-authored code. -- [GitHub Actions quota hygiene](GITHUB_ACTIONS_QUOTA.md) — CodeQL scoping, artifact retention, and quota-safe diagnostics. +- [GitHub Actions quota hygiene](GITHUB_ACTIONS_QUOTA.md) — scanner budget, artifact retention, and quota-safe diagnostics. - [Engineering practices](ENGINEERING_PRACTICES.md) — tiered merge policy, backlog lifecycle, release trains, security SLOs, and evidence-first completion. ## Platform Services