Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 0 additions & 22 deletions .github/workflows/scan.yml

This file was deleted.

39 changes: 39 additions & 0 deletions .github/workflows/security-scan.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Weekly security scan

on:
schedule:
# Cron for every Monday at 12:00 UTC.
- cron: "0 12 * * 1"
workflow_dispatch:
inputs:
branch:
description: 'Branch to scan'
required: false
default: 'main'
type: string

# Remove all permissions from GITHUB_TOKEN except metadata.
permissions: {}

jobs:
scan:
strategy:
fail-fast: false
matrix:
branch: [ ${{ inputs.branch || 'main' }} ]
name: Trivy
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2
with:
ref: ${{ matrix.branch }}
- name: Calculate go version
id: vars
run: echo "go_version=$(make go-version)" >> $GITHUB_OUTPUT
- name: Set up Go
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # tag=v5.5.0
with:
go-version: ${{ steps.vars.outputs.go_version }}
- name: Run verify security target
run: make verify-security
37 changes: 36 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,8 @@ RELEASE_NOTES_VER := v0.18.0
RELEASE_NOTES_BIN := release-notes
RELEASE_NOTES := $(TOOLS_BIN_DIR)/$(RELEASE_NOTES_BIN)-$(RELEASE_NOTES_VER)

TRIVY_VER := 0.64.0
Copy link
Contributor

Choose a reason for hiding this comment

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

wouldn't it be nice if there were a way to integrate general purpose tool binary installs into dependabot? seems that's an unsolved problem https://docs.github.com/en/code-security/dependabot/ecosystems-supported-by-dependabot/supported-ecosystems-and-repositories#supported-ecosystems-and-repositories

Copy link
Contributor

Choose a reason for hiding this comment

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

actually for trivy maybe we can use docker run?

(not blocking this PR, just thinking out loud)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

for trivy maybe we can use docker run?

Sure, that would probably be cleaner. I was just trying to minimize the delta between these same scripts here and in CAPI and CAPZ.


YQ_VER := v4.35.2
YQ_BIN := yq
YQ := $(abspath $(TOOLS_BIN_DIR)/$(YQ_BIN)-$(YQ_VER))
Expand Down Expand Up @@ -203,6 +205,11 @@ TILT_PREPARE := $(abspath $(TOOLS_BIN_DIR)/$(TILT_PREPARE_BIN))
GOLANGCI_LINT_BIN := golangci-lint
GOLANGCI_LINT := $(abspath $(TOOLS_BIN_DIR)/$(GOLANGCI_LINT_BIN))

GOVULNCHECK_BIN := govulncheck
GOVULNCHECK_VER := v1.1.4
GOVULNCHECK := $(abspath $(TOOLS_BIN_DIR)/$(GOVULNCHECK_BIN)-$(GOVULNCHECK_VER))
GOVULNCHECK_PKG := golang.org/x/vuln/cmd/govulncheck

