Class: BoringServices::Secrets

Inherits:
Object
  • Object
show all
Defined in:
lib/boring_services/secrets.rb

Class Method Summary collapse

Class Method Details

.resolve(value) ⇒ Object



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# File 'lib/boring_services/secrets.rb', line 7

def self.resolve(value)
  return nil if value.nil? || value.to_s.strip.empty?

  value_str = value.to_s.strip

  if value_str.start_with?('credentials:')
    resolve_rails_credentials(value_str)
  elsif value_str.start_with?('$(') && value_str.end_with?(')')
    resolve_command(value_str[2..-2])
  elsif value_str.start_with?('$')
    resolve_env_var(value_str)
  else
    value_str
  end
end

.resolve_command(command) ⇒ Object

Raises:



54
55
56
57
58
59
60
61
62
# File 'lib/boring_services/secrets.rb', line 54

def self.resolve_command(command)
  argv = Shellwords.split(command)
  raise Error, 'Command secret is empty' if argv.empty?

  result, stderr, status = Open3.capture3(*argv)
  raise Error, "Command failed: #{argv.first}: #{stderr.strip}" unless status.success?

  result.strip
end

.resolve_env_var(value) ⇒ Object



47
48
49
50
51
52
# File 'lib/boring_services/secrets.rb', line 47

def self.resolve_env_var(value)
  var_name = value[1..]
  ENV.fetch(var_name) do
    raise Error, "Environment variable #{var_name} not set"
  end
end

.resolve_rails_credentials(value) ⇒ Object

Raises:



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/boring_services/secrets.rb', line 23

def self.resolve_rails_credentials(value)
  # Extract the key path from "credentials:ssl.certificate" -> "ssl.certificate"
  key_path = value.sub(/^credentials:/, '')
  keys = key_path.split('.')

  # Use rails credentials:show to fetch the value
  # This requires being run from the Rails root directory
  runner = "puts Rails.application.credentials.dig(#{keys.map { |key| key.to_sym.inspect }.join(', ')})"
  result, stderr, status = Open3.capture3(
    { 'RAILS_ENV' => ENV.fetch('RAILS_ENV', 'production') },
    'bundle', 'exec', 'rails', 'runner', runner
  )

  unless status.success?
    detail = stderr.strip.empty? ? 'Make sure you are running from the Rails root directory.' : stderr.strip
    raise Error, "Failed to resolve Rails credentials: #{key_path}. #{detail}"
  end

  result = result.strip
  raise Error, "Rails credentials key not found: #{key_path}" if result.empty?

  result
end