58 ci cd pipeline review
Skill FluxonLab/Skillry/plugins/devops-and-release/skills/58-ci-cd-pipeline-review
Installable, permission-bounded, multi-platform agent skills & subagents for Claude Code, Codex, Copilot & Gemini/Antigravity — 125 skills + 73 subagents across 18 departments, with a validation harness, native plugin marketplace, and full upstream attribution. by FluxonLab.
npx -y skills add FluxonLab/Skillry --skill 58-ci-cd-pipeline-reviewAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Use when you need to review CI jobs, workflow triggers, caches, matrixes, artifacts, and safe release gates.
SKILL.md
9.4 KB, as published. Nobody here has run it
CI/CD Pipeline Review
Purpose
Audit GitHub Actions workflows, GitLab CI pipelines, CircleCI configs, or equivalent: trigger correctness, secret handling, job dependency ordering, cache hygiene, matrix configuration, artifact retention, fail-fast behavior, and deployment gate safety. Identify security misconfigurations, unnecessary permissions, and reliability anti-patterns — each with a file:line and a concrete fix. The review is read-only: it never triggers a run, approves a deploy, or prints a secret value.
When to use
- A new workflow file is added or an existing one is significantly modified.
- CI is slow and you need to find caching or parallelization improvements.
- A security review flags the pipeline (secret exposure, overly broad
GITHUB_TOKENpermissions). - Deployments fail non-deterministically and the cause is suspected to be in the pipeline config.
- A PR workflow accidentally triggers on pushes to protected branches or production environments.
When not to use
- The pipeline works correctly and the task is to add an application feature unrelated to CI.
- The review concerns application code quality, not pipeline infrastructure.
- A dedicated DevOps team owns the pipeline and has a separate review process.
Procedure
- Identify all workflow files. Find
.github/workflows/*.yml,.gitlab-ci.yml,.circleci/config.yml,Jenkinsfile, or equivalent. List each workflow, its triggers, and its purpose. - Audit trigger configuration. Verify
pull_requestvspushvsworkflow_dispatchare used appropriately; deploy/release workflows trigger only onpushto the default branch or tags, never onpull_request;workflow_runtriggers do not grant elevated permissions to fork PRs;scheduleintervals are reasonable (not sub-5-minute). - Review
GITHUB_TOKENpermissions. Checkpermissions:at workflow and job level. Least privilege applies: a test-only job needscontents: readat most. Flagpermissions: write-allor a missing block (defaults to repo settings, often too broad). - Audit secret usage. For every
${{ secrets.FOO }}: is it needed in that job? Confirm it is not echoed to logs (echo,run: env,::debug::) and is passed to third-party actions as env vars, not inline args (args appear in logs). - Check job dependency ordering. Verify
needs:chains tests before deploy and release jobs depend on all required gates. Flag a missingneeds:that lets a deploy run concurrently with tests. - Review cache configuration. Cache keys include a lockfile hash (
hashFiles('**/package-lock.json')); restore keys are ordered specific to general; PR caches cannot poison the main branch. - Audit matrix strategies. Confirm
fail-fastis intentional per matrix; dimensions are not combinatorially explosive (3x3x3 = 27 jobs per PR is likely too many). - Check artifact retention and naming. Artifacts have explicit
retention-days; names are unique across matrix legs (include${{ matrix.os }}). - Verify deployment gates. All test jobs are in the deploy job's
needs:; production deploys require manual approval viaenvironment:protection; deploy runs with environment-scoped secrets. - Check self-hosted runner risks. Self-hosted runners used for PR workflows must not have production secret access — fork PRs can run on them and exfiltrate env vars.
Concrete checks
- Deploy/release workflows trigger only on protected-branch push or tags, not on PR.
-
permissions:is set at workflow or job level with minimum required scopes. - Secrets are passed as env vars, not inline args; not echoed to logs.
- Job
needs:graph ensures tests complete before any deploy job starts. - Cache keys include a lockfile hash; restore keys are ordered specific to general.
-
fail-fastbehavior is intentional for each matrix configuration. - Artifact
retention-daysis explicitly set. - Production deploy jobs require manual approval via
environment:protection rules. - Self-hosted runners used for PR workflows have no production secret access.
- Scheduled workflow intervals are reasonable (not sub-5-minute).
- Third-party actions are pinned to a commit SHA, not a mutable tag.
Commands or Templates
# List workflows and their trigger blocks
for f in .github/workflows/*.yml .github/workflows/*.yaml; do
echo "== $f =="; grep -nE "^(on|name):|push:|pull_request:|workflow_dispatch:|schedule:" "$f"
done
# Find over-broad permissions and unpinned actions
grep -rn "write-all\|permissions:" .github/workflows/
grep -rnE "uses:\s+\S+@(v?[0-9]+|main|master)\b" .github/workflows/ # mutable refs -> pin to SHA
# Find secrets echoed to logs (high-risk)
grep -rnE "echo .*secrets\.|run:\s*env\b|::debug::" .github/workflows/
# Find deploy jobs missing a needs: gate
grep -rnE "environment:|deploy" .github/workflows/
# Least-privilege + pinned action + gated deploy (target pattern)
permissions:
contents: read
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@<commit-sha> # pinned, not @v4
deploy:
needs: [test] # gate: tests must pass first
environment: production # manual approval via protection rule
runs-on: ubuntu-latest
Severity rubric
Rank findings by exploitability and blast radius so the report drives action:
- Critical — a fork PR can obtain
writepermissions or read production secrets (e.g.,pull_request_targetrunning untrusted code with secrets, or self-hosted PR runners with prod access). An attacker can exfiltrate secrets or push to the repo. - High —
write-allor broadpermissions:on a workflow that handles untrusted input; a deploy job missing a testneeds:gate; an unpinned third-party action used in a privileged job. - Medium — a secret echoed to logs, cache keys without a lockfile hash (poisoning risk within the repo), no environment protection on a non-critical deploy.
- Low — missing
retention-days, sub-5-minute schedules, all-sequential jobs (cost/time only, no security impact).
A misconfiguration's severity rises sharply when it sits on a trigger reachable by an untrusted actor (pull_request from forks, workflow_run), and falls when it is only reachable by trusted maintainers on a protected branch.
Worked example
A workflow contains:
on: [pull_request_target]
permissions: write-all
jobs:
test:
steps:
- uses: actions/checkout@v4
with: { ref: ${{ github.event.pull_request.head.sha }} }
- run: npm install && npm test # runs the PR's code with write-all + secrets
Report as Critical at the on: and permissions: lines: pull_request_target runs with the base repo's secrets and write-all token, but checks out and executes the fork's untrusted code — a classic exfiltration path. Fix: use pull_request (no secrets for forks) for tests, scope permissions: contents: read, and never check out + execute fork code under pull_request_target. This single pattern is the highest-value thing to grep for in any public repo's CI.
Common issues & anti-patterns
- Unpinned action versions.
uses: actions/checkout@v4can be hijacked if the tag is moved; pin to a commit SHA. write-allpermissions. A compromised step can push to the repo, create releases, or modify issues.- Secrets in non-secret contexts.
run: echo "Token is ${{ secrets.API_TOKEN }}"logs the secret (masking has workarounds). - Missing
needs:on deploy. Deploy runs in parallel with tests; a failing test does not block it. - Cache poisoning via PR. A PR caches a modified
node_modules; the main branch restore key picks it up. workflow_run+ fork PR elevation. Aworkflow_runtrigger withwritepermissions can be exploited by a fork PR.- All jobs sequential. No parallelism; lint, test, and typecheck run one after another, doubling CI time.
- No environment protection on prod deploy. Any push to main deploys to production with no human review.
Required output
## CI/CD Pipeline Review
### Workflows found
| File | Trigger | Purpose |
### Security findings
| Severity | Finding | File:line | Recommendation |
### Permission audit
| Workflow/Job | Current permissions | Minimum required |
### Job dependency graph issues
- Missing needs: [job X should depend on job Y]
### Cache configuration
- Keys include lockfile hash: yes/no | Cross-branch contamination risk: yes/no
### Deployment gate status
- All test jobs in deploy needs: yes/no | Manual approval for prod: yes/no | Env secrets scoped: yes/no
### Performance / cost findings
- Parallelization opportunities | Excessive matrix size | Artifact retention not set
### Recommended actions (priority order)
1. ...
Safety
- Do not modify workflow files without explicit user instruction.
- Do not trigger workflows, approve deployments, or cancel runs.
- Do not access or print secret values — reference them by name only.
- Do not recommend disabling a security gate (environment protection, branch protection) to make CI faster.
Completion criteria
Done means all workflows are listed with triggers, security findings carry severity + file:line + fix, the permission and deployment-gate audits are complete, cache and matrix risks are assessed, and recommendations are ordered by priority — with no secret value printed.