Problemas al agregar el gem vault-rails a un plugin

Estoy intentando agregar vault-rails a un plugin para cifrar claves que forman parte de un modelo que he añadido, siguiendo un ejemplo aquí: Plugin with custom gems - #4 by Falco

(¿Existe alguna forma de hacer esto ya en Discourse que no haya encontrado? Solo veo el plugin de cifrado…)

Si coloco esta línea en mi plugin.rb, obtengo Could not find 'rails' (>= 5.0) among 348 total gem(s). Agregar la misma línea al Gemfile de Discourse funciona sin problemas.

gem "vault-rails", "0.7.0", { require: false }
 (master *) pfaffman@shinytim:~/src/discourse-repos/discourse$ ./bin/rails c
Traceback (most recent call last):
	43: from ./bin/rails:17:in `<main>'
	42: from /home/pfaffman/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.0.3.3/lib/active_support/dependencies.rb:324:in `require'
	41: from /home/pfaffman/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.0.3.3/lib/active_support/dependencies.rb:291:in `load_dependency'
	40: from /home/pfaffman/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.0.3.3/lib/active_support/dependencies.rb:324:in `block in require'
	39: from /home/pfaffman/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/bootsnap-1.5.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:31:in `require'
	38: from /home/pfaffman/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/bootsnap-1.5.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require_with_bootsnap_lfi'
	37: from /home/pfaffman/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/bootsnap-1.5.1/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in `register'
	36: from /home/pfaffman/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/bootsnap-1.5.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `block in require_with_bootsnap_lfi'
	35: from /home/pfaffman/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/bootsnap-1.5.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `require'
	34: from /home/pfaffman/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/railties-6.0.3.3/lib/rails/commands.rb:18:in `<main>'
	33: from /home/pfaffman/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/railties-6.0.3.3/lib/rails/command.rb:46:in `invoke'
	32: from /home/pfaffman/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/railties-6.0.3.3/lib/rails/command/base.rb:69:in `perform'
	31: from /home/pfaffman/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/thor-1.0.1/lib/thor.rb:392:in `dispatch'
	30: from /home/pfaffman/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/thor-1.0.1/lib/thor/invocation.rb:127:in `invoke_command'
	29: from /home/pfaffman/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/thor-1.0.1/lib/thor/command.rb:27:in `run'
	28: from /home/pfaffman/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/railties-6.0.3.3/lib/rails/commands/console/console_command.rb:101:in `perform'
	27: from /home/pfaffman/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/railties-6.0.3.3/lib/rails/command/actions.rb:14:in `require_application_and_environment!'
	26: from /home/pfaffman/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/railties-6.0.3.3/lib/rails/command/actions.rb:22:in `require_application!'
	25: from /home/pfaffman/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.0.3.3/lib/active_support/dependencies.rb:324:in `require'
	24: from /home/pfaffman/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.0.3.3/lib/active_support/dependencies.rb:291:in `load_dependency'
	23: from /home/pfaffman/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activesupport-6.0.3.3/lib/active_support/dependencies.rb:324:in `block in require'
	22: from /home/pfaffman/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/bootsnap-1.5.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:31:in `require'
	21: from /home/pfaffman/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/bootsnap-1.5.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require_with_bootsnap_lfi'
	20: from /home/pfaffman/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/bootsnap-1.5.1/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in `register'
	19: from /home/pfaffman/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/bootsnap-1.5.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `block in require_with_bootsnap_lfi'
	18: from /home/pfaffman/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/bootsnap-1.5.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `require'
	17: from /home/pfaffman/src/discourse-repos/discourse/config/application.rb:70:in `<main>'
	16: from /home/pfaffman/src/discourse-repos/discourse/config/application.rb:71:in `<module:Discourse>'
	15: from /home/pfaffman/src/discourse-repos/discourse/config/application.rb:304:in `<class:Application>'
	14: from /home/pfaffman/src/discourse-repos/discourse/lib/plugin_initialization_guard.rb:5:in `plugin_initialization_guard'
	13: from /home/pfaffman/src/discourse-repos/discourse/config/application.rb:305:in `block in <class:Application>'
	12: from lib/discourse.rb:225:in `activate_plugins!'
	11: from lib/discourse.rb:225:in `each'
	10: from lib/discourse.rb:228:in `block in activate_plugins!'
	 9: from /home/pfaffman/src/discourse-repos/discourse/lib/plugin/instance.rb:611:in `activate!'
	 8: from /home/pfaffman/src/discourse-repos/discourse/lib/plugin/instance.rb:611:in `instance_eval'
	 7: from /home/pfaffman/src/discourse-repos/discourse/plugins/discourse-pfaffmanager/plugin.rb:13:in `activate!'
	 6: from /home/pfaffman/src/discourse-repos/discourse/lib/plugin/instance.rb:705:in `gem'
	 5: from /home/pfaffman/src/discourse-repos/discourse/lib/plugin_gem.rb:22:in `load'
	 4: from /home/pfaffman/.rbenv/versions/2.7.1/lib/ruby/site_ruby/2.7.0/rubygems/specification.rb:1371:in `activate'
	 3: from /home/pfaffman/.rbenv/versions/2.7.1/lib/ruby/site_ruby/2.7.0/rubygems/specification.rb:1389:in `activate_dependencies'
	 2: from /home/pfaffman/.rbenv/versions/2.7.1/lib/ruby/site_ruby/2.7.0/rubygems/specification.rb:1389:in `each'
	 1: from /home/pfaffman/.rbenv/versions/2.7.1/lib/ruby/site_ruby/2.7.0/rubygems/specification.rb:1400:in `block in activate_dependencies'
/home/pfaffman/.rbenv/versions/2.7.1/lib/ruby/site_ruby/2.7.0/rubygems/dependency.rb:311:in `to_specs': Could not find 'rails' (>= 5.0) among 348 total gem(s) (Gem::MissingSpecError)
Checked in 'GEM_PATH=/home/pfaffman/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0:/home/pfaffman/Dropbox/home/bin/dotfiles/.gem/ruby/2.7.0', execute `gem env` for more information

