Skip to content

Commit 025bc8f

Browse files
committed
feat!: support external KMS to secure GitHub App credentials (#24)
* Add support for external KMS to secure private keys: - AWS KMS, - GCP KMS, - HashiCorp Vault. When using external KMS, the private key is stored in the KMS and all JWT signing operations are performed using the KMS API. * Refactor configuration to better align with support for external KMS. Configuration secret, file name and keys are updated to better reflect the new functionality. * Support full configuration via environment (best with KMS providers). * Re-enable HTTP2 by default. * Update Operator-SDK and dependencies to latest versions.
1 parent 03d3e4f commit 025bc8f

27 files changed

+1179
-1017
lines changed

.ko.yaml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1+
---
12
defaultPlatforms:
23
- linux/arm64
34
- linux/amd64
4-
- linux/s390x
5-
- linux/ppc64le
65

76
builds:
87
- id: manager
9-
main: ./cmd
8+
main: ./cmd/manager
109
env:
1110
- CGO_ENABLED=0
1211
flags:

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ COPY internal/controller/ internal/controller/
2121
# was called. For example, if we call make docker-build in a local env which has the Apple Silicon M1 SO
2222
# the docker BUILDPLATFORM arg will be linux/arm64 when for Apple x86 it will be linux/amd64. Therefore,
2323
# by leaving it empty we can ensure that the container and binary shipped on it will have the same platform.
24-
RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o manager cmd/main.go
24+
RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o manager ./cmd/manager
2525

2626
# Use distroless as minimal base image to package the manager binary
2727
# Refer to https://github.com/GoogleContainerTools/distroless for more details

Makefile

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,12 @@ endif
5151

5252
# Set the Operator SDK version to use. By default, what is installed on the system is used.
5353
# This is useful for CI or a project to utilize a specific version of the operator-sdk toolkit.
54-
OPERATOR_SDK_VERSION ?= v1.34.1
54+
OPERATOR_SDK_VERSION ?= v1.37.0
5555

5656
# Image URL to use all building/pushing image targets
5757
IMG ?= $(IMAGE_TAG_BASE):latest
5858
# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary.
59-
ENVTEST_K8S_VERSION = 1.28.3
59+
ENVTEST_K8S_VERSION = 1.31.0
6060

6161
# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
6262
ifeq (,$(shell go env GOBIN))
@@ -134,7 +134,7 @@ test-e2e:
134134
go test ./test/e2e/ -v -ginkgo.v
135135

136136
GOLANGCI_LINT = $(shell pwd)/bin/golangci-lint
137-
GOLANGCI_LINT_VERSION ?= v1.54.2
137+
GOLANGCI_LINT_VERSION ?= v1.61.0
138138
golangci-lint:
139139
@[ -f $(GOLANGCI_LINT) ] || { \
140140
set -e ;\
@@ -153,11 +153,11 @@ lint-fix: golangci-lint ## Run golangci-lint linter and perform fixes
153153

154154
.PHONY: build
155155
build: manifests generate fmt vet ## Build manager binary.
156-
go build -o bin/manager cmd/main.go
156+
go build -o bin/manager ./cmd/manager
157157

158158
.PHONY: run
159159
run: manifests generate fmt vet ## Run a controller from your host.
160-
go run ./cmd/main.go
160+
go run ./cmd/manager
161161

162162
# If you wish to build the manager image targeting other platforms you can use the --platform flag.
163163
# (i.e. docker build --platform linux/arm64). However, you must enable docker buildKit for it.
@@ -190,7 +190,7 @@ docker-buildx: ## Build and push docker image for the manager for cross-platform
190190
.PHONY: ko-build
191191
ko-build: ## Build the manager image using ko.
192192
KO_DOCKER_REPO=$(IMAGE_TAG_BASE) \
193-
ko build --bare --platform=$(PLATFORMS) --image-label org.opencontainers.image.source=$(IMAGE_SOURCE) --push ./cmd
193+
ko build --bare --platform=$(PLATFORMS) --image-label org.opencontainers.image.source=$(IMAGE_SOURCE) --push ./cmd/manager
194194

195195

196196
##@ Deployment
@@ -230,8 +230,8 @@ CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen
230230
ENVTEST ?= $(LOCALBIN)/setup-envtest
231231

232232
## Tool Versions
233-
KUSTOMIZE_VERSION ?= v5.3.0
234-
CONTROLLER_TOOLS_VERSION ?= v0.14.0
233+
KUSTOMIZE_VERSION ?= v5.5.0
234+
CONTROLLER_TOOLS_VERSION ?= v0.16.4
235235

236236
.PHONY: kustomize
237237
kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary. If wrong version is installed, it will be removed before downloading.

README.md

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,23 +19,26 @@ This operator functions similarly to cert-manager, but instead of managing certi
1919
* A Kubernetes cluster (v1.21+)
2020
* A [GitHub App](https://docs.github.com/en/apps/creating-github-apps) with permissions and repository assignments sufficient to meet the needs of all anticipated GitHub API interactions. Typically: `metadata: read`, `contents: read`, `statuses: write`.
2121

22-
#### Example `github-app-credentials` secret
22+
#### Example `gtm-config` secret
2323
<details>
2424
<summary><i>expand me! ✨</i></summary>
2525

2626
```yaml
2727
apiVersion: v1
2828
kind: Secret
2929
metadata:
30-
name: github-app-credentials
31-
namespace: default
32-
data:
33-
github-token-manager.yaml: |
34-
##### BASE64 ENCODED #####
35-
appID: "<app-id>"
36-
installationID: "<installation-id>"
37-
privateKey: |
38-
----- <BEGIN RSA PRIVATE KEY> -----
30+
name: gtm-config
31+
namespace: github-token-manager
32+
stringData:
33+
gtm.yaml: |
34+
app_id: <app-id>
35+
installation_id: <installation-id>
36+
provider: file
37+
key: /config/private.key
38+
private.key: |
39+
-----BEGIN RSA PRIVATE KEY-----
40+
...elided...
41+
-----END RSA PRIVATE KEY-----
3942
```
4043
4144
</details>

api/v1/clustertoken_types.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ package v1
1919
import (
2020
"time"
2121

22-
"github.com/google/go-github/v62/github"
22+
"github.com/google/go-github/v66/github"
2323
"github.com/isometry/github-token-manager/internal/ghapp"
2424
"k8s.io/apimachinery/pkg/api/meta"
2525
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

api/v1/permissions.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package v1
22

33
import (
4-
"github.com/google/go-github/v62/github"
4+
"github.com/google/go-github/v66/github"
55
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
66
)
77

api/v1/token_types.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ package v1
1919
import (
2020
"time"
2121

22-
"github.com/google/go-github/v62/github"
22+
"github.com/google/go-github/v66/github"
2323
"github.com/isometry/github-token-manager/internal/ghapp"
2424
"k8s.io/apimachinery/pkg/api/meta"
2525
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

cmd/main.go renamed to cmd/manager/main.go

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -56,16 +56,16 @@ func main() {
5656
var enableLeaderElection bool
5757
var probeAddr string
5858
var secureMetrics bool
59-
var enableHTTP2 bool
59+
var disableHTTP2 bool
6060
flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.")
6161
flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.")
6262
flag.BoolVar(&enableLeaderElection, "leader-elect", false,
6363
"Enable leader election for controller manager. "+
6464
"Enabling this will ensure there is only one active controller manager.")
6565
flag.BoolVar(&secureMetrics, "metrics-secure", false,
6666
"If set the metrics endpoint is served securely")
67-
flag.BoolVar(&enableHTTP2, "enable-http2", false,
68-
"If set, HTTP/2 will be enabled for the metrics and webhook servers")
67+
flag.BoolVar(&disableHTTP2, "disable-http2", false,
68+
"If set, HTTP/2 will be disabled for the metrics and webhook servers")
6969
opts := zap.Options{
7070
Development: true,
7171
}
@@ -74,20 +74,14 @@ func main() {
7474

7575
ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts)))
7676

77-
// if the enable-http2 flag is false (the default), http/2 should be disabled
78-
// due to its vulnerabilities. More specifically, disabling http/2 will
79-
// prevent from being vulnerable to the HTTP/2 Stream Cancelation and
80-
// Rapid Reset CVEs. For more information see:
81-
// - https://github.com/advisories/GHSA-qppj-fm5r-hxr3
82-
// - https://github.com/advisories/GHSA-4374-p667-p6c8
83-
disableHTTP2 := func(c *tls.Config) {
84-
setupLog.Info("disabling http/2")
85-
c.NextProtos = []string{"http/1.1"}
86-
}
87-
8877
tlsOpts := []func(*tls.Config){}
89-
if !enableHTTP2 {
90-
tlsOpts = append(tlsOpts, disableHTTP2)
78+
79+
if disableHTTP2 {
80+
forceHTTP11 := func(c *tls.Config) {
81+
setupLog.Info("disabling http/2")
82+
c.NextProtos = []string{"http/1.1"}
83+
}
84+
tlsOpts = append(tlsOpts, forceHTTP11)
9185
}
9286

9387
webhookServer := webhook.NewServer(webhook.Options{

0 commit comments

Comments
 (0)