Skip to content
Merged
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
1 change: 1 addition & 0 deletions cmd/controller/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ func bindControllerFlags(f *controller.Flags, fs *flag.FlagSet) {
fs.StringVar(&f.LabelSelector, "label-selector", "", "Label selector which can be used to filter sealed secrets.")
fs.IntVar(&f.RateLimitPerSecond, "rate-limit", 2, "Number of allowed sustained request per second for verify endpoint")
fs.IntVar(&f.RateLimitBurst, "rate-limit-burst", 2, "Number of requests allowed to exceed the rate limit per second for verify endpoint")
fs.BoolVar(&f.MetricsOmitSecretLabels, "metrics-omit-secret-labels", false, "When true, the sealed_secrets_controller_condition_info metric is not updated, so the metrics endpoint does not expose SealedSecret namespaces and names. Use this if :8081 is reachable by users who should not be able to enumerate SealedSecret inventory.")
fs.StringVar(&f.PrivateKeyAnnotations, "privatekey-annotations", "", "Comma-separated list of additional annotations to be put on renewed sealing keys.")
fs.StringVar(&f.PrivateKeyLabels, "privatekey-labels", "", "Comma-separated list of additional labels to be put on renewed sealing keys.")

Expand Down
52 changes: 27 additions & 25 deletions pkg/controller/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,31 +35,32 @@ var (

// Flags to configure the controller.
type Flags struct {
KeyPrefix string
KeySize int
ValidFor time.Duration
MyCN string
KeyRenewPeriod time.Duration
KeyOrderPriority string
AcceptV1Data bool
KeyCutoffTime string
NamespaceAll bool
AdditionalNamespaces string
LabelSelector string
RateLimitPerSecond int
RateLimitBurst int
OldGCBehavior bool
UpdateStatus bool
SkipRecreate bool
LogInfoToStdout bool
LogLevel string
LogFormat string
PrivateKeyAnnotations string
PrivateKeyLabels string
MaxRetries int
WatchForSecrets bool
KubeClientQPS float32
KubeClientBurst int
KeyPrefix string
KeySize int
ValidFor time.Duration
MyCN string
KeyRenewPeriod time.Duration
KeyOrderPriority string
AcceptV1Data bool
KeyCutoffTime string
NamespaceAll bool
AdditionalNamespaces string
LabelSelector string
RateLimitPerSecond int
RateLimitBurst int
MetricsOmitSecretLabels bool
OldGCBehavior bool
UpdateStatus bool
SkipRecreate bool
LogInfoToStdout bool
LogLevel string
LogFormat string
PrivateKeyAnnotations string
PrivateKeyLabels string
MaxRetries int
WatchForSecrets bool
KubeClientQPS float32
KubeClientBurst int
}

func initKeyPrefix(keyPrefix string) (string, error) {
Expand Down Expand Up @@ -172,6 +173,7 @@ func initKeyRenewal(ctx context.Context, registry *KeyRegistry, period, validFor
}

func Main(f *Flags, version string) error {
SetMetricsOmitSecretLabels(f.MetricsOmitSecretLabels)
registerMetrics(version)

config, err := rest.InClusterConfig()
Expand Down
17 changes: 17 additions & 0 deletions pkg/controller/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,17 @@ import (
// Define Prometheus Exporter namespace (prefix) for all metric names.
const metricNamespace string = "sealed_secrets_controller"

// metricsOmitSecretLabels controls whether ObserveCondition and
// UnregisterCondition emit per-SealedSecret labels on condition_info.
// When true the gauge is not updated at all, so the metrics endpoint
// no longer exposes an inventory of SealedSecret namespaces and names
// to anyone who can reach :8081.
var metricsOmitSecretLabels bool

// SetMetricsOmitSecretLabels wires the controller flag into the metrics
// package. Called once from controller.Main before registerMetrics.
func SetMetricsOmitSecretLabels(b bool) { metricsOmitSecretLabels = b }

const (
labelNamespace = "namespace"
labelName = "name"
Expand Down Expand Up @@ -98,6 +109,9 @@ func registerMetrics(version string) {

// ObserveCondition sets a `condition_info` Gauge according to a SealedSecret status.
func ObserveCondition(ssecret *v1alpha1.SealedSecret) {
if metricsOmitSecretLabels {
return
}
if ssecret.Status == nil {
return
}
Expand All @@ -113,6 +127,9 @@ func ObserveCondition(ssecret *v1alpha1.SealedSecret) {

// UnregisterCondition unregisters Gauges associated to a SealedSecret conditions.
func UnregisterCondition(ssecret *v1alpha1.SealedSecret) {
if metricsOmitSecretLabels {
return
}
if ssecret.Status == nil {
return
}
Expand Down
30 changes: 30 additions & 0 deletions pkg/controller/metrics_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -230,3 +230,33 @@ func getLabel(labels []*dto.LabelPair, name string) string {
}
return ""
}

func TestObserveConditionRespectsOmitSecretLabels(t *testing.T) {
registry := setupTestMetrics()
SetMetricsOmitSecretLabels(true)
t.Cleanup(func() { SetMetricsOmitSecretLabels(false) })

ssecret := &ssv1alpha1.SealedSecret{
ObjectMeta: metav1.ObjectMeta{
Namespace: "test-ns",
Name: "test-secret",
},
Status: &ssv1alpha1.SealedSecretStatus{
Conditions: []ssv1alpha1.SealedSecretCondition{
{Type: ssv1alpha1.SealedSecretSynced, Status: corev1.ConditionTrue},
},
},
}

ObserveCondition(ssecret)

metricFamilies, err := registry.Gather()
if err != nil {
t.Fatalf("Failed to gather metrics: %v", err)
}
for _, mf := range metricFamilies {
if mf.GetName() == "sealed_secrets_controller_condition_info" && len(mf.GetMetric()) > 0 {
t.Errorf("Expected condition_info to be empty when omit flag is on, got %d series", len(mf.GetMetric()))
}
}
}
Loading