github.com/grailbio/base@v0.0.11/security/keycrypt/keycrypt.go (about)

     1  // Copyright 2018 GRAIL, Inc. All rights reserved.
     2  // Use of this source code is governed by the Apache-2.0
     3  // license that can be found in the LICENSE file.
     4  
     5  // Package keycrypt implements an API for storing and retrieving
     6  // opaque blobs of data stored in a secure fashion. Keycrypt multiplexes
     7  // several backends, both local (e.g., macOS Keychain) and remote (e.g.,
     8  // AWS's KMS and S3).
     9  package keycrypt
    10  
    11  import (
    12  	"encoding/json"
    13  	"errors"
    14  )
    15  
    16  var ErrNoSuchSecret = errors.New("no such secret")
    17  
    18  // Secret represents a single object. Secret objects are
    19  // uninterpreted bytes that are stored securely.
    20  type Secret interface {
    21  	// Retrieve the current value of this secret. If the secret does not
    22  	// exist, Get returns ErrNoSuchSecret.
    23  	Get() ([]byte, error)
    24  	// Write a new value for this secret.
    25  	Put([]byte) error
    26  }
    27  
    28  // Interface Keycrypt represents a secure secret storage.
    29  type Keycrypt interface {
    30  	// Look up the named secret. A secret is returned even if it does
    31  	// not yet exist. In this case, Secret.Get will return
    32  	// ErrNoSuchSecret.
    33  	Lookup(name string) Secret
    34  }
    35  
    36  type Resolver interface {
    37  	Resolve(host string) Keycrypt
    38  }
    39  
    40  type funcResolver func(string) Keycrypt
    41  
    42  func (f funcResolver) Resolve(host string) Keycrypt { return f(host) }
    43  func ResolverFunc(f func(string) Keycrypt) Resolver { return funcResolver(f) }
    44  
    45  // Retrieve the content from a secret and unmarshal
    46  // it into a value.
    47  func GetJSON(s Secret, v interface{}) error {
    48  	b, err := s.Get()
    49  	if err != nil {
    50  		return err
    51  	}
    52  	return json.Unmarshal(b, v)
    53  }
    54  
    55  // Marshal a value and write it into a secret.
    56  func PutJSON(s Secret, v interface{}) error {
    57  	b, err := json.Marshal(v)
    58  	if err != nil {
    59  		return err
    60  	}
    61  	return s.Put(b)
    62  }
    63  
    64  // Implements Secret.
    65  type static []byte
    66  
    67  func Static(b []byte) Secret          { return static(b) }
    68  func (s static) Get() ([]byte, error) { return []byte(s), nil }
    69  func (s static) Put([]byte) error     { return errors.New("illegal operation") }
    70  
    71  type nonexistent int
    72  
    73  func Nonexistent() Secret                { return nonexistent(0) }
    74  func (nonexistent) Get() ([]byte, error) { return nil, ErrNoSuchSecret }
    75  func (nonexistent) Put([]byte) error     { return errors.New("illegal operation") }