El post que has enlazado dice:

¿Has intentado hacer eso?

Discourse no tiene una dependencia de la gema Rails; solo importamos los módulos que necesitamos. La gema que deseas depende de la gema Rails completa, por lo que tendrás que añadir recursivamente cada dependencia que Discourse no incluya por defecto.

Me temo que será bastante trabajo, pero al menos te indicará exactamente lo que te falta.

3 Me gusta

Oh. Nunca se me habría ocurrido que rails no estaba cargado.

¡toda el árbol de dependencias! Entiendo.

Parece que hay un montón de cosas.

Voy a almacenar cosas como una clave de API de Digital Ocean y una clave SSH en la base de datos. ¿Sabes, de inmediato, otra forma sencilla de hacerlo de manera segura? Supongo que podría simplemente ejecutar un shell y lanzar vault o algo similar con un exec. No va a ocurrir con tanta frecuencia.

¿Quizás usar solo el gem vault, que solo depende de aws-sigv4 y aws-eventstream?

¿Qué quieres decir con “de forma segura” aquí? ¿Cuál es el Threat model - Wikipedia? ¿Estás intentando protegerlo de los administradores con acceso a Data Explorer? En ese caso, usar una variable de entorno simple debería ser más fácil.

1 me gusta

“Seguro” significa lo suficientemente seguro como para que estés dispuesto a proporcionar tu clave de API de Digital Ocean y tu clave de API de Mailgun para que mi pequeño plugin cree un droplet e instale Discourse en él, y luego genere una clave SSH que use para realizar actualizaciones y otras tareas.

Creo que la única medida de seguridad que añadiré en producción es que, si alguien roba la base de datos, no tendrá esas claves. Por supuesto, si hackean el servidor, todo vale.

Supongo que tendré que buscar una forma más ligera de cifrar estos pocos campos.

EDIT: https://pawelurbanek.com/rails-secure-encrypt-decrypt parece lo suficientemente sencillo y utiliza ActiveSupport::MessageEncryptor, que parece estar disponible de forma predeterminada.