github.com/zntrio/harp/v2@v2.0.9/pkg/vault/transformer.go (about)

     1  // Licensed to Elasticsearch B.V. under one or more contributor
     2  // license agreements. See the NOTICE file distributed with
     3  // this work for additional information regarding copyright
     4  // ownership. Elasticsearch B.V. licenses this file to you under
     5  // the Apache License, Version 2.0 (the "License"); you may
     6  // not use this file except in compliance with the License.
     7  // You may obtain a copy of the License at
     8  //
     9  //     http://www.apache.org/licenses/LICENSE-2.0
    10  //
    11  // Unless required by applicable law or agreed to in writing,
    12  // software distributed under the License is distributed on an
    13  // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    14  // KIND, either express or implied.  See the License for the
    15  // specific language governing permissions and limitations
    16  // under the License.
    17  
    18  package vault
    19  
    20  import (
    21  	"fmt"
    22  	"path"
    23  	"strings"
    24  
    25  	"github.com/zntrio/harp/v2/pkg/sdk/value"
    26  	"github.com/zntrio/harp/v2/pkg/sdk/value/encryption"
    27  	"github.com/zntrio/harp/v2/pkg/sdk/value/encryption/aead"
    28  	"github.com/zntrio/harp/v2/pkg/sdk/value/encryption/envelope"
    29  	"github.com/zntrio/harp/v2/pkg/sdk/value/encryption/secretbox"
    30  	vaultpath "github.com/zntrio/harp/v2/pkg/vault/path"
    31  )
    32  
    33  type DataEncryption string
    34  
    35  var (
    36  	AESGCM           DataEncryption = "aesgcm"
    37  	Chacha20Poly1305 DataEncryption = "chacha20poly1305"
    38  	Secretbox        DataEncryption = "secretbox"
    39  )
    40  
    41  func init() {
    42  	encryption.Register("vault", FromKey)
    43  }
    44  
    45  // Vault returns an envelope encryption using a remote transit backend for key
    46  // encryption.
    47  // vault:<path>:<data encryption>
    48  func FromKey(key string) (value.Transformer, error) {
    49  	// Remove the prefix
    50  	key = strings.TrimPrefix(key, "vault:")
    51  
    52  	// Split path / encryption
    53  	parts := strings.SplitN(key, ":", 2)
    54  	if len(parts) != 2 {
    55  		return nil, fmt.Errorf("key format error, invalid part count")
    56  	}
    57  
    58  	// Split transit backend path
    59  	mountPath, keyName := path.Split(parts[0])
    60  
    61  	// Delegate to transformer
    62  	return Transformer(mountPath, keyName, DataEncryption(parts[1]))
    63  }
    64  
    65  func TransformerKey(mountPath, keyName string, dataEncryption DataEncryption) string {
    66  	return fmt.Sprintf("vault:%s/%s:%s", vaultpath.SanitizePath(mountPath), strings.TrimPrefix(keyName, "/"), dataEncryption)
    67  }
    68  
    69  // Transformer returns an envelope encryption using a remote transit backend for key
    70  // encryption.
    71  func Transformer(mountPath, keyName string, dataEncryption DataEncryption) (value.Transformer, error) {
    72  	// Create default vault client
    73  	client, err := DefaultClient()
    74  	if err != nil {
    75  		return nil, fmt.Errorf("unable to initialize vault client: %w", err)
    76  	}
    77  
    78  	// Create transit backend service
    79  	backend, err := client.Transit(vaultpath.SanitizePath(mountPath), keyName)
    80  	if err != nil {
    81  		return nil, fmt.Errorf("unable to initialize vault transit backend service: %w", err)
    82  	}
    83  
    84  	// Prepare data encryption
    85  	var dataEncryptionFunc encryption.TransformerFactoryFunc
    86  	switch dataEncryption {
    87  	case AESGCM:
    88  		dataEncryptionFunc = aead.AESGCM
    89  	case Chacha20Poly1305:
    90  		dataEncryptionFunc = aead.Chacha20Poly1305
    91  	case Secretbox:
    92  		dataEncryptionFunc = secretbox.Transformer
    93  	default:
    94  		return nil, fmt.Errorf("unsupported data encryption %q for envelope transformer", dataEncryption)
    95  	}
    96  
    97  	// Wrap the transformer with envelope
    98  	return envelope.Transformer(backend, dataEncryptionFunc)
    99  }