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  }