github.com/Schaudge/grailbase@v0.0.0-20240223061707-44c758a471c0/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") }