Skip to content
Agent Orchestration
Skill

/workflow-audit

Audit GitHub Actions workflows for correctness, security, and unattended reliability. Use when asked to audit workflows, check CI health, review workflow security, or before committing workflow changes.

From plugin
vmark
49819 skills9 agents7 commands2 MCP
Install
$ npx -y skills add xiaolai/vmark --skill workflow-audit --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/workflow-audit

Context preview

The summary Claude sees to decide when to auto-load this skill.

Audit GitHub Actions workflows for correctness, security, and unattended reliability. Use when asked to audit workflows, check CI health, review workflow security, or before committing workflow changes.

SKILL.md

workflow-audit.SKILL.md
name: workflow-audit
description: >-
  Audit GitHub Actions workflows for correctness, security, and unattended
  reliability. Use when asked to audit workflows, check CI health, review
  workflow security, or before committing workflow changes.

Workflow Audit

Comprehensive audit of `.github/workflows/*.yml` files against GitHub Actions best practices, security hardening guidelines, and project conventions.

When to Use

  • User asks to audit, review, or check workflows
  • Before committing changes to any workflow file
  • After a workflow failure that needs root-cause analysis
  • Periodic health check (e.g., monthly)

Workflow

1. **Discover** — Glob `.github/workflows/*.yml` and list all workflow files. 2. **Parse** — Read each file; validate YAML syntax. 3. **Audit** — Run every check in the checklist below against each file. 4. **Cross-check** — Run cross-workflow consistency checks. 5. **Report** — Output a findings table sorted by severity (critical > high > medium > low). 6. **Fix offer** — For each finding, suggest a concrete fix (diff or instruction).

Audit Checklist

1. YAML Validity

  • File parses as valid YAML.
  • No duplicate keys at the same level.
  • No tabs (GitHub Actions requires spaces).

2. Action Version Currency

Check every `uses:` line.

| Pattern | Severity | Rule | |---------|----------|------| | `actions/checkout@v4` or lower | **critical** | Upgrade to `@v6`. Node.js 20 actions break June 2, 2026 (forced to Node 24). | | `actions/setup-node@v4` or lower | **critical** | Same — upgrade to `@v6`. | | `actions/cache@v3` or lower | **high** | Upgrade to `@v4`. | | `pnpm/action-setup@v3` or lower | **high** | Upgrade to `@v4`. | | `softprops/action-gh-release@v1` | **medium** | Upgrade to `@v2`. | | `actions/upload-pages-artifact@v2` or lower | **medium** | Upgrade to `@v3`. | | `actions/deploy-pages@v3` or lower | **medium** | Upgrade to `@v4`. | | Any `@main` or `@master` pin | **high** | Pin to a tag or SHA — mutable refs are a supply-chain risk. |

**Node.js deprecation timeline** (reference for findings):

  • **June 2, 2026**: Node 24 becomes default (`FORCE_JAVASCRIPT_ACTIONS_TO_NODE24=true` to opt in early).
  • **Fall 2026**: Node 20 removed entirely from runners.
  • Temporary opt-out after June 2: `ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION=true` (stops working fall 2026).

3. Security — Script Injection

For every `run:` block, check for **untrusted context expressions used inline**:

# DANGEROUS — attacker-controlled input interpreted by shell
run: echo "${{ github.event.issue.title }}"

# SAFE — passed via environment variable
env:
  TITLE: ${{ github.event.issue.title }}
run: echo "$TITLE"

**Untrusted contexts** (must NEVER appear directly in `run:` blocks):

  • `github.event.issue.title` / `.body`
  • `github.event.pull_request.title` / `.body`
  • `github.event.comment.body`
  • `github.event.review.body` / `github.event.review_comment.body`
  • `github.event.commits.*.message`
  • `github.event.head_commit.message` / `.author.email` / `.author.name`
  • `github.event.pull_request.head.ref` / `.head.label` / `.head.repo.default_branch`
  • `github.head_ref`
  • `github.event.pages.*.page_name`

**Safe contexts** (numeric or system-controlled, OK inline):

  • `github.event.issue.number`, `github.event.pull_request.number`
  • `github.repository`, `github.run_id`, `github.sha`
  • `github.ref` (only on push/tag events, not PR)
  • `secrets.*`, `env.*`, `matrix.*`

4. Security — Permissions

| Check | Severity | Rule | |-------|----------|------| | No `permissions:` block at all | **high** | Add explicit permissions — defaults give broad access. | | `permissions: write-all` | **critical** | Never use. Specify individual scopes. | | Unused permission scopes | **medium** | Remove permissions not needed by any step. | | `id-token: write` without OIDC usage | **medium** | Only needed for Bedrock/Vertex/Foundry or cloud OIDC. | | `pull_request_target` trigger | **high** | Grants write access from forks — verify checkout uses PR base, not head. |

5. Security — Auto-merge and Bot Patterns

| Check | Severity | Rule | |-------|----------|------| | `gh pr merge --auto` without author guard | **high** | Restrict to bot PRs: `if: github.event.pull_request.user.login == 'claude[bot]'` | | `allowed_bots: '*'` in claude-code-action | **medium** | Prefer explicit bot names over wildcard. |

6. Reliability — Timeouts

| Check | Severity | Rule | |-------|----------|------| | Job without `timeout-minutes` | **high** | Default is 360 min (6 hours). Always set explicit timeouts. | | Claude Code action jobs | **high** | Must have `timeout-minutes` (recommended: 15 for review, 30 for fix). | | Build jobs | **medium** | Recommended: 30-45 min depending on platform. |

7. Reliability — Error Handling

| Check | Severity | Rule | |-------|----------|------| | `git push` to a protected branch | **critical** | Will fail if branch protection requires status checks. Push to unprotected branch or use PR. | | `gh pr merge` without `\|\| true` or `continue-on-error` | **medium** | May fail if PR is not mergeable — handle gracefully. | | Steps after a `continue-on-error` step that depend on its output | **medium** | Check if downstream steps handle the soft failure. | | Network-dependent steps without retry or `continue-on-error` | **low** | CDN downloads, API calls can be flaky. |

8. Reliability — Concurrency

| Check | Severity | Rule | |-------|----------|------| | Scheduled workflow without `concurrency` group | **medium** | Overlapping runs waste resources. | | `cancel-in-progress: true` on deploy workflows | **high** | Can corrupt partial deployments. Use `false` for deploys. | | Missing `concurrency` on Claude Code jobs | **medium** | Multiple concurrent AI runs on the same issue/PR waste credits. |

9. Reliability — Branch Protection Awareness

| Check | Severity | Rule | |-------|----------|------| | Workflow pushes to `main` (or default branch) | *

Read more
Ships withvmark

The Plain-Text Workspace Where Humans and AI Collaborate Free. Local-first. Format-aware. VMark is the plain-text workspace where humans and AI collaborate.

Get the whole plugin