审查AI生成的GitHub Actions的检查清单
由AI编码代理编写的GitHub Actions工作流的人工审查清单——秘密泄露、供应链攻击、权限和部署安全性。
CursorClaude CodeCodexWindsurf TypeScript
GitHub Actions工作流可以直接访问秘密和部署环境。AI生成的工作流会固定到可变标签、在日志中暴露秘密,并授予第三方操作过多的权限。
正确性
[ ] Workflow triggers are scoped correctly — pull_request vs pull_request_target behave differently for fork PRs[ ] pull_request_target does not check out the PR's code without explicit trust validation[ ] on: push branches filter is set — avoid triggering on every branch push[ ] Job dependencies are declared with needs: — parallel jobs that must be sequential are chained[ ] Conditional steps use the correct expression syntax — ${{ }} not $() or %VAR%[ ] Matrix strategy fail-fast is set intentionally — false if you want all matrix jobs to complete[ ] Artifact retention days are set — default is 90 days, which may retain sensitive files too long[ ] Cache keys are specific enough to invalidate on dependency changes (include lockfile hash)[ ] Upload-artifact and download-artifact steps use matching names and paths[ ] Environment variables are set at the correct scope (job vs step) — step-level env does not persist[ ] Working directory is set explicitly for monorepos — default is repo root[ ] Checkout depth is set for git history-dependent commands (e.g. conventional commits, changelogs)安全性
[ ] Third-party actions are pinned to a full SHA commit hash, not a mutable tag like @v3 or @main[ ] actions/checkout, actions/setup-node, and other GitHub-owned actions are pinned to SHA[ ] GITHUB_TOKEN permissions are declared with the minimum required scope (contents: read, id-token: write, etc.)[ ] permissions: at the workflow level is set to read-all or {} to restrict defaults before granting per-job[ ] Secrets are not echoed in run: steps — no echo ${{ secrets.MY_SECRET }}[ ] Secrets are not set as environment variables at the job level if only one step needs them[ ] User-controlled input (GitHub event data) is not interpolated into run: shell commands — use env: instead[ ] Expression injection is prevented — do not use ${{ github.event.pull_request.title }} directly in run: steps[ ] Deployment jobs require environment approval for production — use environment: with protection rules[ ] Self-hosted runners are not used for open-source repos with pull_request triggers[ ] OpenID Connect (OIDC) is used for cloud auth (AWS, GCP, Azure) instead of long-lived credentials[ ] No AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY stored as secrets — prefer OIDC role assumption[ ] workflow_dispatch inputs are validated — do not pass them directly to shell commands部署
[ ] Production deployments run only on the main or release branch — not on every PR[ ] Deployment workflow has a manual approval gate via environment protection rules[ ] Rollback step or procedure is documented in the workflow or linked[ ] Database migration steps run before the new application version is deployed[ ] Health check is polled after deployment — workflow fails if the service does not come up[ ] Concurrency group is set to prevent simultaneous deployments: concurrency: deploy-${{ github.ref }}[ ] cancel-in-progress is set to false for deployments — do not cancel a deployment mid-flight[ ] Release assets and changelogs are generated from signed commits or tags, not PR body text[ ] Semantic versioning is automated with a verified tool — not a hand-rolled shell script性能
[ ] Node modules are cached using actions/cache with the lockfile as the cache key[ ] Docker layer caching is enabled — use cache-from and cache-to in docker/build-push-action[ ] Large test suites are parallelized with matrix strategy across available runners[ ] Setup steps (language runtime, tools) use cached versions where available[ ] Artifact uploads are scoped to only the files needed by downstream jobs[ ] Workflow does not install global tools that could be provided by a pre-built actionAI特定风险
[ ] AI has not used deprecated set-output syntax — use GITHUB_OUTPUT environment file instead[ ] AI has not used deprecated add-path or save-state commands — use GITHUB_PATH and GITHUB_STATE[ ] AI has not pinned to a mutable :latest Docker image in a container: block[ ] AI has not mixed GitHub-hosted and self-hosted runner syntax for the same job[ ] AI has not used actions/cache@v2 — v3 or v4 is required for current runner images[ ] AI has not generated a workflow that runs on pull_request_target and checks out PR code — classic supply chain vulnerability[ ] AI-generated workflow secrets are referenced by the correct name — check for typos that silently pass empty strings[ ] AI has not hardcoded environment-specific URLs or bucket names that differ between staging and production修复提示
Review this GitHub Actions workflow against the checklist above. Pin allthird-party actions to their full SHA, add minimum-required permissions, replaceany secret interpolation in run: steps with env: bindings, add a concurrencygroup to prevent parallel deployments, and add an environment approval gate forthe production deploy step. Return the corrected workflow YAML only.