diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 48079d91..84a6760c 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -5,12 +5,16 @@ updates: directory: "/" schedule: interval: "weekly" + cooldown: + default-days: 7 # dependabot auto-detects the vendor/ directory and runs `go mod tidy` + `go mod vendor` on updates - package-ecosystem: "gomod" directory: "/" schedule: interval: "weekly" + cooldown: + default-days: 7 # dev tools (actionlint, golangci-lint, gofumpt) pinned in .tools/go.mod; tools move slowly, # so only check quarterly @@ -18,3 +22,5 @@ updates: directory: "/.tools" schedule: interval: "quarterly" + cooldown: + default-days: 7 diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index e7fa1436..f8b2d995 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -19,6 +19,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 with: go-version-file: ./.go-version diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 26608adc..7fffc3a5 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -46,6 +46,8 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/pr-check-against-providers.yaml b/.github/workflows/pr-check-against-providers.yaml index 634ab0e2..41e26424 100644 --- a/.github/workflows/pr-check-against-providers.yaml +++ b/.github/workflows/pr-check-against-providers.yaml @@ -20,6 +20,7 @@ jobs: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 # the golden comparison builds origin/main too + persist-credentials: false - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 with: go-version-file: ./.go-version diff --git a/.github/workflows/pr-depscheck.yaml b/.github/workflows/pr-depscheck.yaml index d6410cb6..b9966e2b 100644 --- a/.github/workflows/pr-depscheck.yaml +++ b/.github/workflows/pr-depscheck.yaml @@ -20,6 +20,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 with: go-version-file: ./.go-version diff --git a/.github/workflows/pr-golangci-lint.yaml b/.github/workflows/pr-golangci-lint.yaml index c947c37a..00dd4f1e 100644 --- a/.github/workflows/pr-golangci-lint.yaml +++ b/.github/workflows/pr-golangci-lint.yaml @@ -20,6 +20,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 with: go-version-file: ./.go-version diff --git a/.github/workflows/pr-tests.yaml b/.github/workflows/pr-tests.yaml index 2282c875..4016cf2b 100644 --- a/.github/workflows/pr-tests.yaml +++ b/.github/workflows/pr-tests.yaml @@ -22,6 +22,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 with: go-version-file: ./.go-version diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 47c72b08..f4826b14 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -20,9 +20,11 @@ jobs: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 # goreleaser derives the changelog and version from tag history + persist-credentials: false - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 with: go-version-file: ./.go-version + cache: false - uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2 - uses: goreleaser/goreleaser-action@f06c13b6b1a9625abc9e6e439d9c05a8f2190e94 # v7.2.3 with: @@ -44,7 +46,7 @@ jobs: id-token: write # sign the provenance contents: write # upload multiple.intoto.jsonl to the release # the slsa builder must be referenced by tag, not commit hash; it verifies its own ref at runtime - uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.1.0 + uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.1.0 # zizmor: ignore[unpinned-uses] with: base64-subjects: ${{ needs.goreleaser.outputs.hashes }} upload-assets: true @@ -54,6 +56,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - name: update tap formula (source build) env: TAG: ${{ github.ref_name }} diff --git a/.github/workflows/shellcheck.yaml b/.github/workflows/shellcheck.yaml index 29c39f27..fcdc8ced 100644 --- a/.github/workflows/shellcheck.yaml +++ b/.github/workflows/shellcheck.yaml @@ -17,5 +17,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false # shellcheck is preinstalled on ubuntu-latest - run: make shellcheck diff --git a/.github/workflows/typos.yaml b/.github/workflows/typos.yaml index bbc99a17..9c561dbe 100644 --- a/.github/workflows/typos.yaml +++ b/.github/workflows/typos.yaml @@ -21,4 +21,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - run: make typos diff --git a/.github/workflows/workflow-actionlint.yml b/.github/workflows/workflow-actionlint.yml index ad01b29a..8ddfe959 100644 --- a/.github/workflows/workflow-actionlint.yml +++ b/.github/workflows/workflow-actionlint.yml @@ -27,6 +27,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 with: go-version-file: ./.go-version diff --git a/.github/workflows/workflow-yamllint.yml b/.github/workflows/workflow-yamllint.yml index d7090574..97f190b3 100644 --- a/.github/workflows/workflow-yamllint.yml +++ b/.github/workflows/workflow-yamllint.yml @@ -27,4 +27,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - run: make yamllint diff --git a/.github/workflows/workflow-zizmor.yml b/.github/workflows/workflow-zizmor.yml new file mode 100644 index 00000000..ffc160c4 --- /dev/null +++ b/.github/workflows/workflow-zizmor.yml @@ -0,0 +1,27 @@ +name: workflow security audit + +# Audits .github/workflows/ with zizmor (template injection, credential persistence, excessive +# permissions, dangerous triggers). Complements actionlint, which covers syntax, expressions and +# shell but not these. make downloads the version pinned in the makefile. + +on: + push: + branches: [ 'main' ] + pull_request: + types: ['opened', 'synchronize'] + +permissions: + contents: read + +concurrency: + group: 'workflow-zizmor-${{ github.head_ref || github.ref }}' + cancel-in-progress: true + +jobs: + workflow-zizmor: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - run: make zizmor diff --git a/makefile b/makefile index eda452da..9caf0f33 100644 --- a/makefile +++ b/makefile @@ -13,14 +13,16 @@ GOFUMPT=$(TOOLS_BIN)/gofumpt GOLANGCI_LINT=$(TOOLS_BIN)/golangci-lint # non-Go tools also live in .tools/bin at pinned versions, but the pins are here (dependabot -# cannot bump them): shellcheck and typos are static binaries downloaded from their github releases, +# cannot bump them): shellcheck, typos and zizmor are static binaries downloaded from their github releases, # yamllint is python installed into a repo-local venv. all rebuild when this makefile changes. SHELLCHECK_VERSION=v0.11.0 TYPOS_VERSION=v1.50.1 YAMLLINT_VERSION=1.38.0 +ZIZMOR_VERSION=v1.30.1 SHELLCHECK=$(TOOLS_BIN)/shellcheck TYPOS=$(TOOLS_BIN)/typos YAMLLINT=$(TOOLS_BIN)/yamllint +ZIZMOR=$(TOOLS_BIN)/zizmor # golangci-lint with the azproviderlint module plugin compiled in (.tools/.custom-gcl.yml); # lint runs use this binary, the plain go.mod one exists to bootstrap `golangci-lint custom` @@ -58,6 +60,14 @@ $(YAMLLINT): makefile @mkdir -p $(TOOLS_BIN) @python3 -m venv .tools/venv && .tools/venv/bin/pip install -q yamllint==$(YAMLLINT_VERSION) && ln -sf ../venv/bin/yamllint $@ +$(ZIZMOR): makefile + @echo "==> downloading zizmor $(ZIZMOR_VERSION)..." + @mkdir -p $(TOOLS_BIN) + @case "$$(uname)" in Darwin) target=apple-darwin;; *) target=unknown-linux-gnu;; esac; \ + arch=$$(uname -m); [ "$$arch" = "arm64" ] && arch=aarch64; \ + curl -sSfL "https://github.com/zizmorcore/zizmor/releases/download/$(ZIZMOR_VERSION)/zizmor-$$arch-$$target.tar.gz" \ + | tar -xz -O zizmor > $@ && chmod +x $@ + default: fmt build all: fmt build @@ -74,7 +84,7 @@ install: ## Install terrafmt into GOPATH/bin with version info from git @echo "==> installing..." go install -ldflags "-X github.com/katbyte/terrafmt/lib/version.GitCommit=${GIT_COMMIT} -X github.com/katbyte/terrafmt/lib/version.Version=${GIT_VERSION}" . -tools: $(ACTIONLINT) $(GOFUMPT) $(GOLANGCI_LINT) $(GOLANGCI_LINT_MODULES) $(SHELLCHECK) $(TYPOS) $(YAMLLINT) ## Install all pinned dev tools into .tools/bin +tools: $(ACTIONLINT) $(GOFUMPT) $(GOLANGCI_LINT) $(GOLANGCI_LINT_MODULES) $(SHELLCHECK) $(TYPOS) $(YAMLLINT) $(ZIZMOR) ## Install all pinned dev tools into .tools/bin ##@ Formatting fmt: $(GOFUMPT) $(GOLANGCI_LINT) ## Fix Go formatting (gofmt, gofumpt, goimports) @@ -118,6 +128,10 @@ typos-fix: $(TYPOS) ## Fix spelling mistakes found by typos @echo "==> Fixing typos..." @$(TYPOS) --write-changes +zizmor: $(ZIZMOR) ## Audit GitHub workflows for security issues with zizmor + @echo "==> Auditing workflows with zizmor..." + @$(ZIZMOR) . + depscheck: ## Check that go.mod/go.sum and vendor/ are in sync @echo "==> Checking source code with go mod tidy..." @go mod tidy @@ -147,4 +161,4 @@ check-against-providers: ## Check formatting against real provider repos (golden check-all: build test lint actionlint yamllint shellcheck typos depscheck ## Run build + test + all linters + depscheck -.PHONY: default all help fmt goimports build lint lint-fix actionlint yamllint shellcheck typos typos-fix depscheck check-against-providers check-all install tools test +.PHONY: default all help fmt goimports build lint lint-fix actionlint yamllint shellcheck typos typos-fix zizmor depscheck check-against-providers check-all install tools test