Skip to content

Commit

Permalink
fix(konnect) avoid collisions when redacting
Browse files Browse the repository at this point in the history
Change the static redacted pretend Vault string to a function that
generates a random pretend Vault string.

This avoids collisions for certain types of values when
go-database-reconciler builds configuration. It uses an in-memory
database that looks up Kong entities by unique fields. If these fields
aren't actually unique, go-database-reconciler will detect a conflict
and abort.
  • Loading branch information
rainest committed May 3, 2024
1 parent 755e2ce commit 1ce7f48
Show file tree
Hide file tree
Showing 9 changed files with 33 additions and 26 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ Adding a new version? You'll need three changes:
`parentRefs`'s group/kind is not `gateway.network.k8s.io/Gateway`, the item
is seen as a parent other than the controller and ignored in parentRef check.
[#5919](https://github.com/Kong/kubernetes-ingress-controller/pull/5919)
- Redacted values no longer cause collisions in configuration reported to Konnect.
[5964](https://github.com/Kong/kubernetes-ingress-controller/pull/5964)

### Changed

Expand Down
10 changes: 5 additions & 5 deletions internal/dataplane/kongstate/consumer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,13 @@ func TestConsumer_SanitizedCopy(t *testing.T) {
Tags: []*string{kong.String("5.1"), kong.String("5.2")},
},
Plugins: []kong.Plugin{{ID: kong.String("1")}},
KeyAuths: []*KeyAuth{{kong.KeyAuth{ID: kong.String("1"), Key: redactedString}}},
HMACAuths: []*HMACAuth{{kong.HMACAuth{ID: kong.String("1"), Secret: redactedString}}},
JWTAuths: []*JWTAuth{{kong.JWTAuth{ID: kong.String("1"), Secret: redactedString}}},
BasicAuths: []*BasicAuth{{kong.BasicAuth{ID: kong.String("1"), Password: redactedString}}},
KeyAuths: []*KeyAuth{{kong.KeyAuth{ID: kong.String("1"), Key: redactedString()}}},
HMACAuths: []*HMACAuth{{kong.HMACAuth{ID: kong.String("1"), Secret: redactedString()}}},
JWTAuths: []*JWTAuth{{kong.JWTAuth{ID: kong.String("1"), Secret: redactedString()}}},
BasicAuths: []*BasicAuth{{kong.BasicAuth{ID: kong.String("1"), Password: redactedString()}}},
ACLGroups: []*ACLGroup{{kong.ACLGroup{ID: kong.String("1")}}},
Oauth2Creds: []*Oauth2Credential{
{kong.Oauth2Credential{ID: kong.String("1"), ClientSecret: redactedString}},
{kong.Oauth2Credential{ID: kong.String("1"), ClientSecret: redactedString()}},
},
MTLSAuths: []*MTLSAuth{{kong.MTLSAuth{ID: kong.String("1"), SubjectName: kong.String("foo@example.com")}}},
K8sKongConsumer: kongv1.KongConsumer{Username: "foo"},
Expand Down
19 changes: 12 additions & 7 deletions internal/dataplane/kongstate/credentials.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,19 @@ package kongstate
import (
"fmt"

"github.com/google/uuid"
"github.com/kong/go-kong/kong"
"github.com/mitchellh/mapstructure"
)

// redactedString is used to redact sensitive values in the KongState.
// It uses a vault URI to pass Konnect Admin API validations (e.g. when a TLS key is expected, it's only possible
// to pass a valid key or a vault URI).
var redactedString = kong.String("{vault://redacted-value}")
// to pass a valid key or a vault URI). The value is random to avoid collisions when the sensitive field must be
// unique, such as for key-auths.
func redactedString() *string {
s := fmt.Sprintf("{vault://%s}", uuid.NewString())
return &s
}

// KeyAuth represents a key-auth credential.
type KeyAuth struct {
Expand Down Expand Up @@ -158,7 +163,7 @@ func (c *KeyAuth) SanitizedCopy() *KeyAuth {
// Consumer field omitted
CreatedAt: c.CreatedAt,
ID: c.ID,
Key: redactedString,
Key: redactedString(),
Tags: c.Tags,
},
}
Expand All @@ -172,7 +177,7 @@ func (c *HMACAuth) SanitizedCopy() *HMACAuth {
CreatedAt: c.CreatedAt,
ID: c.ID,
Username: c.Username,
Secret: redactedString,
Secret: redactedString(),
Tags: c.Tags,
},
}
Expand All @@ -188,7 +193,7 @@ func (c *JWTAuth) SanitizedCopy() *JWTAuth {
Algorithm: c.Algorithm,
Key: c.Key, // despite field name, "key" is an identifier
RSAPublicKey: c.RSAPublicKey,
Secret: redactedString,
Secret: redactedString(),
Tags: c.Tags,
},
}
Expand All @@ -202,7 +207,7 @@ func (c *BasicAuth) SanitizedCopy() *BasicAuth {
CreatedAt: c.CreatedAt,
ID: c.ID,
Username: c.Username,
Password: redactedString,
Password: redactedString(),
Tags: c.Tags,
},
}
Expand All @@ -217,7 +222,7 @@ func (c *Oauth2Credential) SanitizedCopy() *Oauth2Credential {
ID: c.ID,
Name: c.Name,
ClientID: c.ClientID,
ClientSecret: redactedString,
ClientSecret: redactedString(),
RedirectURIs: c.RedirectURIs,
Tags: c.Tags,
},
Expand Down
10 changes: 5 additions & 5 deletions internal/dataplane/kongstate/credentials_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func TestKeyAuth_SanitizedCopy(t *testing.T) {
want: KeyAuth{kong.KeyAuth{
CreatedAt: kong.Int(1),
ID: kong.String("2"),
Key: redactedString,
Key: redactedString(),
Tags: []*string{kong.String("4.1"), kong.String("4.2")},
}},
},
Expand Down Expand Up @@ -57,7 +57,7 @@ func TestHMACAuth_SanitizedCopy(t *testing.T) {
CreatedAt: kong.Int(1),
ID: kong.String("2"),
Username: kong.String("3"),
Secret: redactedString,
Secret: redactedString(),
Tags: []*string{kong.String("5.1"), kong.String("5.2")},
}},
},
Expand Down Expand Up @@ -93,7 +93,7 @@ func TestJWTAuth_SanitizedCopy(t *testing.T) {
Algorithm: kong.String("3"),
Key: kong.String("4"),
RSAPublicKey: kong.String("5"),
Secret: redactedString,
Secret: redactedString(),
Tags: []*string{kong.String("7.1"), kong.String("7.2")},
}},
},
Expand Down Expand Up @@ -125,7 +125,7 @@ func TestBasicAuth_SanitizedCopy(t *testing.T) {
CreatedAt: kong.Int(1),
ID: kong.String("2"),
Username: kong.String("3"),
Password: redactedString,
Password: redactedString(),
Tags: []*string{kong.String("5.1"), kong.String("5.2")},
}},
},
Expand Down Expand Up @@ -160,7 +160,7 @@ func TestOauth2Credential_SanitizedCopy(t *testing.T) {
ID: kong.String("2"),
Name: kong.String("3"),
ClientID: kong.String("4"),
ClientSecret: redactedString,
ClientSecret: redactedString(),
RedirectURIs: []*string{kong.String("6.1"), kong.String("6.2")},
Tags: []*string{kong.String("7.1"), kong.String("7.2")},
}},
Expand Down
8 changes: 4 additions & 4 deletions internal/dataplane/kongstate/kongstate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,16 +79,16 @@ func TestKongState_SanitizedCopy(t *testing.T) {
want: KongState{
Services: []Service{{Service: kong.Service{ID: kong.String("1")}}},
Upstreams: []Upstream{{Upstream: kong.Upstream{ID: kong.String("1")}}},
Certificates: []Certificate{{Certificate: kong.Certificate{ID: kong.String("1"), Key: redactedString}}},
Certificates: []Certificate{{Certificate: kong.Certificate{ID: kong.String("1"), Key: redactedString()}}},
CACertificates: []kong.CACertificate{{ID: kong.String("1")}},
Plugins: []Plugin{{
SensitiveFieldsMeta: PluginSensitiveFieldsMetadata{WholeConfigIsSensitive: true},
Plugin: kong.Plugin{ID: kong.String("1"), Config: kong.Configuration{"secret": *redactedString}},
Plugin: kong.Plugin{ID: kong.String("1"), Config: kong.Configuration{"secret": *redactedString()}},
}},
Consumers: []Consumer{{
KeyAuths: []*KeyAuth{{kong.KeyAuth{ID: kong.String("1"), Key: redactedString}}},
KeyAuths: []*KeyAuth{{kong.KeyAuth{ID: kong.String("1"), Key: redactedString()}}},
}},
Licenses: []License{{kong.License{ID: kong.String("1"), Payload: redactedString}}},
Licenses: []License{{kong.License{ID: kong.String("1"), Payload: redactedString()}}},
ConsumerGroups: []ConsumerGroup{{
ConsumerGroup: kong.ConsumerGroup{ID: kong.String("1"), Name: kong.String("consumer-group")},
}},
Expand Down
2 changes: 1 addition & 1 deletion internal/dataplane/kongstate/license.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ func (l License) SanitizedCopy() *License {
return &License{
License: kong.License{
ID: l.ID,
Payload: redactedString,
Payload: redactedString(),
CreatedAt: l.CreatedAt,
UpdatedAt: l.UpdatedAt,
},
Expand Down
4 changes: 2 additions & 2 deletions internal/dataplane/kongstate/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func (p Plugin) SanitizedCopy() Plugin {
patchOperations = append(patchOperations, fmt.Sprintf(
`{"op":"replace","path":"%s","value":"%s"}`,
path,
*redactedString,
*redactedString(),
))
}

Expand Down Expand Up @@ -100,7 +100,7 @@ func (p Plugin) SanitizedCopy() Plugin {
func sanitizeWholePluginConfig(config kong.Configuration) kong.Configuration {
sanitized := config.DeepCopy()
for k := range config {
sanitized[k] = *redactedString
sanitized[k] = *redactedString()
}
return sanitized
}
Expand Down
2 changes: 1 addition & 1 deletion internal/dataplane/kongstate/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func (c *Certificate) SanitizedCopy() *Certificate {
kong.Certificate{
ID: c.ID,
Cert: c.Cert,
Key: redactedString,
Key: redactedString(),
CreatedAt: c.CreatedAt,
SNIs: c.SNIs,
Tags: c.Tags,
Expand Down
2 changes: 1 addition & 1 deletion internal/dataplane/kongstate/types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func TestCertificate_SanitizedCopy(t *testing.T) {
want: Certificate{kong.Certificate{
ID: kong.String("1"),
Cert: kong.String("2"),
Key: redactedString,
Key: redactedString(),
CreatedAt: int64Ptr(4),
SNIs: []*string{kong.String("5.1"), kong.String("5.2")},
Tags: []*string{kong.String("6.1"), kong.String("6.2")},
Expand Down

0 comments on commit 1ce7f48

Please sign in to comment.