ci: wire no-infra-g1 into CI (caller half) - #6009
Conversation
Caller for the ci-no-infra-g1.yml reusable workflow. no-infra-g1 was the
only group flagged NEW by lint_group_coverage.py -- its five tests have
never run in CI, including reg_test_5363_admin_monitor_caching_sha2-t, the
regression test for the Admin/Monitor caching_sha2 work.
After this pair lands the lint reports:
group coverage lint: 94 groups | phantom-infra=0 | missing-workflow NEW=0 known=41
infras.lst for the group is empty, so no backend containers start; the group
costs ~73s locally.
Requires the callee at ci-no-infra-g1.yml@GH-Actions to be merged first,
otherwise this caller resolves to a missing workflow.
📝 WalkthroughWalkthroughThe pull request adds the ChangesCI workflow orchestration
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/CI-no-infra-g1.yml:
- Line 24: Update the reusable workflow reference in the CI workflow to replace
the mutable GH-Actions branch with the reviewed immutable commit SHA from that
branch, preserving the existing called workflow path.
- Line 25: Replace secrets: inherit in the reusable workflow invocation with an
explicit named-secrets mapping, passing only the GITHUB_TOKEN and secrets
declared by the called workflow; preserve the existing workflow permissions and
other invocation settings.
- Line 16: Update the workflow_run job condition near the existing conclusion
check to require that github.event.workflow_run.head_repository.full_name
matches github.repository, while preserving the current
success-or-no-workflow_run behavior. Ensure fork-derived runs are rejected
before the privileged callee is invoked.
- Around line 17-23: Replace the broad permissions setting in the caller
workflow with an explicit minimal permissions map, retaining id-token: write and
adding only scopes required by the called jobs; update the corresponding
permissions declaration in the reusable ci-<group>.yml workflow to the same
least-privilege set so checkout, Codecov, and other actions receive only
necessary access.
- Around line 10-12: Update the concurrency group in the workflow’s concurrency
configuration to use a callee-specific key, such as a workflow name with a
callee prefix and github.run_id, instead of the caller-derived branch/ref
expression. Keep cancel-in-progress enabled while ensuring reusable workflow
runs cannot share or cancel the caller’s group.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: bad58f60-2cbc-4e37-9678-66377034ce40
📒 Files selected for processing (1)
.github/workflows/CI-no-infra-g1.yml
📜 Review details
🧰 Additional context used
🪛 zizmor (1.29.0)
.github/workflows/CI-no-infra-g1.yml
[error] 23-23: overly broad permissions (excessive-permissions): uses write-all permissions
(excessive-permissions)
[error] 4-8: use of fundamentally insecure workflow trigger (dangerous-triggers): workflow_run is almost always used insecurely
(dangerous-triggers)
[warning] 24-24: secrets unconditionally inherited by called workflow (secrets-inherit): this reusable workflow
(secrets-inherit)
🔇 Additional comments (2)
.github/workflows/CI-no-infra-g1.yml (2)
1-2: LGTM!
26-27: 🗄️ Data Integrity & IntegrationVerify the callee contract and minimize the shared
githubpayload.Line [27] passes the full
githubcontext string to.github/workflows/ci-<callee>.yml@GH-Actions. If the callee declares a reusableworkflow_call.triggerstring input, ensure it applies the same parsing/validation forworkflow_dispatchandworkflow_runevents. Treat branch names, commit messages, and PR fields as untrusted, and pass only the fields the callee needs to avoid exposing unfilteredgithub.contextdata across the reusable workflow boundary.
| concurrency: | ||
| group: ${{ github.workflow }}-${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }} | ||
| cancel-in-progress: true |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
callee=.github/workflows/ci-no-infra-g1.yml
git show "GH-Actions:$callee" |
rg -n -C 5 'concurrency|cancel-in-progress|github.workflow|ref_name|head_branch' || trueRepository: sysown/proxysql
Length of output: 194
🏁 Script executed:
#!/bin/bash
set -u
echo "--- available workflow files ---"
git ls-files '.github/workflows/*' | sed -n '1,120p'
echo "--- matching filenames ---"
git ls-files '.github/workflows/*' | rg -i 'ci-no-infra-g1|call|callable|caller|trigger' || true
echo "--- current file excerpt (if present) ---"
if [ -f .github/workflows/CI-no-infa-g1.yml ]; then
cat -n .github/workflows/CI-no-infa-g1.yml | sed -n '1,80p'
elif [ -f .github/workflows/CI-no-infra-g1.yml ]; then
cat -n .github/workflows/CI-no-infra-g1.yml | sed -n '1,80p'
fi
echo "--- workflow_run and reusable usages ---"
rg -n "workflow_run|uses:|concurrency:|cancel-in-progress|ref_name|head_branch|github.workflow" .github/workflows || trueRepository: sysown/proxysql
Length of output: 50372
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "--- call-target metadata files ---"
git ls-files '.github/workflows/ci-no-infra-g1.yml'
echo "--- ci-no-infra-g1.yml excerpt (current) ---"
if [ -f .github/workflows/ci-no-infra-g1.yml ]; then
cat -n .github/workflows/ci-no-infra-g1.yml | sed -n '1,120p'
fi
echo "--- ci-no-infra-g1.yml remote references ---"
git ls-remote https://github.com/sysown/proxysql refs/tags/GH-Actions --symref 2>/dev/null || true
git ls-remote https://github.com/sysown/proxysql refs/heads/GH-Actions --symref 2>/dev/null || true
echo "--- caller and callable concurrency groups for CI-no-infra-g1 ---"
python3 - <<'PY'
import json, pathlib, re
callers = [p for p in pathlib.Path('.github/workflows').glob('CI-no-infra-g1.yml') if p.name == 'CI-no-infra-g1.yml']
for caller in callers:
text = caller.read_text()
print(f'CALLER {caller}')
for m in re.finditer(r'(^[\s]{0,2}uses:\s*sysown\/proxysql\.github\.workflows\/[\S]+(?:@[\S]+)?|^\s*concurrency:|^\s{2,4}group:\s*|^\s{4,6}cancel-in-progress:\s*)', text, re.M):
line = text.count('\n', 0, m.start()) + 1
print(f'{line}: {m.group(0).strip()}')
# Read only remote Git references (not repo code).
import subprocess
for ref in ['refs/tags/GH-Actions', 'refs/heads/GH-Actions']:
out = subprocess.run(['git','ls-remote','https://github.com/sysown/proxysql', ref], text=True, capture_output=True)
print(f'REMOTE {ref}: {out.stdout.strip() if out.returncode == 0 else f'ERR {out.returncode}: {out.stderr.strip()}'}')
PYRepository: sysown/proxysql
Length of output: 671
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "--- fetch ci-no-infra-g1.yml from GH-Actions ---"
url="https://raw.githubusercontent.com/sysown/proxysql/GH-Actions/.github/workflows/ci-no-infra-g1.yml"
python3 - <<'PY'
import urllib.request
url = "https://raw.githubusercontent.com/sysown/proxysql/GH-Actions/.github/workflows/ci-no-infra-g1.yml"
try:
data = urllib.request.urlopen(url, timeout=20).read().decode()
print(data)
except Exception as e:
print(type(e).__name__, e)
PY
echo "--- fetch remote commits from GH-Actions for relevant workflows ---"
python3 - <<'PY'
import urllib.request, urllib.error
sha = "GH-Actions"
url = f"https://raw.githubusercontent.com/sysown/proxysql/{sha}/.github/workflows/ci-no-infra-g1.yml"
try:
data = urllib.request.urlopen(url, timeout=20).read().decode()
except urllib.error.HTTPError as e:
print("fetch_error", e.code, e.url, str(e.reason)[:200])
else:
print("fetched", url, len(data))
PY
echo "--- parse caller concurrency with simple Python ---"
python3 - <<'PY'
import pathlib, re
caller = pathlib.Path(".github/workflows/CI-no-infra-g1.yml")
text = caller.read_text()
print("caller", caller, "exists", caller.exists())
for m in re.finditer(r'(^[\s]{0,2}uses:\s*sysown\/proxysql\.github\.workflows\/[\S]+(?:@[\S]+)?|^\s*concurrency:|^\s{2,4}group:\s*|^\s{4,6}cancel-in-progress:\s*)', text, re.M):
line = text.count('\n', 0, m.start()) + 1
print(f'{line}: {m.group(0).strip()}')
PYRepository: sysown/proxysql
Length of output: 2700
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "--- list remote ref GH-Actions metadata ---"
git ls-remote --symref https://github.com/sysown/proxysql refs/heads/GH-Actions refs/tags/GH-Actions
echo "--- find ci-no-infra-g1.yml in remote archive ---"
git ls-tree --name-only -r "GH-Actions" ".github/workflows" | rg -n '(^|[[:space:]])ci-no-infra-g1\.yml$' || true
echo "--- stream selected file from remote repository archive ---"
git show "GH-Actions:.github/workflows/ci-no-infra-g1.yml" 2>/dev/null | sed -n '1,120p'
echo "--- parser comparison for caller and callee concurrency groups ---"
python3 - <<'PY'
import re, pathlib, subprocess
def extract_concurrency(path):
data = subprocess.check_output(["git", "show", f"GH-Actions:{path}"], text=True)
out = {}
in_conc = False
for i, line in enumerate(data.splitlines(), 1):
if re.match(r'^\s*concurrency:', line):
in_conc = True
out["concurrency"] = i
continue
if not in_conc:
continue
m_conc = re.match(r'^\s+group:\s*(.+)', line)
m_cancel = re.match(r'^\s+cancel-in-progress:\s*(.+)', line)
if m_conc:
out["group_value"] = m_conc.group(1).strip()
if m_cancel:
out["cancel"] = m_cancel.group(1).strip()
break
return out
caller = extract_concurrency(".github/workflows/CI-no-infra-g1.yml")
callee = extract_concurrency(".github/workflows/ci-no-infra-g1.yml")
print("caller", caller)
print("callee", callee)
print("caller group equals callee group:", caller.get("group_value") == callee.get("group_value"))
print("both disable cancellations:", caller.get("cancel") == "false" and callee.get("cancel") == "false")
PYRepository: sysown/proxysql
Length of output: 416
🌐 Web query:
GitHub Actions reusable workflows reusable workflow configurations matching caller and callee concurrency groups cancel caller
💡 Result:
In GitHub Actions, using concurrency groups across caller and reusable (callee) workflows requires caution because ${{ github.workflow }} in a called workflow resolves to the name of the caller workflow, not the reusable workflow itself [1][2]. If both the caller and the callee use the same concurrency group name derived from ${{ github.workflow }}, they may inadvertently target the same group, causing the caller to cancel itself when the callee runs, or causing callees to cancel each other [1][3][2]. To manage concurrency correctly and avoid unwanted cancellations: 1. Avoid ${{ github.workflow }} in reusable workflows: Since the callee inherits the caller's workflow name, using ${{ github.workflow }} as part of a concurrency group key in both locations creates a collision [1][2][4]. 2. Use unique, hardcoded identifiers: To distinguish between caller and callee or prevent collisions between multiple reusable workflows, use distinct, hardcoded prefixes or identifiers within the concurrency group strings [2][4]. For example, use group: caller-name-${{ github.ref }} in the caller and group: callee-name-${{ github.run_id }} or a specific prefix in the callee [2]. 3. Understanding cancel-in-progress: If cancel-in-progress: true is set, any workflow or job already running in the same concurrency group will be cancelled when a new run in that group starts [5][6]. If a caller and callee share a group, the act of starting the callee can trigger the cancellation of the caller [1][3]. 4. Context availability: Note that ${{ github.run_id }} is unique to each individual workflow run, making it a reliable way to isolate concurrency groups if you want to avoid collisions entirely between concurrent executions [2]. In summary, GitHub explicitly advises against using the same concurrency group value for both caller and called workflows if cancel-in-progress: true is enabled, as the shared context causes the caller to be cancelled by its own called workflow [1]. Always use unique, explicit group identifiers in the callee to prevent this inheritance-related conflict [2][4].
Citations:
- 1: https://docs.github.com/en/actions/reference/workflows-and-actions/reusing-workflow-configurations
- 2: safe-outputs.call-workflow workers cancel each other under parallel fan-out due to gh-aw-copilot-${{ github.workflow }} job concurrency group' github/gh-aw#35161
- 3: https://github.com/kentomk/gha-concurrency-cycle
- 4: wysaid/cge-tools@7e5746d
- 5: https://docs.github.com/en/actions/how-tos/write-workflows/choose-when-workflows-run/control-workflow-concurrency
- 6: https://docs.github.com/actions/writing-workflows/choosing-what-your-workflow-does/control-the-concurrency-of-workflows-and-jobs
Use distinct concurrency groups for caller and callee.
The caller uses group: ${{ github.workflow }}-${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }} with cancel-in-progress: true; avoid the reusable workflow using the same caller-derived group. This can cancel the caller run when the callee starts; use a unique callee-prefixed key such as ${{ github.workflow }}-callee-${{ github.run_id }}.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/CI-no-infra-g1.yml around lines 10 - 12, Update the
concurrency group in the workflow’s concurrency configuration to use a
callee-specific key, such as a workflow name with a callee prefix and
github.run_id, instead of the caller-derived branch/ref expression. Keep
cancel-in-progress enabled while ensuring reusable workflow runs cannot share or
cancel the caller’s group.
|
|
||
| jobs: | ||
| run: | ||
| if: ${{ github.event.workflow_run && github.event.workflow_run.conclusion == 'success' || ! github.event.workflow_run }} |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
: "${REPO:?Set REPO=OWNER/REPO}"
gh api --paginate \
"repos/${REPO}/actions/workflows/CI-trigger.yml/runs?event=pull_request&per_page=100" \
--jq '.workflow_runs[]
| select(.head_repository != null and .head_repository.full_name != .repository.full_name)
| [.id, .conclusion, .head_repository.full_name, .repository.full_name]
| `@tsv`'Repository: sysown/proxysql
Length of output: 193
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
printf 'Repo: %s\n' "${GITHUB_REPOSITORY:-<GITHUB_REPOSITORY not set>}"
printf '\nRelevant workflow files:\n'
git ls-files '.github/workflows/CI*.yml' '.github/workflows/CI*.yaml' | sed -n '1,50p'
printf '\nCI-trigger.yml contents:\n'
if [ -f .github/workflows/CI-trigger.yml ]; then
cat -n .github/workflows/CI-trigger.yml | sed -n '1,220p'
fi
printf '\nCI-no-infra-g1.yml relevant contents:\n'
if [ -f .github/workflows/CI-no-infra-g1.yml ]; then
cat -n .github/workflows/CI-no-infra-g1.yml | sed -n '1,220p'
fi
printf '\nSearch for reusable workflow references and workflow_run conditions:\n'
rg -n "uses:|workflow_run|github.repository|head_repository|conclusion" .github/workflows || trueRepository: sysown/proxysql
Length of output: 50372
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
printf 'Repository: %s\n' "${GITHUB_REPOSITORY:-<GITHUB_REPOSITORY not set>}"
printf '\nCI-trigger.yml relevant contents:\n'
cat -n .github/workflows/CI-trigger.yml | sed -n '1,240p'
printf '\nCI-no-infra-g1.yml relevant contents:\n'
cat -n .github/workflows/CI-no-infra-g1.yml | sed -n '1,220p'
printf '\nOther workflow_run runners with same condition pattern:\n'
python3 - <<'PY'
import pathlib
for p in pathlib.Path('.github/workflows').glob('CI*'):
text = p.read_text()
if 'workflow_run.conclusion == \'success\' || ! github.event.workflow_run' in text:
print(p)
for i, line in enumerate(text.splitlines(), 1), None:
print(f' line {line}')
PYRepository: sysown/proxysql
Length of output: 2787
🌐 Web query:
GitHub Actions workflow_run event skipped conclusion head_repository.full_name
💡 Result:
When using the workflow_run event in GitHub Actions, you can access the conclusion and repository details of the triggering workflow via the github.event.workflow_run context [1][2][3][4]. Key points regarding your query: Conclusion and Skipped Status: The workflow_run event triggers regardless of whether the previous workflow passed, failed, or was skipped [2]. If your workflow is being skipped unexpectedly, it is often due to an if conditional in your workflow file that explicitly checks for a specific conclusion (e.g., if: ${{ github.event.workflow_run.conclusion == 'success' }}) [1]. To have your workflow run regardless of the outcome, ensure any such conditional is either removed or adjusted to include all desired statuses (e.g., if: ${{ contains(fromJSON('["success", "failure", "skipped"]'), github.event.workflow_run.conclusion) }}) [1][5]. Accessing Repository Information: You can access the repository of the triggering workflow using the head_repository.full_name property within the event context [3][4]. This is frequently used for security gating, such as ensuring that privileged workflows only run when the triggering event originated from the same repository (e.g., github.event.workflow_run.head_repository.full_name == github.repository) [3][4]. Example Usage: on: workflow_run: workflows: [Previous Workflow Name] types: [completed] jobs: on-complete: runs-on: ubuntu-latest # This ensures the job runs even if the previous workflow was skipped or failed if: ${{ github.event.workflow_run.conclusion!= 'cancelled' }} steps: - run: echo "The previous workflow from ${{ github.event.workflow_run.head_repository.full_name }} finished with conclusion: ${{ github.event.workflow_run.conclusion }}"
Citations:
- 1: https://stackoverflow.com/questions/79027964/workflow-run-skips-the-workflow-if-the-previous-workflow-fails
- 2: https://raw.githubusercontent.com/github/docs/refs/heads/main/content/actions/reference/workflows-and-actions/events-that-trigger-workflows.md
- 3: https://github.com/hyprstream/hyprstream/blob/dd3e423f2852959bb19d671a121268e4e4877e5b/.github/workflows/docker-build.yml
- 4: https://github.com/abhigyanpatwari/GitNexus/blob/8ad4469e/.github/workflows/commit-fork-prebuilds.yml
- 5: https://explore.market.dev/ecosystems/typescript/projects/rossbugginsnhs-github-workflow-dispatcher
Reject fork-derived runs before invoking the privileged callee.
.github/workflows/CI-trigger.yml skips its job for fork pull requests, but this workflow_run job accepts any completed run with conclusion == 'success'. Add a source-repository check in this job, such as comparing github.event.workflow_run.head_repository.full_name or repository ID with github.repository, because the fork guard stops the job, not the workflow-run event from arriving.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/CI-no-infra-g1.yml at line 16, Update the workflow_run job
condition near the existing conclusion check to require that
github.event.workflow_run.head_repository.full_name matches github.repository,
while preserving the current success-or-no-workflow_run behavior. Ensure
fork-derived runs are rejected before the privileged callee is invoked.
Source: Linters/SAST tools
| # `write-all` is required for the callee's `use_oidc: true` Codecov | ||
| # upload step to mint a GitHub OIDC token. Reusable-workflow | ||
| # permissions are the intersection of caller + callee, so the | ||
| # caller has to grant id-token:write (and everything else included | ||
| # in write-all) for the callee's declaration to take effect. The | ||
| # callee at ci-<group>.yml@GH-Actions also declares write-all. | ||
| permissions: write-all |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
echo "== workflow files =="
git ls-files '.github/workflows/*' | sort
echo
echo "== target workflow excerpt =="
if [ -f .github/workflows/CI-no-infra-g1.yml ]; then
cat -n .github/workflows/CI-no-infra-g1.yml | sed -n '1,120p'
else
echo "missing target workflow"
fi
echo
echo "== related workflow permission snippets =="
for f in $(git ls-files '.github/workflows/*' | sort); do
echo "--- $f"
cat -n "$f" | sed -n '1,80p' | grep -nE 'permissions:|id-token:|write-all|codecov|ci-|reuse|uses:' || true
done
echo
echo "== search codecov / id-token / write-all in workflows =="
rg -n "codecov|id-token|write-all|permissions:" .github/workflows || trueRepository: sysown/proxysql
Length of output: 50372
🌐 Web query:
GitHub reusable workflow caller permissions intersection GITHUB_TOKEN id-token writeall documentation
💡 Result:
In GitHub Actions, reusable workflows inherit the permissions of the calling job [1][2][3]. The following rules govern the interaction between caller and called workflow permissions: 1. Permission Downgrading: The GITHUB_TOKEN permissions passed from a caller workflow can only be downgraded, never elevated, by a called (reusable) workflow [1][2]. If a caller workflow assigns specific permissions to a job that calls a reusable workflow, the reusable workflow cannot request or exercise permissions beyond that set [1][2][4]. 2. Inheritance and Defaults: If a caller job does not explicitly define permissions, the called (reusable) workflow defaults to the repository's configured default permissions for the GITHUB_TOKEN [1][2]. 3. Security Hardening and "write-all": While the "write-all" permission set exists, it is strongly discouraged in security-sensitive contexts. Because reusable workflows inherit the caller's permission context, if a caller job grants "write-all," the reusable workflow also gains those extensive privileges, which contradicts the principle of least privilege [5][3]. Best practice is to explicitly define the minimum required permissions (e.g., contents: read) at the job or workflow level in both the caller and the reusable workflow [5][3]. 4. ID Token Permissions: If a reusable workflow requires the use of OpenID Connect (OIDC) for cloud authentication, the caller job must grant the id-token: write permission [6]. The reusable workflow will then inherit this ability [6]. OIDC tokens generated for jobs within a reusable workflow include a custom claim, job_workflow_ref, which identifies the specific reusable workflow being executed, allowing cloud providers to apply granular trust conditions [7]. Summary of Interaction: - Caller permissions act as an upper bound (a ceiling) for all nested jobs in the reusable workflow [2][8]. - If you attempt to use more permissions in a called workflow than are granted by the caller job, the workflow will fail at runtime [3]. - For maximum security, define explicit, minimal permissions in both the caller and the called workflow [5][3]. Top Results: [1], [7], [2], [3]
Citations:
- 1: https://docs.github.com/en/enterprise-server@3.13/actions/reference/reusable-workflows-reference
- 2: https://docs.github.com/en/actions/reference/workflows-and-actions/reusing-workflow-configurations
- 3: https://www.kenmuse.com/blog/github-actions-workflow-permissions/
- 4: Reusable workflow permissions docker/github-builder#24
- 5: Add
permissions: {}to all reusable workflows python/cpython#148114 - 6: make reference accessible in reusable workflow actions/toolkit#1264
- 7: https://docs.github.com/en/enterprise-cloud@latest/actions/how-tos/secure-your-work/security-harden-deployments/oidc-with-reusable-workflows
- 8:
call-workflowgenerated caller jobs omit requiredpermissions:for reusable workflows github/gh-aw#21071
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
echo "== CI-no-infra branch candidate files =="
git ls-remote --heads origin gh-actions 2>/dev/null | sed -n '1,120p' || true
git ls-remote --tags origin gh-actions 2>/dev/null | sed -n '1,120p' || true
echo
echo "== fetch caller file from gh-actions, if available =="
tmp="$(mktemp -d)"
git ls-remote refs/remotes/origin/gh-actions sysown/proxysql/.github/workflows/CI-no-infra-g1.yml 2>/dev/null | while read -r ref path; do
[ -n "$path" ] || continue
git cat-file -p "$ref" -o "$tmp/CI-no-infra-g1.yml"
echo "--- $path"
cat -n "$tmp/CI-no-infra-g1.yml" | sed -n '1,160p'
done
echo
echo "== fetch same branch reusable callee if present =="
git ls-remote refs/remotes/origin/gh-actions sysown/proxysql/.github/workflows/ci-no-infra-g1.yml 2>/dev/null | while read -r ref path; do
[ -n "$path" ] || continue
git cat-file -p "$ref" -o "$tmp/ci-no-infra-g1.yml"
echo "--- $path permissions/content snippets"
cat -n "$tmp/ci-no-infra-g1.yml" | sed -n '1,180p' | grep -nE 'permissions:|id-token:|write-all|use_oidc|codecov|jobs:|workflow_call|uses:' || cat -n "$tmp/ci-no-infra-g1.yml" | sed -n '1,180p'
done
echo
echo "== local GH-Actions branch availability =="
git branch -r 2>/dev/null | grep 'origin/gh-actions' || trueRepository: sysown/proxysql
Length of output: 253
🌐 Web query:
GH-Actions write-all id-token write reuse_workflow_permissions documentation
💡 Result:
In GitHub Actions, the id-token: write permission is required to request and use an OpenID Connect (OIDC) JSON Web Token (JWT) for authenticating with external cloud providers [1][2]. This permission does not grant write access to repository contents or any other resources; it strictly enables the generation and use of the OIDC token [1][3]. Key aspects regarding permissions and reusable workflows include: Explicit Requirement: When using reusable workflows (especially those outside your enterprise or organization), you must explicitly set permissions: id-token: write at the caller workflow or job level to allow the token to be generated and consumed [1][4]. Permission Hierarchy: Permissions can be defined at the workflow level (applying to all jobs) or the job level (overriding workflow-level settings) [5][6]. If you specify any permissions, all unspecified permissions are set to none [5][6]. Security Best Practices: Avoid write-all: The write-all permission grants broad, often unnecessary access [7]. It is a security best practice to follow the principle of least privilege by explicitly defining only the minimal permissions required for each job [8][7][9]. Default Settings: GitHub now defaults new repositories and organizations to restricted (read-only) GITHUB_TOKEN permissions, though workflows may inherit broader settings depending on existing repository configurations [10][8][11]. If your workflow fails with permission errors, verify that you have not inadvertently restricted required access or omitted necessary permissions (like contents: read or id-token: write) [11][9].
Citations:
- 1: https://docs.github.com/actions/reference/openid-connect-reference
- 2: https://docs.github.com/en/enterprise-cloud@latest/actions/how-tos/secure-your-work/security-harden-deployments/oidc-in-cloud-providers
- 3: https://github.github.com/gh-aw/reference/permissions/
- 4: https://github.blog/changelog/2023-06-15-github-actions-securing-openid-connect-oidc-token-permissions-in-reusable-workflows/
- 5: https://docs.github.com/actions/using-workflows/workflow-syntax-for-github-actions
- 6: https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax?use_case=
- 7: https://github.com/github/awesome-copilot/blob/main/skills/github-actions-hardening/references/permissions-and-tokens.md
- 8: https://github.blog/security/new-tool-to-secure-your-github-actions/
- 9: https://docs.github.com/en/actions/reference/security/secure-use
- 10: https://github.blog/changelog/2021-04-20-github-actions-control-permissions-for-github_token/
- 11: https://adhdecode.com/articles/github-actions/github-actions-workflow-permissions/
Narrow the caller job permissions.
permissions: write-all grants every write-capable token scope. OIDC Codecov uploads need id-token: write, and the reusable workflow calls can still be elevated to broader actions such as actions/checkout or codecov/codecov-action unless permission caps are set. Declare only the permissions called jobs require in both the caller and the reusable GH-Actions workflow.
🧰 Tools
🪛 zizmor (1.29.0)
[error] 23-23: overly broad permissions (excessive-permissions): uses write-all permissions
(excessive-permissions)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/CI-no-infra-g1.yml around lines 17 - 23, Replace the broad
permissions setting in the caller workflow with an explicit minimal permissions
map, retaining id-token: write and adding only scopes required by the called
jobs; update the corresponding permissions declaration in the reusable
ci-<group>.yml workflow to the same least-privilege set so checkout, Codecov,
and other actions receive only necessary access.
Source: Linters/SAST tools
| # in write-all) for the callee's declaration to take effect. The | ||
| # callee at ci-<group>.yml@GH-Actions also declares write-all. | ||
| permissions: write-all | ||
| uses: sysown/proxysql/.github/workflows/ci-no-infra-g1.yml@GH-Actions |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
git ls-remote --heads --tags origin GH-ActionsRepository: sysown/proxysql
Length of output: 216
Pin the called workflow to an immutable ref.
GH-Actions resolves to refs/heads/GH-Actions, a mutable branch. Use the reviewed commit SHA from that branch for the callee ref after the companion PR merges, so future workflow changes require a review.
🧰 Tools
🪛 zizmor (1.29.0)
[warning] 24-24: secrets unconditionally inherited by called workflow (secrets-inherit): this reusable workflow
(secrets-inherit)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/CI-no-infra-g1.yml at line 24, Update the reusable
workflow reference in the CI workflow to replace the mutable GH-Actions branch
with the reviewed immutable commit SHA from that branch, preserving the existing
called workflow path.
| # callee at ci-<group>.yml@GH-Actions also declares write-all. | ||
| permissions: write-all | ||
| uses: sysown/proxysql/.github/workflows/ci-no-infra-g1.yml@GH-Actions | ||
| secrets: inherit |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf 'Tracked workflow files:\n'
git ls-files '.github/workflows/*' | sort
printf '\nTarget file with line numbers around secrets usage:\n'
sed -n '1,80p' .github/workflows/CI-no-infra-g1.yml 2>/dev/null || true
printf '\nAll uses of ci-no-infra-g1 / CI-no-infra-g1 workflow files:\n'
rg -n "ci-no-infra-g1|CI-no-infra-g1|secrets:\s*inherit|secrets:" .github/workflows || true
printf '\nWorkflow dispatch/run triggers mentioning secrets or workflow_run:\n'
rg -n "workflow_dispatch|workflow_run|repository_dispatch|schedule|workflow_call|secrets:\s*inherit" .github/workflows || trueRepository: sysown/proxysql
Length of output: 50371
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf 'Callee workflow header and secrets declaration:\n'
cat -n .github/workflows/ci-no-infra-g1.yml | sed -n '1,80p'
printf '\nAll secret references in callee:\n'
rg -n "\$\{\{\s* secrets\.[A-Za-z0-9_-]+\s*\}\}" .github/workflows/ci-no-infra-g1.yml || true
printf '\nAll reusable-workflow uses in root workflows with job-local permissions/secrets:\n'
python3 - <<'PY'
from pathlib import Path
import re, yaml, sys
for p in sorted(Path('.github/workflows').glob('*.yml')):
text = p.read_text()
if 'uses: sysown/proxysql/.github/workflows/ci-no-infra-g1.yml@GH-Actions' not in text:
continue
lines = text.splitlines()
start = 0
while start < len(lines) and 'uses: sysown/proxysql/.github/workflows/ci-no-infra-g1.yml@GH-Actions' not in lines[start]:
start += 1
indent = re.match(r'^(\s*)', lines[start]).group(1)
end = len(lines)
for i in range(start+1, len(lines)):
if re.match(r'^\S', lines[i]):
end = i
break
block = lines[start:end]
sec = next((s.strip() for s in block if s.startswith('secrets:')), '')
perm = next((s.strip() for s in block if s.startswith ('permissions:')), '')
print(p)
print(' '.join(block[:18]))
print(' permissions:', perm)
print(' secrets:', sec)
PYRepository: sysown/proxysql
Length of output: 270
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf 'Locate ci-no-infra-g1 workflow files exactly:\n'
fd -a '^ci-no-infra-g1\.yml$|^CI-no-infra-g1\.yml$' . || true
git ls-files | rg '(^|/)ci-no-infra-g1\.yml$|(^|/)CI-no-infra-g1\.yml$' || true
printf '\nGit tracked diff for CI-no-infra-g1.yml if available:\n'
git diff -- .github/workflows/CI-no-infra-g1.yml .github/workflows/ci-no-infra-g1.yml 2>/dev/null | sed -n '1,180p' || true
printf '\nTracked reusable workflows with named secrets or call references to ci-no-infra-g1:\n'
rg -n "ci-no-infra-g1.yml|name:\s*\$.*|on:\s*\{\}|uses:\s*[^@]+@[^\\n]*secrets:" .github/workflows 2>/dev/null | sed -n '1,200p' || trueRepository: sysown/proxysql
Length of output: 490
Pass only named secrets to the reusable workflow.
Line 25 uses secrets: inherit, which passes every secret available to this caller to the reusable workflow. The caller also grants permissions: write-all; because workflow_run workflows can access secrets and use tokens, this broad call makes the reusable workflow available for secret exfiltration if it is compromised. Use secrets: [ ... ] and the specific GITHUB_TOKEN/secrets that this reusable workflow declares.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/CI-no-infra-g1.yml at line 25, Replace secrets: inherit in
the reusable workflow invocation with an explicit named-secrets mapping, passing
only the GITHUB_TOKEN and secrets declared by the called workflow; preserve the
existing workflow permissions and other invocation settings.
Source: Linters/SAST tools




Caller for
ci-no-infra-g1.yml. See the companion PR againstGH-Actionsfor the callee — that one must merge first, otherwise this caller resolves to a missing workflow.no-infra-g1was the only group flagged NEW bylint_group_coverage.py; its five tests have never run in CI, includingreg_test_5363_admin_monitor_caching_sha2-t.With the pair in place:
Closes the pending "wire no-infra-g1 into CI" item. Tracking for the 41 remaining (deliberately allowlisted) families: #6007.
Summary by CodeRabbit