HELM_VER := $(call get_go_version,helm.sh/helm/v3)
HELM_BIN := helm
HELM := $(TOOLS_BIN_DIR)/$(HELM_BIN)-$(HELM_VER)
Expand Down Expand Up @@ -262,6 +269,9 @@ all: test manager
help: # Display this help
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n"} /^[0-9A-Za-z_-]+:.*?##/ { printf " \033[36m%-45s\033[0m %s\n", $$1, $$2 } /^\$$\([0-9A-Za-z_-]+\):.*?##/ { gsub("_","-", $$1); printf " \033[36m%-45s\033[0m %s\n", tolower(substr($$1, 3, length($$1)-7)), $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)

go-version: ## Print the go version we use to compile our binaries and images
@echo $(GO_VERSION)

## --------------------------------------
## Generate / Manifests
## --------------------------------------
Expand Down Expand Up @@ -384,7 +394,26 @@ verify-shellcheck: ## Verify shell files

.PHONY: verify-container-images
verify-container-images: ## Verify container images
TRACE=$(TRACE) ./hack/verify-container-images.sh
TRACE=$(TRACE) ./hack/verify-container-images.sh $(TRIVY_VER)

.PHONY: verify-govulncheck
verify-govulncheck: $(GOVULNCHECK) ## Verify code for vulnerabilities
$(GOVULNCHECK) ./... && R1=$$? || R1=$$?; \
$(GOVULNCHECK) -C "$(TOOLS_DIR)" ./... && R2=$$? || R2=$$?; \
$(GOVULNCHECK) -C "$(TEST_DIR)" ./... && R3=$$? || R3=$$?; \
if [ "$$R1" -ne "0" ] || [ "$$R2" -ne "0" ] || [ "$$R3" -ne "0" ]; then \
exit 1; \
fi

.PHONY: verify-security
verify-security: ## Verify code and images for vulnerabilities
$(MAKE) verify-container-images && R1=$$? || R1=$$?; \
$(MAKE) verify-govulncheck && R2=$$? || R2=$$?; \
if [ "$$R1" -ne "0" ] || [ "$$R2" -ne "0" ]; then \
echo "Check for vulnerabilities failed! There are vulnerabilities to be fixed"; \
exit 1; \
fi


## --------------------------------------
## Binaries
Expand Down Expand Up @@ -759,6 +788,12 @@ $(TILT_PREPARE_BIN): $(TILT_PREPARE) ## Build a local copy of tilt-prepare.
.PHONY: $(GOLANGCI_LINT_BIN)
$(GOLANGCI_LINT_BIN): $(GOLANGCI_LINT) ## Build a local copy of golangci-lint

.PHONY: $(GOVULNCHECK_BIN)
$(GOVULNCHECK_BIN): $(GOVULNCHECK) ## Build a local copy of govulncheck.

$(GOVULNCHECK): # Build govulncheck.
GOBIN=$(TOOLS_BIN_DIR) $(GO_INSTALL) $(GOVULNCHECK_PKG) $(GOVULNCHECK_BIN) $(GOVULNCHECK_VER)

.PHONY: $(GINKGO_BIN)
$(GINKGO_BIN): $(GINKGO) ## Build a local copy of ginkgo

Expand Down
57 changes: 57 additions & 0 deletions hack/ensure-trivy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/bin/bash

# Copyright 2025 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

set -o errexit
set -o nounset
set -o pipefail

if [[ "${TRACE-0}" == "1" ]]; then
set -o xtrace
fi

VERSION=${1}

GO_OS="$(go env GOOS)"
if [[ "${GO_OS}" == "linux" ]]; then
TRIVY_OS="Linux"
elif [[ "${GO_OS}" == "darwin"* ]]; then
TRIVY_OS="macOS"
fi

GO_ARCH="$(go env GOARCH)"
if [[ "${GO_ARCH}" == "amd" ]]; then
TRIVY_ARCH="32bit"
elif [[ "${GO_ARCH}" == "amd64"* ]]; then
TRIVY_ARCH="64bit"
elif [[ "${GO_ARCH}" == "arm" ]]; then
TRIVY_ARCH="ARM"
elif [[ "${GO_ARCH}" == "arm64" ]]; then
TRIVY_ARCH="ARM64"
fi

TOOL_BIN=hack/tools/bin
mkdir -p ${TOOL_BIN}
Comment on lines +45 to +46
Copy link

Copilot AI Sep 30, 2025

Choose a reason for hiding this comment

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

Variables should be quoted to handle paths with spaces. Change to TOOL_BIN="hack/tools/bin" and mkdir -p "${TOOL_BIN}".

Suggested change
TOOL_BIN=hack/tools/bin
mkdir -p ${TOOL_BIN}
TOOL_BIN="hack/tools/bin"
mkdir -p "${TOOL_BIN}"

Copilot uses AI. Check for mistakes.

TRIVY="${TOOL_BIN}/trivy/${VERSION}/trivy"

# Downloads trivy scanner
if [ ! -f "$TRIVY" ]; then
curl -L -o "${TOOL_BIN}/trivy.tar.gz" "https://github.com/aquasecurity/trivy/releases/download/v${VERSION}/trivy_${VERSION}_${TRIVY_OS}-${TRIVY_ARCH}.tar.gz"
mkdir -p "${TOOL_BIN}/trivy/${VERSION}"
tar -xf "${TOOL_BIN}/trivy.tar.gz" -C "${TOOL_BIN}/trivy/${VERSION}" trivy
chmod +x "${TOOL_BIN}/trivy/${VERSION}/trivy"
rm "${TOOL_BIN}/trivy.tar.gz"
fi
36 changes: 7 additions & 29 deletions hack/verify-container-images.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,51 +22,29 @@ if [[ "${TRACE-0}" == "1" ]]; then
set -o xtrace
fi

TRIVY_VERSION=0.34.0

GO_OS="$(go env GOOS)"
if [[ "${GO_OS}" == "linux" ]]; then
TRIVY_OS="Linux"
elif [[ "${GO_OS}" == "darwin"* ]]; then
TRIVY_OS="macOS"
fi

VERSION=${1}
GO_ARCH="$(go env GOARCH)"
if [[ "${GO_ARCH}" == "amd" ]]; then
TRIVY_ARCH="32bit"
elif [[ "${GO_ARCH}" == "amd64"* ]]; then
TRIVY_ARCH="64bit"
elif [[ "${GO_ARCH}" == "arm" ]]; then
TRIVY_ARCH="ARM"
elif [[ "${GO_ARCH}" == "arm64" ]]; then
TRIVY_ARCH="ARM64"
fi

TOOL_BIN=hack/tools/bin
mkdir -p ${TOOL_BIN}

# Downloads trivy scanner
curl -L -o ${TOOL_BIN}/trivy.tar.gz "https://github.com/aquasecurity/trivy/releases/download/v${TRIVY_VERSION}/trivy_${TRIVY_VERSION}_${TRIVY_OS}-${TRIVY_ARCH}.tar.gz"
REPO_ROOT=$(git rev-parse --show-toplevel)
"${REPO_ROOT}/hack/ensure-trivy.sh" "${VERSION}"

tar -xf "${TOOL_BIN}/trivy.tar.gz" -C "${TOOL_BIN}" trivy
chmod +x ${TOOL_BIN}/trivy
rm ${TOOL_BIN}/trivy.tar.gz
TRIVY="${REPO_ROOT}/hack/tools/bin/trivy/${VERSION}/trivy"

# Builds all the container images to be scanned and cleans up changes to ./*manager_image_patch.yaml ./*manager_pull_policy.yaml.
make REGISTRY=gcr.io/k8s-staging-cluster-api-helm PULL_POLICY=IfNotPresent TAG=dev docker-build
make clean-release-git

# Scan the images
${TOOL_BIN}/trivy image -q --exit-code 1 --ignore-unfixed --severity MEDIUM,HIGH,CRITICAL gcr.io/k8s-staging-cluster-api-helm/cluster-api-helm-controller-"${GO_ARCH}":dev && R5=$? || R5=$?
"${TRIVY}" image -q --exit-code 1 --ignore-unfixed --severity MEDIUM,HIGH,CRITICAL gcr.io/k8s-staging-cluster-api-helm/cluster-api-helm-controller-"${GO_ARCH}":dev && R1=$? || R1=$?

echo ""
BRed='\033[1;31m'
BGreen='\033[1;32m'
NC='\033[0m' # No

if [ "$R1" -ne "0" ] || [ "$R2" -ne "0" ] || [ "$R3" -ne "0" ] || [ "$R4" -ne "0" ] || [ "$R5" -ne "0" ] || [ "$R6" -ne "0" ]
if [ "$R1" -ne "0" ]
then
echo -e "${BRed}Check container images failed! There are vulnerability to be fixed${NC}"
echo -e "${BRed}Check container images failed! There are vulnerabilities to be fixed${NC}"
exit 1
fi

Expand Down
Loading