github.com/grahambrereton-form3/tilt@v0.10.18/pkg/model/secret.go (about) 1 package model 2 3 import ( 4 "bytes" 5 "encoding/base64" 6 "fmt" 7 ) 8 9 // Don't scrub secrets less than 5 characters, 10 // to avoid weird behavior where we scrub too much 11 // https://app.clubhouse.io/windmill/story/3568/small-secrets-lead-to-weird-behavior 12 const minSecretLengthToScrub = 5 13 14 // Secrets are different than other kinds of build/deploy outputs. 15 // 16 // Once something is marked as a secret, we want to scrub it from all logs 17 // until the user quits Tilt. Removing the secret from the Kubernetes cluster 18 // doesn't suddenly "reveal" the secret. 19 type SecretSet map[string]Secret 20 21 func (s SecretSet) AddAll(other SecretSet) { 22 for key, val := range other { 23 s[key] = val 24 } 25 } 26 27 func (s SecretSet) AddSecret(name string, key string, value []byte) { 28 v := string(value) 29 valueEncoded := base64.StdEncoding.EncodeToString(value) 30 s[v] = Secret{ 31 Name: name, 32 Key: key, 33 Value: value, 34 ValueEncoded: []byte(valueEncoded), 35 Replacement: []byte(fmt.Sprintf("[redacted secret %s:%s]", name, key)), 36 } 37 } 38 39 func (s SecretSet) Scrub(text []byte) []byte { 40 for _, secret := range s { 41 text = secret.Scrub(text) 42 } 43 return text 44 } 45 46 type Secret struct { 47 // The name of the secret in the kubernetes cluster, so the user 48 // can look it up themselves. 49 Name string 50 51 Key string 52 53 Value []byte 54 55 ValueEncoded []byte 56 57 Replacement []byte 58 } 59 60 func (s Secret) Scrub(text []byte) []byte { 61 if len(s.Value) < minSecretLengthToScrub { 62 return text 63 } 64 if bytes.Contains(text, s.Value) { 65 text = bytes.ReplaceAll(text, s.Value, s.Replacement) 66 } 67 if bytes.Contains(text, s.ValueEncoded) { 68 text = bytes.ReplaceAll(text, s.ValueEncoded, s.Replacement) 69 } 70 return text 71 }