Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: POC of dynamic authority #468

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
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
10 changes: 9 additions & 1 deletion cmd/trust-manager/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@ limitations under the License.
package app

import (
"crypto/tls"
"errors"
"fmt"
"net/http"

"github.com/erikgb/dynamic-authority/pkg/authority"
"github.com/spf13/cobra"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/labels"
Expand Down Expand Up @@ -70,6 +72,8 @@ func NewCommand() *cobra.Command {

ctrl.SetLogger(mlog)

certOperator := authority.ServingCertificateOperator{Options: opts.DynamicServing}

eventBroadcaster := record.NewBroadcaster()
eventBroadcaster.StartLogging(func(format string, args ...any) { mlog.V(3).Info(fmt.Sprintf(format, args...)) })
eventBroadcaster.StartRecordingToSink(&clientv1.EventSinkImpl{Interface: cl.CoreV1().Events("")})
Expand All @@ -87,7 +91,7 @@ func NewCommand() *cobra.Command {
WebhookServer: ctrlwebhook.NewServer(ctrlwebhook.Options{
Port: opts.Webhook.Port,
Host: opts.Webhook.Host,
CertDir: opts.Webhook.CertDir,
TLSOpts: []func(*tls.Config){certOperator.ServingCertificate()},
}),
Metrics: server.Options{
BindAddress: fmt.Sprintf("0.0.0.0:%d", opts.MetricsPort),
Expand Down Expand Up @@ -119,6 +123,10 @@ func NewCommand() *cobra.Command {
return fmt.Errorf("failed to create manager: %w", err)
}

if err := certOperator.SetupWithManager(mgr); err != nil {
return fmt.Errorf("failed to setup cert operator: %w", err)
}

targetCache, err := cache.New(mgr.GetConfig(), cache.Options{
HTTPClient: mgr.GetHTTPClient(),
Scheme: mgr.GetScheme(),
Expand Down
16 changes: 16 additions & 0 deletions cmd/trust-manager/app/options/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"os"
"time"

"github.com/erikgb/dynamic-authority/pkg/authority"
"github.com/go-logr/logr"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
Expand Down Expand Up @@ -70,6 +71,8 @@ type Options struct {

// Leader election lease renew duration
RenewDeadline time.Duration

DynamicServing authority.Options
}

type logOptions struct {
Expand Down Expand Up @@ -164,6 +167,7 @@ func (o *Options) addFlags(cmd *cobra.Command) {
o.addBundleFlags(nfs.FlagSet("Bundle"))
o.addLoggingFlags(nfs.FlagSet("Logging"))
o.addWebhookFlags(nfs.FlagSet("Webhook"))
o.addDynamicServingFlags(nfs.FlagSet("Dynamic Serving"))
o.kubeConfigFlags = genericclioptions.NewConfigFlags(true)
o.kubeConfigFlags.AddFlags(nfs.FlagSet("Kubernetes"))

Expand Down Expand Up @@ -248,3 +252,15 @@ func (o *Options) addWebhookFlags(fs *pflag.FlagSet) {
"Certificate and private key must be named 'tls.crt' and 'tls.key' "+
"respectively.")
}

func (o *Options) addDynamicServingFlags(fs *pflag.FlagSet) {
fs.StringVar(&o.DynamicServing.Namespace,
"dynamic-serving-ca-secret-namespace", "",
"Namespace of the secret used to store the CA that signs serving certificates")
fs.StringVar(&o.DynamicServing.CASecret,
"dynamic-serving-ca-secret-name", "",
"Name of the secret used to store the CA that signs serving certificates")
fs.StringSliceVar(&o.DynamicServing.DNSNames,
"dynamic-serving-dns-names", nil,
"DNS names that should be present on certificates generated by the dynamic serving CA")
}
26 changes: 0 additions & 26 deletions deploy/charts/trust-manager/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -421,32 +421,6 @@ The nodePort set on the Service used by the webhook.
> ```

Whether to issue a webhook cert using Helm, which removes the need to install cert-manager. Helm-issued certificates can be challenging to rotate and maintain, and the issued cert will have a duration of 10 years and be modified when trust-manager is updated. It's safer and easier to rely on cert-manager for issuing the webhook cert - avoid using Helm-generated certs in production.
#### **app.webhook.tls.approverPolicy.enabled** ~ `bool`
> Default value:
> ```yaml
> false
> ```

Whether to create an approver-policy CertificateRequestPolicy allowing auto-approval of the trust-manager webhook certificate. If you have approver-policy installed, you almost certainly want to enable this.
#### **app.webhook.tls.approverPolicy.certManagerNamespace** ~ `string`
> Default value:
> ```yaml
> cert-manager
> ```

The namespace in which cert-manager was installed. Only used if `app.webhook.tls.approverPolicy.enabled` is true.
#### **app.webhook.tls.approverPolicy.certManagerServiceAccount** ~ `string`
> Default value:
> ```yaml
> cert-manager
> ```

The name of cert-manager's Service Account. Only used if `app.webhook.tls.approverPolicy.enabled` is true.
#### **app.webhook.tls.certificate.secretTemplate** ~ `object`
> Default value:
> ```yaml
> {}
> ```
#### **app.webhook.hostNetwork** ~ `bool`
> Default value:
> ```yaml
Expand Down
94 changes: 0 additions & 94 deletions deploy/charts/trust-manager/templates/certificate.yaml

This file was deleted.

13 changes: 13 additions & 0 deletions deploy/charts/trust-manager/templates/clusterrole.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,19 @@ metadata:
{{- include "trust-manager.labels" . | nindent 4 }}
name: {{ include "trust-manager.name" . }}
rules:
- apiGroups:
- "admissionregistration.k8s.io"
resources:
- "validatingwebhookconfigurations"
verbs: ["get", "list", "watch"]
- apiGroups:
- "admissionregistration.k8s.io"
resources:
- "validatingwebhookconfigurations"
verbs: ["patch"]
resourceNames:
- {{ include "trust-manager.name" . }}

- apiGroups:
- "trust.cert-manager.io"
resources:
Expand Down
18 changes: 10 additions & 8 deletions deploy/charts/trust-manager/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,11 @@ spec:
# webhook
- "--webhook-host={{.Values.app.webhook.host}}"
- "--webhook-port={{.Values.app.webhook.port}}"
- "--webhook-certificate-dir=/tls"
- "--dynamic-serving-ca-secret-namespace={{ include "trust-manager.namespace" . }}"
- "--dynamic-serving-ca-secret-name={{ include "trust-manager.name" . }}-dynamic-ca"
- "--dynamic-serving-dns-names={{ include "trust-manager.name" . }}"
- "--dynamic-serving-dns-names={{ include "trust-manager.name" . }}.$(POD_NAMESPACE)"
- "--dynamic-serving-dns-names={{ include "trust-manager.name" . }}.$(POD_NAMESPACE).svc"
{{- if .Values.defaultPackage.enabled }}
- "--default-package-location=/packages/cert-manager-package-debian.json"
{{- end }}
Expand All @@ -97,10 +101,12 @@ spec:
{{- if .Values.filterExpiredCertificates.enabled }}
- "--filter-expired-certificates=true"
{{- end }}
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
volumeMounts:
- mountPath: /tls
name: tls
readOnly: true
- mountPath: /packages
name: packages
readOnly: true
Expand Down Expand Up @@ -140,10 +146,6 @@ spec:
- name: packages
emptyDir:
sizeLimit: 50M
- name: tls
secret:
defaultMode: 420
secretName: {{ include "trust-manager.name" . }}-tls
{{- if .Values.app.webhook.hostNetwork }}
hostNetwork: true
dnsPolicy: ClusterFirstWithHostNet
Expand Down
9 changes: 9 additions & 0 deletions deploy/charts/trust-manager/templates/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@ rules:
- "get"
- "list"
- "watch"
- apiGroups:
- ""
resources:
- "secrets"
verbs:
- "create"
- "patch"
resourceNames:
- {{ include "trust-manager.name" . }}-dynamic-ca
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
Expand Down
10 changes: 2 additions & 8 deletions deploy/charts/trust-manager/templates/webhook.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
{{- if and .Values.app.webhook.tls.helmCert.enabled .Values.app.webhook.tls.approverPolicy.enabled -}}
{{- fail "cannot set .app.webhook.tls.helmCert.enabled and .Values.app.webhook.tls.approverPolicy.enabled" }}
{{- end -}}

{{- /*
$ca is always generated here even if .Values.app.webhook.tls.helmCert.enabled is false because we need it to be
visible in the scope for the ValidatingWebhookConfiguration below.
Expand Down Expand Up @@ -83,10 +79,8 @@ metadata:
labels:
app: {{ include "trust-manager.name" . }}
{{- include "trust-manager.labels" . | nindent 4 }}
{{ if not .Values.app.webhook.tls.helmCert.enabled }}
annotations:
cert-manager.io/inject-ca-from: "{{ include "trust-manager.namespace" . }}/{{ include "trust-manager.name" . }}"
{{ end }}
cert-manager.io/inject-dynamic-ca-from-secret-namespace: "{{ include "trust-manager.namespace" . }}"
cert-manager.io/inject-dynamic-ca-from-secret-name: "{{ include "trust-manager.name" . }}-dynamic-ca"

webhooks:
- name: trust.cert-manager.io
Expand Down
49 changes: 0 additions & 49 deletions deploy/charts/trust-manager/values.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -389,61 +389,12 @@
"helm-values.app.webhook.tls": {
"additionalProperties": false,
"properties": {
"approverPolicy": {
"$ref": "#/$defs/helm-values.app.webhook.tls.approverPolicy"
},
"certificate": {
"$ref": "#/$defs/helm-values.app.webhook.tls.certificate"
},
"helmCert": {
"$ref": "#/$defs/helm-values.app.webhook.tls.helmCert"
}
},
"type": "object"
},
"helm-values.app.webhook.tls.approverPolicy": {
"additionalProperties": false,
"properties": {
"certManagerNamespace": {
"$ref": "#/$defs/helm-values.app.webhook.tls.approverPolicy.certManagerNamespace"
},
"certManagerServiceAccount": {
"$ref": "#/$defs/helm-values.app.webhook.tls.approverPolicy.certManagerServiceAccount"
},
"enabled": {
"$ref": "#/$defs/helm-values.app.webhook.tls.approverPolicy.enabled"
}
},
"type": "object"
},
"helm-values.app.webhook.tls.approverPolicy.certManagerNamespace": {
"default": "cert-manager",
"description": "The namespace in which cert-manager was installed. Only used if `app.webhook.tls.approverPolicy.enabled` is true.",
"type": "string"
},
"helm-values.app.webhook.tls.approverPolicy.certManagerServiceAccount": {
"default": "cert-manager",
"description": "The name of cert-manager's Service Account. Only used if `app.webhook.tls.approverPolicy.enabled` is true.",
"type": "string"
},
"helm-values.app.webhook.tls.approverPolicy.enabled": {
"default": false,
"description": "Whether to create an approver-policy CertificateRequestPolicy allowing auto-approval of the trust-manager webhook certificate. If you have approver-policy installed, you almost certainly want to enable this.",
"type": "boolean"
},
"helm-values.app.webhook.tls.certificate": {
"additionalProperties": false,
"properties": {
"secretTemplate": {
"$ref": "#/$defs/helm-values.app.webhook.tls.certificate.secretTemplate"
}
},
"type": "object"
},
"helm-values.app.webhook.tls.certificate.secretTemplate": {
"default": {},
"type": "object"
},
"helm-values.app.webhook.tls.helmCert": {
"additionalProperties": false,
"properties": {
Expand Down
20 changes: 0 additions & 20 deletions deploy/charts/trust-manager/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -242,26 +242,6 @@ app:
# It's safer and easier to rely on cert-manager for issuing the webhook cert - avoid using Helm-generated certs in production.
enabled: false

approverPolicy:
# Whether to create an approver-policy CertificateRequestPolicy allowing auto-approval of the trust-manager webhook certificate. If you have approver-policy installed, you almost certainly want to enable this.
enabled: false

# The namespace in which cert-manager was installed. Only used if `app.webhook.tls.approverPolicy.enabled` is true.
certManagerNamespace: "cert-manager"

# The name of cert-manager's Service Account. Only used if `app.webhook.tls.approverPolicy.enabled` is true.
certManagerServiceAccount: "cert-manager"

# Add labels/annotations to secrets created by Certificate resources when using cert-manager provisioned TLS certificate.
certificate:
secretTemplate: {}
# For example:
# annotations:
# my-secret-annotation-1: "foo"
# my-secret-annotation-2: "bar"
# labels:
# my-secret-label: foo

# This value specifies if the app should be started in hostNetwork mode. It is required for use in some managed Kubernetes clusters (such as AWS EKS) with custom CNI.
hostNetwork: false

Expand Down
Loading