You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A reusable workflow, crs-plugin-release.yaml, that attests a plugin's release artifacts with actions/attest-build-provenance, so a downloaded plugin can be verified with gh attestation verify before anything loads its rules.
Same technique as coreruleset/coreruleset#4750, which adds provenance to CRS releases, applied to the plugins — and living here so each plugin repository keeps the one line caller that crs-plugin-integration.yaml and crs-plugin-lint.yaml already established.
Why
Plugin releases carry nothing verifiable today. Sampling the two most used:
Only GitHub's auto-attached source archives exist, with no signature and no attestation, so anyone consuming a plugin is trusting the tag and the transport.
That is the blocker on coreruleset/modsecurity-crs-docker#470, which proposes installing plugins into the container from a CRS_PLUGINS variable. The images gpg --verify the CRS tarball against the CRS signing key; adding plugin rules to the same engine with no equivalent check would be a step down in the trust chain, and four registry entries are third-party repositories. coreruleset/plugin-registry#21 puts signing out of scope for its first iteration, which leaves a gap that provenance fills without needing a key at all.
GPG is the wrong tool for 30 repositories: it means a private key per plugin owner, or one shared key with wide distribution. Provenance attestations are keyless and tie an artifact to the workflow and commit that produced it, which is the property an installer actually wants to check.
Shape
Triggered on release: published in the calling repository:
take the source archives GitHub attaches to the release, as feat: attest release artifacts with build provenance coreruleset#4750 does, rather than rebuilding them — zip and tar archives embed mtimes and permissions, so an independently rebuilt copy would not match the hash of what people download
Verification inside a container.gh attestation verify needs the gh binary, which the CRS images do not ship; cosign verify-blob-attestation is the other option and is another binary to add and keep current. Whatever #470 ends up doing has to pick one, so it is worth deciding here what the documented verification command is.
Rollout. 18 plugin repositories are mid-migration to the reusable workflows already. Attestation only helps a consumer once the plugins it installs have it, so the installer needs a policy for plugins that do not yet — refuse, or warn.
Does the registry record it?Move the plugin registry list to a different format plugin-registry#21 is designing registry.yaml. A field saying whether a plugin's releases are attested would let an installer decide before it downloads anything, instead of discovering it afterwards.
Scope. Provenance says which workflow built an artifact. It does not say the rules are safe, and the registry already documents that it attests range allocation and review rather than a code audit. Worth stating plainly so downstream tooling does not over-read a green check.
What
A reusable workflow,
crs-plugin-release.yaml, that attests a plugin's release artifacts withactions/attest-build-provenance, so a downloaded plugin can be verified withgh attestation verifybefore anything loads its rules.Same technique as coreruleset/coreruleset#4750, which adds provenance to CRS releases, applied to the plugins — and living here so each plugin repository keeps the one line caller that
crs-plugin-integration.yamlandcrs-plugin-lint.yamlalready established.Why
Plugin releases carry nothing verifiable today. Sampling the two most used:
Only GitHub's auto-attached source archives exist, with no signature and no attestation, so anyone consuming a plugin is trusting the tag and the transport.
That is the blocker on coreruleset/modsecurity-crs-docker#470, which proposes installing plugins into the container from a
CRS_PLUGINSvariable. The imagesgpg --verifythe CRS tarball against the CRS signing key; adding plugin rules to the same engine with no equivalent check would be a step down in the trust chain, and four registry entries are third-party repositories. coreruleset/plugin-registry#21 puts signing out of scope for its first iteration, which leaves a gap that provenance fills without needing a key at all.GPG is the wrong tool for 30 repositories: it means a private key per plugin owner, or one shared key with wide distribution. Provenance attestations are keyless and tie an artifact to the workflow and commit that produced it, which is the property an installer actually wants to check.
Shape
Triggered on
release: publishedin the calling repository:actions/attest-build-provenanceagainst thempermissions: { id-token: write, attestations: write, contents: read }, and nothing elseCaller, per plugin repository:
Open questions
gh attestation verifyneeds theghbinary, which the CRS images do not ship;cosign verify-blob-attestationis the other option and is another binary to add and keep current. Whatever #470 ends up doing has to pick one, so it is worth deciding here what the documented verification command is.registry.yaml. A field saying whether a plugin's releases are attested would let an installer decide before it downloads anything, instead of discovering it afterwards.Refs