Skip to content
Closed
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
38 changes: 37 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ jobs:
steps:
- uses: actions/checkout@v4
- uses: azure/setup-helm@v4
- run: helm plugin install https://github.com/helm-unittest/helm-unittest
- run: helm plugin install --verify=false https://github.com/helm-unittest/helm-unittest
- run: helm lint charts/kilo-clustermesh-operator --strict
- run: helm unittest charts/kilo-clustermesh-operator

Expand All @@ -70,3 +70,39 @@ jobs:
go-version: "1.26.3"
- run: make manifests generate
- run: git diff --exit-code

image:
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
needs: [lint, test, build, helm, generate, integration]
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/setup-buildx-action@v3
- uses: docker/metadata-action@v5
id: meta
with:
images: ghcr.io/${{ github.repository }}
tags: |
type=raw,value=main
type=sha,prefix=sha-,format=long
- uses: docker/build-push-action@v6
Comment on lines +83 to +96
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

cat -n .github/workflows/ci.yml

Repository: cozystack/kilo-clustermesh-operator

Length of output: 3825


🌐 Web query:

GitHub Actions security best practices pin commit SHA Docker actions

💡 Result:

Pinning GitHub Actions to a full-length commit SHA is a critical security best practice for protecting your CI/CD supply chain [1][2][3]. Why Pin to a Commit SHA GitHub Actions referenced by tags (e.g., @v4) or branches (e.g., @main) are mutable [4][5][6]. This means an attacker who compromises the action's repository or the maintainer's account can force-push a new commit to that tag, silently changing the code your workflow executes [7][8][9]. Pinning to an immutable, full-length commit SHA ensures that your workflow always runs the exact, audited code you expect, preventing unauthorized code execution [5][6][3]. How to Implement SHA Pinning 1. Identify the current commit SHA: You can retrieve the full SHA for a specific tag using Git commands (e.g., git ls-remote https://github.com/owner/repo tag_name) or by viewing the commit history in the action's repository [1][7]. 2. Update your workflow: Replace the tag in your workflow file with the full SHA [7][8]. 3. Add a version comment: To maintain readability and ease of updates, include the original version tag as a comment next to the SHA [7][8][10]. Example: uses: actions/checkout@11bd719 # v4.2.2 Governance and Enforcement GitHub now supports organization-level and repository-level policies that can enforce SHA pinning [2][10][3]. When enabled, any workflow attempting to use an action referenced by a tag or branch will fail, ensuring compliance across your organization [2][5][10]. Administrators can configure these policies in the GitHub Actions settings for their organization or repository [3]. Maintaining Pinned Actions Because pinned actions do not automatically receive updates, you must manage them manually or via automation [1][9]. Tools like Dependabot or Renovate can be configured to monitor for updates to your pinned actions and automatically open pull requests to update the SHAs, allowing you to review and test changes before merging [1][2][9].

Citations:


Pin the Docker actions to immutable commit SHAs.

Version refs like v3, v5, and v6 float with upstream tag updates. Since this workflow publishes release artifacts to ghcr.io on every push to main, any re-tagging of upstream actions could silently change the image contents without a PR in this repository.

Pin each Docker action to its full commit SHA and include the version tag as a comment for maintainability:

Suggested shape
-      - uses: docker/login-action@v3
+      - uses: docker/login-action@<full-commit-sha> # v3

-      - uses: docker/setup-buildx-action@v3
+      - uses: docker/setup-buildx-action@<full-commit-sha> # v3

-      - uses: docker/metadata-action@v5
+      - uses: docker/metadata-action@<full-commit-sha> # v5

-      - uses: docker/build-push-action@v6
+      - uses: docker/build-push-action@<full-commit-sha> # v6
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/ci.yml around lines 83 - 96, Replace the floating tags for
the Docker actions with immutable commit SHAs: change usages of
docker/login-action@v3, docker/setup-buildx-action@v3, docker/metadata-action@v5
(id: meta) and docker/build-push-action@v6 to their corresponding full
commit@sha values and add the original version (e.g., v3/v5/v6) as a trailing
comment for readability; ensure each action line is updated so the workflow uses
the exact commit SHA to prevent upstream retags from changing behavior.

with:
context: .
file: Containerfile
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
platforms: linux/amd64,linux/arm64
build-args: |
VERSION=main
REVISION=${{ github.sha }}
cache-from: type=gha
cache-to: type=gha,mode=max
1 change: 1 addition & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ linters:
- revive
- gochecknoglobals
- noinlineerr
- goconst
path: _test\.go
- linters:
- err113
Expand Down
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ help: ## Display this help.

.PHONY: manifests
manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects.
"$(CONTROLLER_GEN)" rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases
"$(CONTROLLER_GEN)" rbac:roleName=manager-role webhook paths="./..."
"$(CONTROLLER_GEN)" crd paths="./api/..." output:crd:artifacts:config=config/crd/bases

.PHONY: generate
generate: controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations.
Expand Down
16 changes: 16 additions & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion charts/kilo-clustermesh-operator/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ spec:
image: "{{ .Values.image.repository }}:{{ include "kilo-clustermesh-operator.imageTag" . }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
args:
- "--namespace={{ .Release.Namespace }}"
- "--leader-elect={{ .Values.leaderElect }}"
- "--metrics-bind-address={{ .Values.metricsBindAddress }}"
- "--metrics-secure={{ .Values.metricsSecure }}"
- "--health-probe-bind-address={{ .Values.healthProbeBindAddress }}"
securityContext:
runAsNonRoot: true
Expand Down
22 changes: 14 additions & 8 deletions charts/kilo-clustermesh-operator/tests/deployment_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,6 @@ tests:
path: spec.replicas
value: 2

- it: should pass --namespace arg from release namespace
release:
namespace: test-ns
asserts:
- contains:
path: spec.template.spec.containers[0].args
content: "--namespace=test-ns"

- it: should pass --leader-elect=true when leaderElect is true
set:
leaderElect: true
Expand All @@ -62,6 +54,20 @@ tests:
path: spec.template.spec.containers[0].args
content: "--metrics-bind-address=:9090"

- it: should pass --metrics-secure=false by default
asserts:
- contains:
path: spec.template.spec.containers[0].args
content: "--metrics-secure=false"

- it: should pass --metrics-secure=true when enabled
set:
metricsSecure: true
asserts:
- contains:
path: spec.template.spec.containers[0].args
content: "--metrics-secure=true"

- it: should pass --health-probe-bind-address from values
set:
healthProbeBindAddress: ":9091"
Expand Down
1 change: 1 addition & 0 deletions charts/kilo-clustermesh-operator/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ replicaCount: 1
leaderElect: true

metricsBindAddress: ":8080"
metricsSecure: false
healthProbeBindAddress: ":8081"

resources:
Expand Down
8 changes: 7 additions & 1 deletion pkg/kilo/v1alpha1/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,14 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema"
)

