Class: Hippo::SecretManager
- Inherits:
-
Object
- Object
- Hippo::SecretManager
- Defined in:
- lib/hippo/secret_manager.rb
Constant Summary collapse
- CIPHER =
OpenSSL::Cipher.new('aes-256-gcm')
Instance Attribute Summary collapse
-
#key ⇒ Object
readonly
Returns the value of attribute key.
-
#recipe ⇒ Object
readonly
Returns the value of attribute recipe.
-
#stage ⇒ Object
readonly
Returns the value of attribute stage.
Instance Method Summary collapse
-
#create_key ⇒ void
Generate and publish a new secret key to the Kubernetes API.
-
#decrypt(value) ⇒ String
Decrypt the given value value and return it.
-
#download_key ⇒ void
Download the current key from the Kubernetes API and set it as the key for this instance.
- #encrypt(value) ⇒ Object
-
#initialize(recipe, stage) ⇒ SecretManager
constructor
A new instance of SecretManager.
- #key_available? ⇒ Boolean
- #secret(name) ⇒ Object
- #secrets ⇒ Object
Constructor Details
#initialize(recipe, stage) ⇒ SecretManager
Returns a new instance of SecretManager.
14 15 16 17 |
# File 'lib/hippo/secret_manager.rb', line 14 def initialize(recipe, stage) @recipe = recipe @stage = stage end |
Instance Attribute Details
#key ⇒ Object (readonly)
Returns the value of attribute key.
10 11 12 |
# File 'lib/hippo/secret_manager.rb', line 10 def key @key end |
#recipe ⇒ Object (readonly)
Returns the value of attribute recipe.
8 9 10 |
# File 'lib/hippo/secret_manager.rb', line 8 def recipe @recipe end |
#stage ⇒ Object (readonly)
Returns the value of attribute stage.
9 10 11 |
# File 'lib/hippo/secret_manager.rb', line 9 def stage @stage end |
Instance Method Details
#create_key ⇒ void
This method returns an undefined value.
Generate and publish a new secret key to the Kubernetes API.
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/hippo/secret_manager.rb', line 22 def create_key if key_available? raise Hippo::Error, 'A key already exists on Kubernetes. Remove this first.' end CIPHER.encrypt secret_key = CIPHER.random_key secret_key64 = Base64.encode64(secret_key).gsub("\n", '').strip object = { 'apiVersion' => 'v1', 'kind' => 'Secret', 'type' => 'hippo.adam.ac/secret-encryption-key', 'metadata' => { 'name' => 'hippo-secret-key', 'namespace' => @stage.namespace }, 'data' => { 'key' => Base64.encode64(secret_key64).gsub("\n", '').strip } } @recipe.kubernetes.apply_with_kubectl(object.to_yaml) @key = secret_key end |
#decrypt(value) ⇒ String
Decrypt the given value value and return it
88 89 90 91 92 93 94 95 96 97 |
# File 'lib/hippo/secret_manager.rb', line 88 def decrypt(value) value = value.to_s if value =~ /\Aencrypted:(.*)/ value = Base64.decode64(Regexp.last_match(1)) encrypted_value, salt, iv = value.split('---', 3).map { |s| Base64.decode64(s) } Encryptor.decrypt(value: encrypted_value, key: @key, iv: iv, salt: salt).to_s else value end end |
#download_key ⇒ void
This method returns an undefined value.
Download the current key from the Kubernetes API and set it as the key for this instance
45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/hippo/secret_manager.rb', line 45 def download_key return if @key value = @recipe.kubernetes.get_with_kubectl(@stage, 'secret', 'hippo-secret-key').first return if value.nil? return if value.dig('data', 'key').nil? @key = Base64.decode64(Base64.decode64(value['data']['key'])) rescue Hippo::Error => e raise unless e. =~ /not found/ end |
#encrypt(value) ⇒ Object
72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/hippo/secret_manager.rb', line 72 def encrypt(value) CIPHER.encrypt iv = CIPHER.random_iv salt = SecureRandom.random_bytes(16) encrypted_value = Encryptor.encrypt(value: value.to_s, key: @key, iv: iv, salt: salt) 'encrypted:' + Base64.encode64([ Base64.encode64(encrypted_value), Base64.encode64(salt), Base64.encode64(iv) ].join('---')).gsub("\n", '') end |
#key_available? ⇒ Boolean
57 58 59 60 |
# File 'lib/hippo/secret_manager.rb', line 57 def key_available? download_key !@key.nil? end |
#secret(name) ⇒ Object
62 63 64 |
# File 'lib/hippo/secret_manager.rb', line 62 def secret(name) Secret.new(self, name) end |
#secrets ⇒ Object
66 67 68 69 70 |
# File 'lib/hippo/secret_manager.rb', line 66 def secrets Dir[File.join('secrets', @stage.name, '**', '*.{yml,yaml}')].map do |path| secret(path.split('/').last.sub(/\.ya?ml\z/, '')) end end |