Skip to content

Commit b0ce45e

Browse files
pmalekczeslavo
andauthored
[Backport release/3.1.x] fix: do not sanitize plugins' config (#6138) (#6155)
* fix: do not sanitize plugins' config This reverts commit 2d615e3. * ensure we do not sanitize plugins' config in ut Co-authored-by: Grzegorz Burzyński <czeslavo@gmail.com>
1 parent c369e02 commit b0ce45e

5 files changed

Lines changed: 489 additions & 699 deletions

File tree

internal/dataplane/kongstate/kongstate.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,7 @@ func (ks *KongState) SanitizedCopy(uuidGenerator util.UUIDGenerator) *KongState
4747
return
4848
}(),
4949
CACertificates: ks.CACertificates,
50-
Plugins: lo.Map(ks.Plugins, func(p Plugin, _ int) Plugin {
51-
return p.SanitizedCopy()
52-
}),
50+
Plugins: ks.Plugins,
5351
Consumers: func() (res []Consumer) {
5452
for _, v := range ks.Consumers {
5553
res = append(res, *v.SanitizedCopy(uuidGenerator))

internal/dataplane/kongstate/kongstate_test.go

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,7 @@ func TestKongState_SanitizedCopy(t *testing.T) {
5858
Upstreams: []Upstream{{Upstream: kong.Upstream{ID: kong.String("1")}}},
5959
Certificates: []Certificate{{Certificate: kong.Certificate{ID: kong.String("1"), Key: kong.String("secret")}}},
6060
CACertificates: []kong.CACertificate{{ID: kong.String("1")}},
61-
Plugins: []Plugin{{
62-
SensitiveFieldsMeta: PluginSensitiveFieldsMetadata{WholeConfigIsSensitive: true},
63-
Plugin: kong.Plugin{ID: kong.String("1"), Config: kong.Configuration{"secret": "secretValue"}},
64-
}},
61+
Plugins: []Plugin{{Plugin: kong.Plugin{ID: kong.String("1"), Config: map[string]interface{}{"key": "secret"}}}},
6562
Consumers: []Consumer{{
6663
KeyAuths: []*KeyAuth{{kong.KeyAuth{ID: kong.String("1"), Key: kong.String("secret")}}},
6764
}},
@@ -82,10 +79,7 @@ func TestKongState_SanitizedCopy(t *testing.T) {
8279
Upstreams: []Upstream{{Upstream: kong.Upstream{ID: kong.String("1")}}},
8380
Certificates: []Certificate{{Certificate: kong.Certificate{ID: kong.String("1"), Key: redactedString}}},
8481
CACertificates: []kong.CACertificate{{ID: kong.String("1")}},
85-
Plugins: []Plugin{{
86-
SensitiveFieldsMeta: PluginSensitiveFieldsMetadata{WholeConfigIsSensitive: true},
87-
Plugin: kong.Plugin{ID: kong.String("1"), Config: kong.Configuration{"secret": *redactedString}},
88-
}},
82+
Plugins: []Plugin{{Plugin: kong.Plugin{ID: kong.String("1"), Config: map[string]interface{}{"key": "secret"}}}}, // We don't redact plugins' config.
8983
Consumers: []Consumer{{
9084
KeyAuths: []*KeyAuth{{kong.KeyAuth{ID: kong.String("1"), Key: kong.String("{vault://52fdfc07-2182-454f-963f-5f0f9a621d72}")}}},
9185
}},

internal/dataplane/kongstate/plugin.go

Lines changed: 2 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -4,122 +4,18 @@ import (
44
"encoding/json"
55
"errors"
66
"fmt"
7-
"strings"
87

98
jsonpatch "github.com/evanphx/json-patch/v5"
109
"github.com/kong/go-kong/kong"
11-
"github.com/samber/lo"
1210
corev1 "k8s.io/api/core/v1"
1311
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
14-
"sigs.k8s.io/controller-runtime/pkg/client"
1512
"sigs.k8s.io/yaml"
1613

1714
"github.com/kong/kubernetes-ingress-controller/v3/internal/store"
1815
"github.com/kong/kubernetes-ingress-controller/v3/internal/util"
1916
kongv1 "github.com/kong/kubernetes-ingress-controller/v3/pkg/apis/configuration/v1"
2017
)
2118

22-
// Plugin represents a plugin Object in Kong.
23-
type Plugin struct {
24-
kong.Plugin
25-
K8sParent client.Object
26-
SensitiveFieldsMeta PluginSensitiveFieldsMetadata
27-
}
28-
29-
func (p Plugin) DeepCopy() Plugin {
30-
return Plugin{
31-
Plugin: *p.Plugin.DeepCopy(),
32-
K8sParent: p.K8sParent,
33-
SensitiveFieldsMeta: p.SensitiveFieldsMeta,
34-
}
35-
}
36-
37-
func (p Plugin) SanitizedCopy() Plugin {
38-
// We do not want to return an error if any of below fails - the best we can do
39-
// is to return a plugin with wholly redacted config.
40-
// Let's have a closure returning a plugin with wholly redacted config prepared.
41-
whollySanitized := func() Plugin {
42-
p := p.DeepCopy()
43-
p.Config = sanitizeWholePluginConfig(p.Config)
44-
return p
45-
}
46-
47-
// If the whole config is sensitive, we need to redact the entire config.
48-
if p.SensitiveFieldsMeta.WholeConfigIsSensitive {
49-
return whollySanitized()
50-
}
51-
52-
// If there are JSON paths, we need to redact them.
53-
if len(p.SensitiveFieldsMeta.JSONPaths) > 0 {
54-
var patchOperations []string
55-
for _, path := range p.SensitiveFieldsMeta.JSONPaths {
56-
// If the path is empty, we need to sanitize the whole config.
57-
// An empty path means that the patch is on the root of the config.
58-
if path == "" {
59-
return whollySanitized()
60-
}
61-
62-
patchOperations = append(patchOperations, fmt.Sprintf(
63-
`{"op":"replace","path":"%s","value":"%s"}`,
64-
path,
65-
*redactedString,
66-
))
67-
}
68-
69-
// Decode the patch and apply it to the config.
70-
// We need to marshal the config to JSON and then unmarshal it back to Configuration
71-
// because the patch library works with bytes.
72-
patch, err := jsonpatch.DecodePatch([]byte(fmt.Sprintf("[%s]", strings.Join(patchOperations, ","))))
73-
if err != nil {
74-
return whollySanitized()
75-
}
76-
configB, err := json.Marshal(p.Config)
77-
if err != nil {
78-
return whollySanitized()
79-
}
80-
sanitizedConfigB, err := patch.Apply(configB)
81-
if err != nil {
82-
return whollySanitized()
83-
}
84-
sanitizedConfig := kong.Configuration{}
85-
if err := json.Unmarshal(sanitizedConfigB, &sanitizedConfig); err != nil {
86-
return whollySanitized()
87-
}
88-
89-
sanitized := p.DeepCopy()
90-
sanitized.Config = sanitizedConfig
91-
return sanitized
92-
}
93-
94-
// Nothing to sanitize.
95-
return p
96-
}
97-
98-
// sanitizeWholePluginConfig redacts the entire config of a plugin by replacing all of its
99-
// values with a redacted string.
100-
func sanitizeWholePluginConfig(config kong.Configuration) kong.Configuration {
101-
sanitized := config.DeepCopy()
102-
for k := range config {
103-
sanitized[k] = *redactedString
104-
}
105-
return sanitized
106-
}
107-
108-
// PluginSensitiveFieldsMetadata holds metadata about sensitive fields in a plugin's configuration.
109-
// It can be used to sanitize them before exposing the configuration to the user (e.g. in debug dumps
110-
// or in Konnect Admin API).
111-
type PluginSensitiveFieldsMetadata struct {
112-
// WholeConfigIsSensitive indicates that the entire configuration of the plugin is sensitive.
113-
// If this is true, the configuration should be redacted entirely (each of its fields' values
114-
// should be replaced with a redacted string).
115-
WholeConfigIsSensitive bool
116-
117-
// JSONPaths holds a list of JSON paths to sensitive fields in the plugin's configuration.
118-
// If this is not empty, the configuration should be redacted by replacing the values of the
119-
// fields at these paths with a redacted string.
120-
JSONPaths []string
121-
}
122-
12319
// getKongPluginOrKongClusterPlugin fetches a KongPlugin or KongClusterPlugin (as fallback) from the store.
12420
// If both are not found, an error is returned.
12521
func getKongPluginOrKongClusterPlugin(s store.Storer, namespace, name string) (
@@ -181,14 +77,6 @@ func kongPluginFromK8SClusterPlugin(
18177
}
18278
}
18379

184-
// Prepare sensitive fields metadata for the plugin.
185-
sensitiveFieldsMeta := PluginSensitiveFieldsMetadata{
186-
JSONPaths: lo.Map(k8sPlugin.ConfigPatches, func(patch kongv1.NamespacedConfigPatch, _ int) string {
187-
return patch.Path
188-
}),
189-
WholeConfigIsSensitive: k8sPlugin.ConfigFrom != nil,
190-
}
191-
19280
return Plugin{
19381
Plugin: plugin{
19482
Name: k8sPlugin.PluginName,
@@ -201,8 +89,7 @@ func kongPluginFromK8SClusterPlugin(
20189
Protocols: protocolsToStrings(k8sPlugin.Protocols),
20290
Tags: util.GenerateTagsForObject(&k8sPlugin),
20391
}.toKongPlugin(),
204-
K8sParent: &k8sPlugin,
205-
SensitiveFieldsMeta: sensitiveFieldsMeta,
92+
K8sParent: &k8sPlugin,
20693
}, nil
20794
}
20895

@@ -244,14 +131,6 @@ func kongPluginFromK8SPlugin(
244131
}
245132
}
246133

247-
// Prepare sensitive fields metadata for the plugin.
248-
sensitiveFieldsMeta := PluginSensitiveFieldsMetadata{
249-
JSONPaths: lo.Map(k8sPlugin.ConfigPatches, func(patch kongv1.ConfigPatch, _ int) string {
250-
return patch.Path
251-
}),
252-
WholeConfigIsSensitive: k8sPlugin.ConfigFrom != nil,
253-
}
254-
255134
return Plugin{
256135
Plugin: plugin{
257136
Name: k8sPlugin.PluginName,
@@ -264,8 +143,7 @@ func kongPluginFromK8SPlugin(
264143
Protocols: protocolsToStrings(k8sPlugin.Protocols),
265144
Tags: util.GenerateTagsForObject(&k8sPlugin),
266145
}.toKongPlugin(),
267-
K8sParent: &k8sPlugin,
268-
SensitiveFieldsMeta: sensitiveFieldsMeta,
146+
K8sParent: &k8sPlugin,
269147
}, nil
270148
}
271149

0 commit comments

Comments
 (0)