Project

General

Profile

How to use encrypted database credentials » History » Version 1

Jan Catrysse, 2024-09-29 12:27

1 1 Jan Catrysse
{{TOC}}
2
3
h1. Securing Sensitive Credentials in Redmine using Rails Encrypted Credentials
4
5
Managing sensitive information such as database credentials securely is crucial for any Redmine installation. This guide walks through the process of securing database passwords by leveraging the encrypted credentials feature in Rails. 
6
7
Starting with **Rails 5.2**, sensitive data (like API keys, database passwords, etc.) can be stored in an encrypted format, ensuring that only your Redmine instance with access to the decryption key can read it.
8
9
h2. Steps for Securing Credentials
10
11
h3. Generate the Master Key
12
When you use Rails credentials for the first time, Rails will generate a master key. This key is critical to encrypt and decrypt your credentials. Run the following commands to edit the encrypted credentials file:
13
14
<pre><code class="shell">
15
sudo su - redmine # Login on your SSH prompt as the Redmine user
16
cd /var/www/redmine/  # Change to the Redmine home directory
17
EDITOR="nano" bundle exec rails credentials:edit  # Start editing the credentials file using your favorite editor: nano
18
</code></pre>
19
20
Add your database credentials inside the encrypted credentials file:
21
22
<pre><code class="shell">
23
db:
24
  username: redmine
25
  password: super_secure_password
26
</code></pre>
27
28
h3. Securely Store the Master Key
29
30
The @config/master.key@ file must be stored securely and excluded from your version control system. 
31
Ensure it is added to @.gitignore@. Only environments that need to read the encrypted credentials should have access to the master key.
32
This step is already partialy taken care of by the previous @rails credentials:edit@ command.
33
34
<pre><code class="shell">
35
   echo 'config/master.key' >> .gitignore
36
   echo 'config/credentials.yml.enc' >> .gitignore
37
</code></pre>
38
39
Verify @config/credentials.yml.enc@ and @onfig/master.key@ ownership and permissions.
40
41
h3. Modify @database.yml@ to Reference Encrypted Credentials
42
43
Now, reference your encrypted credentials in @config/database.yml@:
44
45
<pre><code class="shell">
46
production:
47
  adapter: postgresql
48
  database: redmine
49
  host: db01.int.geoxyz.eu
50
  username: <%= Rails.application.credentials.dig(:db, :username) %>
51
  password: <%= Rails.application.credentials.dig(:db, :password) %>
52
  sslmode: require
53
  encoding: utf8
54
  schema_search_path: public
55
  pool: 20
56
</code></pre>
57
58
This approach ensures that your database passwords are stored securely and can only be decrypted by systems with access to the @master.key@.
59
60
h3. Patching the @Gemfile@
61
62
Refer to the Redmine @Gemfile@ patch below that resolves issues when parsing the @database.yml@ file using ERB: #41331
63
64
<pre><code class="diff">
65
Index: Gemfile
66
IDEA additional info:
67
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
68
<+>UTF-8
69
===================================================================
70
diff --git a/Gemfile b/Gemfile
71
--- a/Gemfile	(revision 277728afc979a7123eef8d1a8ac54d74c235c5fc)
72
+++ b/Gemfile	(date 1727590462090)
73
@@ -61,7 +61,7 @@
74
 require 'yaml'
75
 database_file = File.join(File.dirname(__FILE__), "config/database.yml")
76
 if File.exist?(database_file)
77
-  yaml_config = ERB.new(IO.read(database_file)).result
78
+  yaml_config = ERB.new(IO.readlines(database_file).reject { |line| line =~ /<%.*%>/ }.join).result
79
   database_config = YAML.respond_to?(:unsafe_load) ? YAML.unsafe_load(yaml_config) : YAML.load(yaml_config)
80
   adapters = database_config.values.filter_map {|c| c['adapter']}.uniq
81
   if adapters.any?
82
</code></pre>