Skip to content

Commit 039f25f

Browse files
committed
Merge branch '434-mask-sensitive-values' into 'master'
fix(engine): mask sensitive environment variables from configuration in UI (#434) Closes #434 See merge request postgres-ai/database-lab!608
2 parents b7dd69e + 46519ad commit 039f25f

File tree

3 files changed

+111
-0
lines changed

3 files changed

+111
-0
lines changed

engine/internal/srv/config.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ func adminConfigYaml() ([]byte, error) {
167167
}
168168

169169
yamlUtils.DefaultConfigMask().Yaml(document)
170+
yamlUtils.TraverseNode(document)
170171

171172
doc, err := yaml.Marshal(document)
172173
if err != nil {

engine/pkg/util/yaml/custom.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Package yaml contains utilities to work with YAML nodes
2+
package yaml
3+
4+
import (
5+
"strings"
6+
7+
"gopkg.in/yaml.v3"
8+
)
9+
10+
var secretKeyList = []string{"secret", "key", "token", "password"}
11+
12+
// TraverseNode traverses node and mask sensitive keys.
13+
func TraverseNode(node *yaml.Node) {
14+
switch node.Kind {
15+
case yaml.DocumentNode:
16+
if len(node.Content) < 1 {
17+
return
18+
}
19+
20+
TraverseNode(node.Content[0])
21+
22+
case yaml.MappingNode:
23+
for i := 0; i < len(node.Content); i += 2 {
24+
if node.Content[i+1].Kind == yaml.ScalarNode {
25+
if containsSecret(strings.ToLower(node.Content[i].Value)) {
26+
node.Content[i+1].Value = maskValue
27+
node.Content[i+1].Tag = "!!str"
28+
}
29+
30+
continue
31+
}
32+
33+
TraverseNode(node.Content[i+1])
34+
}
35+
}
36+
}
37+
38+
func containsSecret(key string) bool {
39+
for _, secret := range secretKeyList {
40+
if strings.Contains(key, secret) {
41+
return true
42+
}
43+
}
44+
45+
return false
46+
}

engine/pkg/util/yaml/custom_test.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package yaml
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/require"
7+
"gopkg.in/yaml.v3"
8+
)
9+
10+
const customYamlStr = `
11+
global:
12+
debug: false
13+
retrieval:
14+
spec:
15+
logicalDump:
16+
options:
17+
source:
18+
type: local # local, remote, rds, etc..
19+
connection:
20+
dbname: test_22
21+
host: 172.17.0.78
22+
port: 5455
23+
username: tony
24+
password: mypass
25+
databases: test1
26+
envs:
27+
AWS_SECRET_ACCESS_KEY: john
28+
PGBACKREST_REPO1_S3_KEY_SECRET: mysecretkey
29+
TEST_ENV: one
30+
`
31+
32+
func TestTraverseNode(t *testing.T) {
33+
r := require.New(t)
34+
node := &yaml.Node{}
35+
36+
err := yaml.Unmarshal([]byte(customYamlStr), node)
37+
r.NoError(err)
38+
TraverseNode(node)
39+
40+
sensitive, found := FindNodeAtPathString(node, "retrieval.spec.logicalDump.options.envs.AWS_SECRET_ACCESS_KEY")
41+
r.NotNil(sensitive)
42+
r.True(found)
43+
r.Equal(maskValue, sensitive.Value)
44+
45+
sensitive2, found := FindNodeAtPathString(node, "retrieval.spec.logicalDump.options.envs.PGBACKREST_REPO1_S3_KEY_SECRET")
46+
r.NotNil(sensitive2)
47+
r.True(found)
48+
r.Equal(maskValue, sensitive2.Value)
49+
50+
nonSensitive, found := FindNodeAtPathString(node, "retrieval.spec.logicalDump.options.envs.TEST_ENV")
51+
r.NotNil(nonSensitive)
52+
r.True(found)
53+
r.Equal("one", nonSensitive.Value)
54+
55+
password, found := FindNodeAtPathString(node, "retrieval.spec.logicalDump.options.source.connection.password")
56+
r.NotNil(password)
57+
r.True(found)
58+
r.Equal(maskValue, password.Value)
59+
60+
host, found := FindNodeAtPathString(node, "retrieval.spec.logicalDump.options.source.connection.host")
61+
r.NotNil(host)
62+
r.True(found)
63+
r.Equal("172.17.0.78", host.Value)
64+
}

0 commit comments

Comments
 (0)