From 01bb19bf6ed033a59e384013c7cc215f5724bdaf Mon Sep 17 00:00:00 2001 From: Matthias Bertschy Date: Sat, 31 Jan 2026 10:21:52 +0100 Subject: [PATCH] Add krew plugin manifest Signed-off-by: Matthias Bertschy --- .github/workflows/02-release.yaml | 6 + .goreleaser.yaml | 1 + .krew.yaml | 60 +++++++ KREW_RELEASE.md | 273 ++++++++++++++++++++++++++++++ 4 files changed, 340 insertions(+) create mode 100644 .krew.yaml create mode 100644 KREW_RELEASE.md diff --git a/.github/workflows/02-release.yaml b/.github/workflows/02-release.yaml index c71dda30..79d83257 100644 --- a/.github/workflows/02-release.yaml +++ b/.github/workflows/02-release.yaml @@ -103,6 +103,12 @@ jobs: REGISTRY_USERNAME: ${{ secrets.REGISTRY_USERNAME }} REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }} + - name: Update new version in krew-index + if: github.event_name != 'workflow_dispatch' || inputs.skip_publish != true + uses: rajatjindal/krew-release-bot@v0.0.47 + with: + krew_template_file: .krew.yaml + - name: List collected system-test results (debug) if: always() run: | diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 0863e7a1..4da771ba 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -18,6 +18,7 @@ archives: - id: cli ids: - cli + formats: - binary - tar.gz diff --git a/.krew.yaml b/.krew.yaml new file mode 100644 index 00000000..0d32d68a --- /dev/null +++ b/.krew.yaml @@ -0,0 +1,60 @@ +apiVersion: krew.googlecontainertools.github.com/v1alpha2 +kind: Plugin +metadata: + name: kubescape +spec: + version: {{ .TagName }} + platforms: + - selector: + matchLabels: + os: linux + arch: amd64 + {{ $version := trimPrefix "v" .TagName }}{{ addURIAndSha "https://github.com/kubescape/kubescape/releases/download/" .TagName (printf "kubescape_%s_linux_amd64.tar.gz" $version) .TagName }} + bin: kubescape + - selector: + matchLabels: + os: linux + arch: arm64 + {{ $version := trimPrefix "v" .TagName }}{{ addURIAndSha "https://github.com/kubescape/kubescape/releases/download/" .TagName (printf "kubescape_%s_linux_arm64.tar.gz" $version) .TagName }} + bin: kubescape + - selector: + matchLabels: + os: darwin + arch: amd64 + {{ $version := trimPrefix "v" .TagName }}{{ addURIAndSha "https://github.com/kubescape/kubescape/releases/download/" .TagName (printf "kubescape_%s_darwin_amd64.tar.gz" $version) .TagName }} + bin: kubescape + - selector: + matchLabels: + os: darwin + arch: arm64 + {{ $version := trimPrefix "v" .TagName }}{{ addURIAndSha "https://github.com/kubescape/kubescape/releases/download/" .TagName (printf "kubescape_%s_darwin_arm64.tar.gz" $version) .TagName }} + bin: kubescape + - selector: + matchLabels: + os: windows + arch: amd64 + {{ $version := trimPrefix "v" .TagName }}{{ addURIAndSha "https://github.com/kubescape/kubescape/releases/download/" .TagName (printf "kubescape_%s_windows_amd64.tar.gz" $version) .TagName }} + bin: kubescape.exe + - selector: + matchLabels: + os: windows + arch: arm64 + {{ $version := trimPrefix "v" .TagName }}{{ addURIAndSha "https://github.com/kubescape/kubescape/releases/download/" .TagName (printf "kubescape_%s_windows_arm64.tar.gz" $version) .TagName }} + bin: kubescape.exe + shortDescription: Scan resources and cluster configs against security frameworks. + description: | + Kubescape is the first tool for testing if Kubernetes is deployed securely + according to mitigations and best practices. It includes risk analysis, + security compliance, and misconfiguration scanning with an easy-to-use + CLI interface, flexible output formats, and automated scanning capabilities. + + Features: + - Risk analysis: Identify vulnerabilities and security risks in your cluster + - Security compliance: Check your cluster against multiple security frameworks + - Misconfiguration scanning: Detect security misconfigurations in your workloads + - Flexible output: Results in JSON, SARIF, HTML, JUnit, and Prometheus formats + - CI/CD integration: Easily integrate into your CI/CD pipeline + homepage: https://kubescape.io/ + caveats: | + Requires kubectl and basic knowledge of Kubernetes. + Run 'kubescape scan' to scan your Kubernetes cluster or manifests. diff --git a/KREW_RELEASE.md b/KREW_RELEASE.md new file mode 100644 index 00000000..f8c4f4d6 --- /dev/null +++ b/KREW_RELEASE.md @@ -0,0 +1,273 @@ +# Krew Release Automation Guide + +This document explains how kubescape automates publishing to the Kubernetes plugin package manager, krew. + +## What is Krew? + +Krew is a plugin manager for `kubectl`. It allows users to discover and install `kubectl` plugins easily. You can learn more about krew at [https://krew.sigs.k8s.io/](https://krew.sigs.k8s.io/). + +## How kubescape publishes to krew + +We use the [krew-release-bot](https://github.com/rajatjindal/krew-release-bot) to automatically create pull requests to the [kubernetes-sigs/krew-index](https://github.com/kubernetes-sigs/krew-index) repository whenever a new release of kubescape is published. + +### Setup Overview + +The automation consists of three components: + +1. **`.krew.yaml`** - A template file that the bot uses to generate the krew plugin manifest +2. **`.github/workflows/02-release.yaml`** - GitHub Actions workflow that runs the krew-release-bot after a successful release +3. **`.goreleaser.yaml`** - GoReleaser configuration that defines the krew manifest (though upload is skipped) + +### Why Use krew-release-bot Instead of GoReleaser's Built-in Krew Support? + +You might have noticed that **GoReleaser has built-in krew support** in its `krews` section. However, almost all projects (including stern) use `skip_upload: true` and rely on **krew-release-bot** instead. Here's why: + +#### Problems with GoReleaser's Built-in Krew Publishing + +To use GoReleaser's direct krew publishing, you would need to: + +```yaml +krews: + - name: kubescape + skip_upload: false # Instead of true + repository: + owner: kubernetes-sigs + name: krew-index + token: "{{ .Env.KREW_INDEX_TOKEN }}" # Required! + pull_request: + enabled: true # Requires GoReleaser Pro for cross-repo PRs +``` + +This approach has several critical issues: + +1. **Permission Barrier**: Almost no one has write access to `kubernetes-sigs/krew-index`. You would need special permissions from the Krew maintainers, which is rarely granted. + +2. **Security Risk**: You'd need to store a GitHub personal access token with write access to the krew-index in your repository secrets. This token could be compromised and used to make unauthorized changes to the krew-index. + +3. **GoReleaser Pro Required**: To create pull requests to a different repository (cross-repository), you need GoReleaser Pro, which is a paid product. + +4. **Manual Work**: Even if you had access, you'd need to manually configure and maintain the repository settings, tokens, and potentially deal with rate limits and authentication issues. + +#### Why krew-release-bot is the Right Solution + +The **krew-release-bot** was created by the Kubernetes community (in collaboration with the Krew team) specifically to solve these problems: + +- **No Repository Access Required**: The bot acts as an intermediary with pre-configured access to krew-index. You don't need write permissions. + +- **No Tokens Needed**: It uses GitHub's `GITHUB_TOKEN` (automatically available in GitHub Actions) via webhooks and events. No personal access tokens required. + +- **Designed for Krew**: It's specifically built for the krew-index workflow and integrates with Krew's automation. + +- **Automatic Merging**: The Krew team has configured their CI to automatically test and merge PRs from krew-release-bot (usually within 5-10 minutes). + +- **Officially Recommended**: The Krew team explicitly recommends this approach in their documentation as the standard way to automate plugin updates. + +- **Free and Open Source**: No paid subscriptions required. + +#### The Real-World Evidence + +Looking at recent pull requests to `kubernetes-sigs/krew-index`, **almost all automated plugin updates are created by krew-release-bot**. You'll see patterns like: + +``` +Author: krew-release-bot +Title: "release new version v0.6.11 of radar" +``` + +This demonstrates that the entire Kubernetes ecosystem has standardized on krew-release-bot, not GoReleaser's built-in publishing. + +#### Summary + +While GoReleaser's built-in krew support exists in the code, it's **practically unusable for the krew-index repository** due to permission and security constraints. The krew-release-bot is the de facto standard because: +- It works without special permissions +- It's more secure +- It integrates with Krew's automation +- It's free and recommended by the Krew team + +This is why we use `skip_upload: true` in GoReleaser and let krew-release-bot handle the actual publishing. + +### The Template File + +The `.krew.yaml` file in the repository root is a Go template that contains placeholders for dynamic values: + +```yaml +apiVersion: krew.googlecontainertools.github.com/v1alpha2 +kind: Plugin +metadata: + name: kubescape +spec: + version: {{ .TagName }} + platforms: + - selector: + matchLabels: + os: linux + arch: amd64 + {{ $version := trimPrefix "v" .TagName }}{{ addURIAndSha "https://github.com/kubescape/kubescape/releases/download/" .TagName (printf "kubescape_%s_linux_amd64.tar.gz" $version) .TagName }} + bin: kubescape + - selector: + matchLabels: + os: linux + arch: arm64 + {{ $version := trimPrefix "v" .TagName }}{{ addURIAndSha "https://github.com/kubescape/kubescape/releases/download/" .TagName (printf "kubescape_%s_linux_arm64.tar.gz" $version) .TagName }} + bin: kubescape + - selector: + matchLabels: + os: darwin + arch: amd64 + {{ $version := trimPrefix "v" .TagName }}{{ addURIAndSha "https://github.com/kubescape/kubescape/releases/download/" .TagName (printf "kubescape_%s_darwin_amd64.tar.gz" $version) .TagName }} + bin: kubescape + - selector: + matchLabels: + os: darwin + arch: arm64 + {{ $version := trimPrefix "v" .TagName }}{{ addURIAndSha "https://github.com/kubescape/kubescape/releases/download/" .TagName (printf "kubescape_%s_darwin_arm64.tar.gz" $version) .TagName }} + bin: kubescape + - selector: + matchLabels: + os: windows + arch: amd64 + {{ $version := trimPrefix "v" .TagName }}{{ addURIAndSha "https://github.com/kubescape/kubescape/releases/download/" .TagName (printf "kubescape_%s_windows_amd64.tar.gz" $version) .TagName }} + bin: kubescape.exe + - selector: + matchLabels: + os: windows + arch: arm64 + {{ $version := trimPrefix "v" .TagName }}{{ addURIAndSha "https://github.com/kubescape/kubescape/releases/download/" .TagName (printf "kubescape_%s_windows_arm64.tar.gz" $version) .TagName }} + bin: kubescape.exe + shortDescription: Scan resources and cluster configs against security frameworks. + description: | + Kubescape is the first tool for testing if Kubernetes is deployed securely + according to mitigations and best practices. It includes risk analysis, + security compliance, and misconfiguration scanning with an easy-to-use + CLI interface, flexible output formats, and automated scanning capabilities. + + Features: + - Risk analysis: Identify vulnerabilities and security risks in your cluster + - Security compliance: Check your cluster against multiple security frameworks + - Misconfiguration scanning: Detect security misconfigurations in your workloads + - Flexible output: Results in JSON, SARIF, HTML, JUnit, and Prometheus formats + - CI/CD integration: Easily integrate into your CI/CD pipeline + homepage: https://kubescape.io/ + caveats: | + Requires kubectl and basic knowledge of Kubernetes. + Run 'kubescape scan' to scan your Kubernetes cluster or manifests. +``` + +The `{{ .TagName }}` is replaced with the release tag (e.g., `v3.0.0`), `{{ trimPrefix "v" .TagName }}` removes the version prefix, and `{{ addURIAndSha ... }}` calculates the SHA256 checksum for the binary archive. + +### Release Workflow + +The release workflow (`.github/workflows/02-release.yaml`) can be triggered in two ways: + +1. **Automatic**: When a new tag matching the pattern `v[0-9]+.[0-9]+.[0-9]+` is pushed to the repository +2. **Manual**: Via `workflow_dispatch` with an optional `skip_publish` input + +When the workflow is triggered: + +1. GoReleaser builds and publishes the release artifacts (unless `skip_publish=true` is set) +2. The krew-release-bot step runs conditionally: + - It **runs** when triggered by a tag push OR by `workflow_dispatch` with `skip_publish=false` + - It **skips** when triggered by `workflow_dispatch` with `skip_publish=true` (default) +3. When it runs, the bot: + - Reads the `.krew.yaml` template + - Fills in the template with release information + - Creates a pull request to the `kubernetes-sigs/krew-index` repository + - The PR is automatically tested and merged by krew's infrastructure + +### Workflow Permissions + +The release job has the following permissions: + +```yaml +permissions: + actions: read + checks: read + contents: write + deployments: read + discussions: read + id-token: write + issues: read + models: read + packages: write + pages: read + pull-requests: read + repository-projects: read + statuses: read + security-events: read + attestations: read + artifact-metadata: read +``` + +These permissions are necessary for GoReleaser to create releases and upload artifacts. + +### Testing the Template + +Before committing changes to `.krew.yaml`, you can test how the template will be rendered using Docker: + +```bash +docker run -v $(pwd)/.krew.yaml:/tmp/.krew.yaml ghcr.io/rajatjindal/krew-release-bot:v0.0.47 \ + krew-release-bot template --tag v3.0.0 --template-file /tmp/.krew.yaml +``` + +This will output the generated krew manifest file, allowing you to verify: +- The version field is correct +- All download URLs are properly formatted +- The SHA256 checksum will be calculated correctly + +### Why skip_upload in GoReleaser? + +In `.goreleaser.yaml`, the `krews` section has `skip_upload: true`: + +```yaml +krews: + - name: kubescape + ids: + - cli + skip_upload: true # We use krew-release-bot instead + homepage: https://kubescape.io/ + description: It includes risk analysis, security compliance, and misconfiguration scanning with an easy-to-use CLI interface, flexible output formats, and automated scanning capabilities. + short_description: Scan resources and cluster configs against security frameworks. +``` + +This is intentional because: +- GoReleaser generates the manifest but doesn't have built-in support for submitting PRs to krew-index +- krew-release-bot is the recommended tool for krew automation by the Krew team +- Using krew-release-bot provides automatic testing and merging of version bump PRs + +### Manual Release Testing + +You can test the release workflow manually without publishing to krew by using `workflow_dispatch`: + +1. Go to Actions tab in GitHub +2. Select "02-create_release" workflow +3. Click "Run workflow" +4. The `skip_publish` input defaults to `true` (publishing will be skipped) +5. Set `skip_publish` to `false` if you want to test the full release process including krew indexing + +### Making Changes to the Template + +If you need to update the krew manifest (e.g., change the description, add platforms, or update the binary location): + +1. Edit the `.krew.yaml` file +2. Test your changes with the Docker command shown above +3. Commit and push the changes +4. The next release will use the updated template + +### Installing kubescape via krew + +Once the plugin is indexed in krew, users can install it with: + +```bash +kubectl krew install kubernetes-sigs/kubescape +``` + +Or after index update: + +```bash +kubectl krew install kubescape +``` + +### Further Reading + +- [Krew official documentation](https://krew.sigs.k8s.io/docs/developer-guide/) +- [krew-release-bot repository](https://github.com/rajatjindal/krew-release-bot) +- [Krew plugin submission guide](https://krew.sigs.k8s.io/docs/developer-guide/develop/plugins/) \ No newline at end of file