Skip to content

feat(zizmor): add Zizmor config validation#1877

Open
mikefat wants to merge 8 commits intomainfrom
mikefat/AddZizmorConfigValidation
Open

feat(zizmor): add Zizmor config validation#1877
mikefat wants to merge 8 commits intomainfrom
mikefat/AddZizmorConfigValidation

Conversation

@mikefat
Copy link
Copy Markdown

@mikefat mikefat commented Apr 15, 2026

This PR adds a step in the reusable zizmor action that will pre-validate the zizmor config file to be used in the run. If validation fails, the job stops and zizmor is not executed.

The validation will fail on any file that does any of the following:

  • Defines any of these audit blocks under rules (no disable, ignore, or config is allowed): insecure-commands, template-injection, impostor-commit, known-vulnerable-actions, ref-confusion.
  • Sets rules.unpinned-uses.disable
  • Sets rules.unpinned-uses.config.policies with a universal "*": any entry (all uses: clauses may stay unpinned). Scoped policies such as actions/*: any or grafana/*: any remain valid.

Any other suggestions for things to be on the lookout/block are welcome

@mikefat mikefat requested a review from a team as a code owner April 15, 2026 13:30
@mikefat mikefat changed the title Add Zizmor config validation feat(zizmor): Add Zizmor config validation Apr 15, 2026
@mikefat mikefat changed the title feat(zizmor): Add Zizmor config validation feat(zizmor): add Zizmor config validation Apr 15, 2026
@mikefat mikefat added the github_actions Pull requests that update GitHub Actions code label Apr 15, 2026
@mikefat
Copy link
Copy Markdown
Author

mikefat commented Apr 15, 2026

Testing this changes in the private repo here and it seems to be working as expected 👍

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a policy gate to the reusable Zizmor workflow to pre-validate repo-local zizmor.yml / .github/zizmor.yml files before running zizmor, preventing configurations that weaken required security audits/pinning rules.

Changes:

  • Emit a repo_local_zizmor_config step output when a repo-local zizmor config is discovered.
  • Add a new validation step that parses the repo-local config and fails the job if forbidden rules/policies are present.
  • Document the new repo-local config policy gate behavior and rejection rules.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
.github/workflows/reusable-zizmor.yml Adds repo-local config output plus a Python-based validation step gating zizmor execution.
.github/workflows/reusable-zizmor.md Documents when the gate runs/skips and which config patterns are rejected.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .github/workflows/reusable-zizmor.md Outdated
Comment thread .github/workflows/reusable-zizmor.yml Outdated
Comment thread .github/workflows/reusable-zizmor.yml Outdated
Comment thread .github/workflows/reusable-zizmor.yml Outdated
Comment thread .github/workflows/reusable-zizmor.yml Outdated
Comment thread .github/workflows/reusable-zizmor.yml Outdated

cfg = unpinned.get("config")
if cfg is None:
return
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While the current implementation of the early returns appears to be correct, this is very fragile. Please at least create unittests here or move the whole step into a standalone action where you can have proper testing.

@github-actions

This comment has been minimized.

Comment thread .github/workflows/reusable-zizmor.yml Fixed
Copy link
Copy Markdown
Contributor

@ezebunandu ezebunandu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice to add a testcase for catching multiple violations in one config, I think. Also nit, but could add tests for the other two forbidden audits.

Test cases to document that the silent pass for when there's no config file or no rules in the config file would be nice too, but that's a nittier nit -:)

Copy link
Copy Markdown
Member

@kleimkuhler kleimkuhler left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looking good. Just a doc comment right now

Comment thread .github/workflows/reusable-zizmor.md
Copy link
Copy Markdown
Contributor

@ezebunandu ezebunandu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

pyyaml_version:
description: PyYAML version passed to uv run --with.
required: false
# renovate: datasource=pypi depName=pyyaml
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not 100% certain that this will work. The renovate config here currently uses the following pattern:

    {
      customType: "regex",
      managerFilePatterns: [
        "/(?:^|/)\\.github/(?:workflows|actions)/.+\\.ya?ml$/",
        "/(?:^|/)action\\.ya?ml$/",
      ],
      matchStrings: [
        "# renovate: datasource=(?<datasource>[a-z-.]+?) depName=(?<depName>[^\\s]+?)(?: (?:lookupName|packageName)=(?<packageName>[^\\s]+?))?(?: versioning=(?<versioning>[^\\s]+?))?(?: extractVersion=(?<extractVersion>[^\\s]+?))?\\s+[A-Za-z0-9_-]+[_-](?:VERSION|version)\\s*[:=]\\s*[\"']?(?<currentValue>[^\"'@\\n]+)(?:@(?<currentDigest>sha256:[a-f0-9]+))?[\"']?",
      ],
    },

Based on that the line including the version number would need to have a format like this:

SOMETHIGN_VERSION: "1.2.3"

Instead, you could set the input to be empty by default and then set the "default" version down below when you inject the PYYAML_VERSION into the process.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for all your comments! Just pushed some more changes

- name: Unit tests
run: |
cd actions/validate-zizmor-config
uv run --with pyyaml==6.0.2 python3 -m unittest discover -v
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also auto-update this version

@kleimkuhler kleimkuhler self-requested a review April 21, 2026 15:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

github_actions Pull requests that update GitHub Actions code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants