namespace :config do desc 'Verify config/app.yml contains no real secrets (safe for git)' task :check do require_relative '../opendax/config_loader' raw = YAML.load_file('config/app.yml') leaks = [] check_value = lambda do |path, value| return if value.nil? return unless value.is_a?(String) str = value.strip return if str.empty? || str == 'changeme' if str.match?(/\As\.[A-Za-z0-9]{20,}\z/) leaks << "#{path}: looks like a Vault token" elsif path.include?('password') && str != 'changeme' leaks << "#{path}: non-placeholder password" end end walk = lambda do |node, prefix| case node when Hash node.each { |k, v| walk.call(v, prefix.empty? ? k.to_s : "#{prefix}.#{k}") } when Array node.each_with_index { |v, i| walk.call(v, "#{prefix}[#{i}]") } else check_value.call(prefix, node) end end walk.call(raw, '') if leaks.any? puts 'FAIL: config/app.yml may contain secrets:' leaks.each { |l| puts " - #{l}" } puts 'Move sensitive values to config/app.local.yml or config/app.production.yml' exit 1 end overlay = Opendax::ConfigLoader.active_overlay puts 'OK: config/app.yml looks safe for git' puts "Active overlay: #{overlay || 'none'}" end end