From 6e73101df3f572233e339c4aad157a81edae2ee2 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Wed, 29 Apr 2026 20:06:50 -0700 Subject: [PATCH] chore(ci): widen CodeQL PR guard Runs the PR CodeQL security guard as high-confidence high/critical security coverage and adds the initial plugin/package-contract quality guard. --- .../codeql-actions-critical-security.yml | 13 ++++++ ...nel-runtime-boundary-critical-security.yml | 6 +-- ...ql-core-auth-secrets-critical-security.yml | 6 +-- ...rocess-tool-boundary-critical-security.yml | 6 +-- ...etwork-ssrf-boundary-critical-security.yml | 6 +-- ...lugin-trust-boundary-critical-security.yml | 6 +-- .github/workflows/codeql-critical-quality.yml | 42 ++++++++++++------- .github/workflows/codeql.yml | 6 +-- docs/ci.md | 30 +++++++------ 9 files changed, 69 insertions(+), 52 deletions(-) diff --git a/.github/codeql/codeql-actions-critical-security.yml b/.github/codeql/codeql-actions-critical-security.yml index bd638a6a667..341324465cd 100644 --- a/.github/codeql/codeql-actions-critical-security.yml +++ b/.github/codeql/codeql-actions-critical-security.yml @@ -1,5 +1,18 @@ name: openclaw-codeql-actions-critical-security +disable-default-queries: true + +queries: + - uses: security-extended + +query-filters: + - include: + precision: + - high + - very-high + tags contain: security + security-severity: /([7-9]|10)\.(\d)+/ + paths: - .github/actions - .github/workflows diff --git a/.github/codeql/codeql-channel-runtime-boundary-critical-security.yml b/.github/codeql/codeql-channel-runtime-boundary-critical-security.yml index 561290262a8..b8819f85bfe 100644 --- a/.github/codeql/codeql-channel-runtime-boundary-critical-security.yml +++ b/.github/codeql/codeql-channel-runtime-boundary-critical-security.yml @@ -10,10 +10,8 @@ query-filters: precision: - high - very-high - - exclude: - problem.severity: - - recommendation - - warning + tags contain: security + security-severity: /([7-9]|10)\.(\d)+/ paths: - src/channels diff --git a/.github/codeql/codeql-core-auth-secrets-critical-security.yml b/.github/codeql/codeql-core-auth-secrets-critical-security.yml index 0d74b8b2724..41909ae8348 100644 --- a/.github/codeql/codeql-core-auth-secrets-critical-security.yml +++ b/.github/codeql/codeql-core-auth-secrets-critical-security.yml @@ -10,10 +10,8 @@ query-filters: precision: - high - very-high - - exclude: - problem.severity: - - recommendation - - warning + tags contain: security + security-severity: /([7-9]|10)\.(\d)+/ paths: - src/agents/*auth*.ts diff --git a/.github/codeql/codeql-mcp-process-tool-boundary-critical-security.yml b/.github/codeql/codeql-mcp-process-tool-boundary-critical-security.yml index 14268aeaf85..1a03f820290 100644 --- a/.github/codeql/codeql-mcp-process-tool-boundary-critical-security.yml +++ b/.github/codeql/codeql-mcp-process-tool-boundary-critical-security.yml @@ -10,10 +10,8 @@ query-filters: precision: - high - very-high - - exclude: - problem.severity: - - recommendation - - warning + tags contain: security + security-severity: /([7-9]|10)\.(\d)+/ paths: - src/mcp diff --git a/.github/codeql/codeql-network-ssrf-boundary-critical-security.yml b/.github/codeql/codeql-network-ssrf-boundary-critical-security.yml index 6fdf3ba9ab1..0e5fe784a02 100644 --- a/.github/codeql/codeql-network-ssrf-boundary-critical-security.yml +++ b/.github/codeql/codeql-network-ssrf-boundary-critical-security.yml @@ -10,10 +10,8 @@ query-filters: precision: - high - very-high - - exclude: - problem.severity: - - recommendation - - warning + tags contain: security + security-severity: /([7-9]|10)\.(\d)+/ paths: - src/infra/net diff --git a/.github/codeql/codeql-plugin-trust-boundary-critical-security.yml b/.github/codeql/codeql-plugin-trust-boundary-critical-security.yml index e2b352454c1..44fb2eafcb4 100644 --- a/.github/codeql/codeql-plugin-trust-boundary-critical-security.yml +++ b/.github/codeql/codeql-plugin-trust-boundary-critical-security.yml @@ -10,10 +10,8 @@ query-filters: precision: - high - very-high - - exclude: - problem.severity: - - recommendation - - warning + tags contain: security + security-severity: /([7-9]|10)\.(\d)+/ paths: - src/cli/plugin-install-config-policy.ts diff --git a/.github/workflows/codeql-critical-quality.yml b/.github/workflows/codeql-critical-quality.yml index 3cb86b0c2f0..ae33dd42c71 100644 --- a/.github/workflows/codeql-critical-quality.yml +++ b/.github/workflows/codeql-critical-quality.yml @@ -10,16 +10,26 @@ on: type: choice options: - all + - plugin-boundary - plugin-sdk-package-contract - plugin-sdk-reply-runtime - provider-runtime-boundary - session-diagnostics-boundary + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + paths: + - ".github/codeql/**" + - ".github/workflows/codeql-critical-quality.yml" + - "packages/plugin-package-contract/**" + - "packages/plugin-sdk/**" + - "src/plugin-sdk/**" + - "src/plugins/**" schedule: - cron: "30 6 * * *" concurrency: - group: codeql-critical-quality-${{ github.workflow }}-${{ github.event_name == 'workflow_dispatch' && github.run_id || github.sha }} - cancel-in-progress: false + group: codeql-critical-quality-${{ github.workflow }}-${{ github.event_name == 'workflow_dispatch' && github.run_id || github.event_name == 'pull_request' && github.event.pull_request.number || github.sha }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} env: FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true" @@ -32,7 +42,7 @@ permissions: jobs: core-auth-secrets: name: Critical Quality (core-auth-secrets) - if: ${{ github.event_name != 'workflow_dispatch' || inputs.profile == 'all' }} + if: ${{ github.event_name != 'pull_request' && (github.event_name != 'workflow_dispatch' || inputs.profile == 'all') }} runs-on: blacksmith-4vcpu-ubuntu-2404 timeout-minutes: 25 steps: @@ -54,7 +64,7 @@ jobs: config-boundary: name: Critical Quality (config-boundary) - if: ${{ github.event_name != 'workflow_dispatch' || inputs.profile == 'all' }} + if: ${{ github.event_name != 'pull_request' && (github.event_name != 'workflow_dispatch' || inputs.profile == 'all') }} runs-on: blacksmith-4vcpu-ubuntu-2404 timeout-minutes: 25 steps: @@ -76,7 +86,7 @@ jobs: gateway-runtime-boundary: name: Critical Quality (gateway-runtime-boundary) - if: ${{ github.event_name != 'workflow_dispatch' || inputs.profile == 'all' }} + if: ${{ github.event_name != 'pull_request' && (github.event_name != 'workflow_dispatch' || inputs.profile == 'all') }} runs-on: blacksmith-4vcpu-ubuntu-2404 timeout-minutes: 25 steps: @@ -98,7 +108,7 @@ jobs: channel-runtime-boundary: name: Critical Quality (channel-runtime-boundary) - if: ${{ github.event_name != 'workflow_dispatch' || inputs.profile == 'all' }} + if: ${{ github.event_name != 'pull_request' && (github.event_name != 'workflow_dispatch' || inputs.profile == 'all') }} runs-on: blacksmith-4vcpu-ubuntu-2404 timeout-minutes: 25 steps: @@ -120,7 +130,7 @@ jobs: agent-runtime-boundary: name: Critical Quality (agent-runtime-boundary) - if: ${{ github.event_name != 'workflow_dispatch' || inputs.profile == 'all' }} + if: ${{ github.event_name != 'pull_request' && (github.event_name != 'workflow_dispatch' || inputs.profile == 'all') }} runs-on: blacksmith-4vcpu-ubuntu-2404 timeout-minutes: 25 steps: @@ -142,7 +152,7 @@ jobs: mcp-process-runtime-boundary: name: Critical Quality (mcp-process-runtime-boundary) - if: ${{ github.event_name != 'workflow_dispatch' || inputs.profile == 'all' }} + if: ${{ github.event_name != 'pull_request' && (github.event_name != 'workflow_dispatch' || inputs.profile == 'all') }} runs-on: blacksmith-4vcpu-ubuntu-2404 timeout-minutes: 25 steps: @@ -164,7 +174,7 @@ jobs: memory-runtime-boundary: name: Critical Quality (memory-runtime-boundary) - if: ${{ github.event_name != 'workflow_dispatch' || inputs.profile == 'all' }} + if: ${{ github.event_name != 'pull_request' && (github.event_name != 'workflow_dispatch' || inputs.profile == 'all') }} runs-on: blacksmith-4vcpu-ubuntu-2404 timeout-minutes: 25 steps: @@ -186,7 +196,7 @@ jobs: session-diagnostics-boundary: name: Critical Quality (session-diagnostics-boundary) - if: ${{ github.event_name != 'workflow_dispatch' || inputs.profile == 'all' || inputs.profile == 'session-diagnostics-boundary' }} + if: ${{ github.event_name != 'pull_request' && (github.event_name != 'workflow_dispatch' || inputs.profile == 'all' || inputs.profile == 'session-diagnostics-boundary') }} runs-on: blacksmith-4vcpu-ubuntu-2404 timeout-minutes: 25 steps: @@ -208,7 +218,7 @@ jobs: plugin-sdk-reply-runtime: name: Critical Quality (plugin-sdk-reply-runtime) - if: ${{ github.event_name != 'workflow_dispatch' || inputs.profile == 'all' || inputs.profile == 'plugin-sdk-reply-runtime' }} + if: ${{ github.event_name != 'pull_request' && (github.event_name != 'workflow_dispatch' || inputs.profile == 'all' || inputs.profile == 'plugin-sdk-reply-runtime') }} runs-on: blacksmith-4vcpu-ubuntu-2404 timeout-minutes: 25 steps: @@ -230,7 +240,7 @@ jobs: provider-runtime-boundary: name: Critical Quality (provider-runtime-boundary) - if: ${{ github.event_name != 'workflow_dispatch' || inputs.profile == 'all' || inputs.profile == 'provider-runtime-boundary' }} + if: ${{ github.event_name != 'pull_request' && (github.event_name != 'workflow_dispatch' || inputs.profile == 'all' || inputs.profile == 'provider-runtime-boundary') }} runs-on: blacksmith-4vcpu-ubuntu-2404 timeout-minutes: 25 steps: @@ -252,7 +262,7 @@ jobs: ui-control-plane: name: Critical Quality (ui-control-plane) - if: ${{ github.event_name != 'workflow_dispatch' || inputs.profile == 'all' }} + if: ${{ github.event_name != 'pull_request' && (github.event_name != 'workflow_dispatch' || inputs.profile == 'all') }} runs-on: blacksmith-4vcpu-ubuntu-2404 timeout-minutes: 25 steps: @@ -274,7 +284,7 @@ jobs: web-media-runtime-boundary: name: Critical Quality (web-media-runtime-boundary) - if: ${{ github.event_name != 'workflow_dispatch' || inputs.profile == 'all' }} + if: ${{ github.event_name != 'pull_request' && (github.event_name != 'workflow_dispatch' || inputs.profile == 'all') }} runs-on: blacksmith-4vcpu-ubuntu-2404 timeout-minutes: 25 steps: @@ -296,7 +306,7 @@ jobs: plugin-boundary: name: Critical Quality (plugin-boundary) - if: ${{ github.event_name != 'workflow_dispatch' || inputs.profile == 'all' }} + if: ${{ (github.event_name != 'pull_request' || !github.event.pull_request.draft) && (github.event_name == 'pull_request' || github.event_name != 'workflow_dispatch' || inputs.profile == 'all' || inputs.profile == 'plugin-boundary') }} runs-on: blacksmith-4vcpu-ubuntu-2404 timeout-minutes: 25 steps: @@ -318,7 +328,7 @@ jobs: plugin-sdk-package-contract: name: Critical Quality (plugin-sdk-package-contract) - if: ${{ github.event_name != 'workflow_dispatch' || inputs.profile == 'all' || inputs.profile == 'plugin-sdk-package-contract' }} + if: ${{ (github.event_name != 'pull_request' || !github.event.pull_request.draft) && (github.event_name == 'pull_request' || github.event_name != 'workflow_dispatch' || inputs.profile == 'all' || inputs.profile == 'plugin-sdk-package-contract') }} runs-on: blacksmith-4vcpu-ubuntu-2404 timeout-minutes: 25 steps: diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index fda7d6f7dc7..0dcb775316f 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -35,8 +35,8 @@ permissions: security-events: write jobs: - critical-security: - name: Critical Security (${{ matrix.category }}) + security-high: + name: Security High (${{ matrix.category }}) if: ${{ (github.event_name != 'pull_request' || !github.event.pull_request.draft) && (github.event_name != 'workflow_dispatch' || inputs.profile == 'all' || inputs.profile == 'security') }} runs-on: ${{ matrix.runs_on }} timeout-minutes: ${{ matrix.timeout_minutes }} @@ -89,4 +89,4 @@ jobs: - name: Analyze uses: github/codeql-action/analyze@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4 with: - category: "/codeql-critical-security/${{ matrix.category }}" + category: "/codeql-security-high/${{ matrix.category }}" diff --git a/docs/ci.md b/docs/ci.md index 48c4235586f..fd02a4bd305 100644 --- a/docs/ci.md +++ b/docs/ci.md @@ -258,30 +258,31 @@ or overlapping changed hunks. The `CodeQL` workflow is intentionally a narrow first-pass security scanner, not the full repository sweep. Daily, manual, and non-draft pull request guard runs scan Actions workflow code plus the highest-risk JavaScript/TypeScript -auth, secrets, sandbox, cron, and gateway surfaces with high-precision security -queries under the `/codeql-critical-security/core-auth-secrets` category. The +auth, secrets, sandbox, cron, and gateway surfaces with high-confidence security +queries filtered to high/critical `security-severity` under the +`/codeql-security-high/core-auth-secrets` category. The channel-runtime-boundary job separately scans core channel implementation contracts plus the channel plugin runtime, gateway, Plugin SDK, secrets, and -audit touchpoints under the `/codeql-critical-security/channel-runtime-boundary` +audit touchpoints under the `/codeql-security-high/channel-runtime-boundary` category so channel security signal can scale without broadening the baseline auth/secrets category. The network-ssrf-boundary job scans core SSRF, IP parsing, network guard, web-fetch, and Plugin SDK SSRF policy surfaces under the -`/codeql-critical-security/network-ssrf-boundary` category so network trust -boundary signal stays separate from the auth/secrets security baseline. +`/codeql-security-high/network-ssrf-boundary` category so network trust boundary +signal stays separate from the auth/secrets security baseline. The mcp-process-tool-boundary job scans MCP servers, process execution helpers, outbound delivery, and agent tool-execution gates under the -`/codeql-critical-security/mcp-process-tool-boundary` category so command and -tool boundary signal stays separate from both the auth/secrets baseline and -the non-security MCP/process quality shard. The plugin-trust-boundary job scans +`/codeql-security-high/mcp-process-tool-boundary` category so command and tool +boundary signal stays separate from both the auth/secrets baseline and the +non-security MCP/process quality shard. The plugin-trust-boundary job scans plugin install, loader, manifest, registry, runtime-dependency staging, source-loading, public-surface, and Plugin SDK package contract trust surfaces -under the `/codeql-critical-security/plugin-trust-boundary` category so plugin +under the `/codeql-security-high/plugin-trust-boundary` category so plugin supply-chain and runtime-loading signal stays separate from both bundled plugin implementation code and the non-security plugin quality shard. The pull request guard stays light: it only starts for changes under `.github/actions`, `.github/codeql`, `.github/workflows`, `packages`, or `src`, -and it runs the same critical-security matrix as the scheduled workflow. Android, -macOS, and non-security quality CodeQL stay out of PR defaults. +and it runs the same high-confidence security matrix as the scheduled workflow. +Android and macOS CodeQL stay out of PR defaults. The `CodeQL Android Critical Security` workflow is the scheduled Android security shard. It builds the Android app manually for CodeQL on the smallest @@ -297,8 +298,11 @@ default workflow because the macOS build dominates runtime even when clean. The `CodeQL Critical Quality` workflow is the matching non-security shard. It runs only error-severity, non-security JavaScript/TypeScript quality queries over narrow high-value surfaces on the smaller Blacksmith Linux runner. Its -manual dispatch accepts -`profile=all|plugin-sdk-package-contract|plugin-sdk-reply-runtime|provider-runtime-boundary|session-diagnostics-boundary`; +pull request guard is intentionally smaller than the scheduled profile: non-draft +PRs only run the `plugin-boundary` and `plugin-sdk-package-contract` shards when +plugin loader, Plugin SDK, package-contract, CodeQL config, or quality workflow +files change. Its manual dispatch accepts +`profile=all|plugin-boundary|plugin-sdk-package-contract|plugin-sdk-reply-runtime|provider-runtime-boundary|session-diagnostics-boundary`; the narrow profiles are teaching/iteration hooks for running one quality shard in isolation without dispatching the rest of the workflow. Its