Introduce plugin keyless verification #2159
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fixes #1351
Closes #1902
TFLint has a mechanism to verify that plugins installed with
tflint --init
have not been tampered with by a malicious actor. Previously, the only way to do this was for plugin developers to sign the checksum files of their plugin binaries with their PGP key.However, this approach has some problems: First, the plugin developer needs to manage their own PGP key, second, they need to consider how to distribute the public key.
To solve the problems, this PR introduces keyless verification as a new plugin verification mechanism. For the basic idea of keyless verification see below:
The core technologies adopted here are Artifact Attestations and sigstore-go. Artifact attestation is a new feature published by GitHub that stores and distributes Sigstore bundle containing Fulcio-issued certificates and transparency logs corresponding to artifacts (checksum files for plugin binaries). The sigstore-go is a client library that provides policy-based verification of Sigstore bundles and is already adopted by
gh attestation verify
.Keyless verification ensures that the artifact was built by the GitHub Actions workflow for that repository. More specifically, it verifies that the SAN of the Fulcio-issued certificate matches the prefix of the plugin's
source
attribute. It is important to note that this approach differs from traditional ones in that it does not rely on trusting the signer. In this respect, it is weaker than the PGP approach, since an attacker could release a valid plugin simply by taking control of the repository.This feature is introduced as an experimental feature, in other words, TFLint will only try to verify a plugin by artifact attestations if it is not signed with a PGP key. This means that official plugins (e.g. tflint-ruleset-aws), or that are already signed with a PGP key are not affected by this change. Even if there is no artifact attestation, there will be no error but just a warning "Plugin not verified" as before.
Here's a flowchart to help you understand if you're affected by this change:
Third-party plugin developers can immediately benefit from this feature by simply adding
actions/attest-build-provenance
to their GitHub Actions release workflow. Please refer to terraform-linters/tflint-ruleset-template#103 as an example PR. If you have already created a plugin from the latest template repository, make sure the repository has artifact attestations.In the future, I plan to remove the built-in PGP key and migrate to this mechanism for official plugins. To test this behavior, this PR introduces a new
TFLINT_EXPERIMENTAL
environment variable. Running TFLint withTFLINT_EXPERIMENTAL=true
will ignore the built-in keys for official plugins and use artifact attestations for verification, and will error out installation of third-party plugins that are not verified by PGP keys or artifact attestations. This way is inspired byCOSIGN_EXPERIMENTAL
. I also considered adding the new option to theplugin
block instead of an environment variable, but I wasn't sure if we would still need it, so I went with this approach.