// GroupName is the API group used by Kilo's Peer type.
const GroupName = "kilo.squat.ai"

// GroupVersion is the API group version used by Kilo's Peer type.
const GroupVersion = "v1alpha1"

// SchemeGroupVersion is group version used to register these objects.
var SchemeGroupVersion = schema.GroupVersion{Group: "kilo.squat.ai", Version: "v1alpha1"} //nolint:gochecknoglobals // kubebuilder-required package-level scheme registration variable.
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: GroupVersion} //nolint:gochecknoglobals // kubebuilder-required package-level scheme registration variable.

// SchemeBuilder is used to add go types to the GroupVersionKind scheme.
var SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) //nolint:gochecknoglobals // kubebuilder-required package-level scheme registration variable.
Expand Down
4 changes: 2 additions & 2 deletions pkg/kilo/v1alpha1/types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ func TestAddToScheme(t *testing.T) {
s := runtime.NewScheme()
require.NoError(t, AddToScheme(s))

gvk := schema.GroupVersionKind{Group: "kilo.squat.ai", Version: "v1alpha1", Kind: "Peer"}
gvk := schema.GroupVersionKind{Group: GroupName, Version: GroupVersion, Kind: "Peer"}
obj, err := s.New(gvk)
require.NoError(t, err)
assert.IsType(t, &Peer{}, obj)

listGVK := schema.GroupVersionKind{Group: "kilo.squat.ai", Version: "v1alpha1", Kind: "PeerList"}
listGVK := schema.GroupVersionKind{Group: GroupName, Version: GroupVersion, Kind: "PeerList"}
listObj, err := s.New(listGVK)
require.NoError(t, err)
assert.IsType(t, &PeerList{}, listObj)
Expand Down
16 changes: 16 additions & 0 deletions pkg/kilo/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading