بنقرة واحدة
zizmor
Audit GitHub Actions workflow and action.yml files for security issues using zizmor rules, then fix violations
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Audit GitHub Actions workflow and action.yml files for security issues using zizmor rules, then fix violations
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
Navigation-only skill for individual actions in netcracker/qubership-workflow-hub. Use when a workflow needs to consume a specific Qubership action (Docker build/push, version/tag rendering, Maven/npm/Python publishing, package cleanup, Helm charts, security scans, etc.) and you need to find the right action and read its authoritative README. All rules (pinning, permissions, anti-hallucination, naming) live in qubership-workflow-conventions — this skill does not restate them.
Markdownlint ruleset from super-linter. Apply when writing or editing any .md file.
Single source of truth for Qubership GitHub Actions workflows. Use when designing, writing, reviewing, or debugging .github/workflows/*.yml that consume actions or templates from netcracker/qubership-workflow-hub or Netcracker/.github.
Update or create documentation for a specific action or reusable workflow based on git diff and action.yml
Audit files for EditorConfig violations (final newline, trailing whitespace, indent, line endings) and fix them in-place
Generate a PR title and description following project conventions, then create or update the PR via gh CLI
| name | zizmor |
| description | Audit GitHub Actions workflow and action.yml files for security issues using zizmor rules, then fix violations |
| arguments | ["files"] |
Security audit for GitHub Actions workflow and action.yml files.
Apply all rules in-memory when writing or editing any .yml workflow or action file.
When invoked via /workflow-audit [files], audit and fix target files directly.
rules:
dangerous-triggers:
ignore:
- cla.yaml
- pr-assigner.yml
Pedantic rules disabled — skip: anonymous-definition, self-hosted-runner,
stale-action-refs, undocumented-permissions.
| Rule | Flag if | Fix |
|---|---|---|
template-injection | Any ${{ }} interpolation directly inside a run: block (or actions/github-script script:) whose value is not a static/matrix value — this includes inputs.* and steps.*.outputs.* in action.yml composite actions, not just github.event.* sources. Common attacker-controlled sources: github.event.pull_request.title/body/head.ref/head.label, github.event.issue.title/body, github.event.comment.body, github.event.review.body, github.event.discussion.title/body, github.head_ref, github.event.workflow_run.head_branch/head_commit.message, and any ${{ inputs.* }} used in a composite action's run: step | Pass through a step-level env: var instead of direct interpolation, then reference as "${VAR_NAME}" (quoted) in the shell |
excessive-permissions | permissions: write-all anywhere; contents: write at workflow level (not job level); any write permission a job doesn't actually need; a job with no permissions: block at all (defaults to broad token permissions) | Move to job level; start from permissions: {} or permissions: contents: read; grant only what each job needs. Add an explicit permissions: block to every job, even if it's just contents: read |
unpinned-uses | Any uses: not pinned to a full 40-char SHA — branches (@main), mutable tags (@v4, @v1.2.3) are all flagged | Replace with SHA pin. Fetch: gh api repos/<owner>/<repo>/git/ref/tags/<tag> --jq '.object.sha'; if annotated tag: dereference with gh api repos/<owner>/<repo>/git/tags/<sha> --jq '.object.sha' |
artipacked | actions/checkout without persist-credentials: false — flagged unconditionally, not only when upload-artifact is present | Add persist-credentials: false to the checkout step |
secrets-inherit | secrets: inherit in a reusable workflow call | Replace with explicit named secrets only |
dangerous-triggers | pull_request_target or workflow_run AND any step checks out with PR head ref or runs shell using github.event.pull_request.* directly. Ignore if file matches config ignore list | Pin checkout ref: to github.sha; add persist-credentials: false; move untrusted input to env vars |
github-env | Writing untrusted event data to $GITHUB_ENV or $GITHUB_PATH in privileged trigger context | Use $GITHUB_OUTPUT for inter-step data; never write raw event data to GITHUB_ENV |
github-app | GitHub App token passed via ${{ steps.*.outputs.token }} directly in shell interpolation | Always pass via env: var, never interpolate directly |
secrets-outside-env | Deployment/publish job uses ${{ secrets.* }} but has no environment: declaration | Add environment: block — apply judgment, not every workflow needs it |
bot-conditions | if: checks github.actor == 'dependabot[bot]' or similar string comparison | Use github.actor_id == '49699333' or github.event.sender.type == 'Bot' |
unsound-contains | contains() with attacker-controlled input as haystack in security-sensitive condition | Use exact equality == instead |
unsound-condition | if: expression always evaluates to true due to type coercion (e.g. ${{ inputs.flag }} where string "false" is truthy) | Use explicit string comparison: inputs.flag == 'true' |
misfeature | continue-on-error: true on security-sensitive steps (scan, lint, auth); workflow_dispatch inputs used unsafely in shell | Remove continue-on-error from sensitive steps; pass dispatch inputs via env: |
unredacted-secrets | Secret value transformed or concatenated in shell (substring, base64, concat) — bypasses GitHub's auto-redaction | Avoid transforming secrets in shell; if unavoidable, mask result with ::add-mask:: |
concurrency-limits | Workflow triggered by push or pull_request with no concurrency: block | Add concurrency group — see workflow-patterns.md → Concurrency |
insecure-commands | ACTIONS_ALLOW_UNSECURE_COMMANDS: true in any env: block | Remove it; use $GITHUB_OUTPUT, $GITHUB_ENV, $GITHUB_STEP_SUMMARY |
hardcoded-container-credentials | Literal credential string in registry-password:, password:, or similar field | Move to ${{ secrets.* }} |
unpinned-images | container.image or services.*.image uses mutable tag (ubuntu:latest, postgres:15) | Pin to SHA256 digest: ubuntu@sha256:<digest> |
unpinned-tools | run: step does curl | bash, pip install <pkg> without version, npm install -g <pkg> without @version | Pin tool versions explicitly or use SHA-verified download |
cache-poisoning | Release workflow uses actions/cache with cache key derived from untrusted input | Use only deterministic keys (e.g. hash of lock files) |
overprovisioned-secrets | secrets: ${{ secrets }} — whole secrets context passed | Pass only named secrets the callee needs |
archived-uses | uses: references an archived GitHub repository | Replace with maintained alternative or vendor locally. Cannot auto-fix — report to user |
impostor-commit | SHA pin that cannot be verified as a real commit in the upstream repo — most common cause: tag object SHA used instead of commit SHA (annotated tags) | Fix: dereference the tag — gh api repos/<owner>/<repo>/git/ref/tags/<tag> --jq '.object.sha', then if .object.type == "tag" dereference again: gh api repos/<owner>/<repo>/git/tags/<sha> --jq '.object.sha' — use the final commit SHA |
known-vulnerable-actions | uses: references action version with known CVE or GitHub Security Advisory | Cannot auto-fix — report action name and version to user |
obfuscation | run: contains base64 -d, eval, or piped decode patterns | Cannot auto-fix — report to user for manual review |
ref-confusion | uses: references a ref that exists as both branch and tag in upstream repo | Pin to full SHA |
ref-version-mismatch | SHA pin comment doesn't match the actual tag for that SHA | Two cases: (1) annotated tag — the SHA is a tag object, not a commit: dereference with gh api repos/<owner>/<repo>/git/tags/<sha> --jq '.tag'. (2) SHA is a valid commit but not what the tag in the comment points to (common — e.g. a later untagged commit was pinned): resolve the tag's actual commit with gh api repos/<owner>/<repo>/git/refs/tags/<tag> --jq '.object.sha' and repin to that SHA, OR list gh api repos/<owner>/<repo>/tags --jq '.[] | .name + " " + .commit.sha' and find the tag whose commit matches the pinned SHA, updating the comment to that tag |
superfluous-actions | uses: calls an action whose functionality is already in the runner image | Remove the step. Cannot always auto-fix — report to user |
use-trusted-publishing | Publishing to PyPI/npm/RubyGems using ${{ secrets.PYPI_TOKEN }} etc. when registry supports OIDC | Migrate to OIDC trusted publishing with id-token: write |
Known pins used in this repo (always verify with API before applying):
| Action | SHA | Tag |
|---|---|---|
actions/checkout | de0fac2e4500dabe0009e67214ff5f5447ce83dd | v6.0.2 |
actions/upload-artifact | 043fb46d1a93c77aae656e7c1c64a875d1fc6a0a | v7.0.1 |
actions/download-artifact | 3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c | v8.0.1 |
actions/setup-python | a309ff8b426b58ec0e2a45f0f869d46889d02405 | v6.2.0 |
actions/setup-node | 53b83947a5a98c8d113130e565377fae1a50d02f | v6.3.0 |
actions/setup-go | 4a3601121dd01d1626a1e23e37211e3254c1c06c | v6.4.0 |
actions/cache | 668228422ae6a00e4ad889ee87cd7109ec5666a7 | v5.0.4 |
For actions not in this table — always fetch the current SHA via API before applying.
If files provided → audit those files. Otherwise:
Resolve base ref in priority order:
baseRefName from the open PR for the current branch (gh pr view --json baseRefName)gh repo view --json defaultBranchRef)main as final fallback — warn the user if this fallback is usedThen collect changed files:
git diff <BASE>..HEAD --name-only
Keep only .yml/.yaml files matching .github/workflows/ or actions/*/action.yml.
Read each file, check all rules above, collect violations.
Fix all auto-fixable violations directly with Edit. Do not ask the user.
Report violations that cannot be auto-fixed (archived-uses, impostor-commit, known-vulnerable-actions, obfuscation, superfluous-actions) — explain why.
Report: files audited, violations found per rule, fixed vs skipped.