main
rb 48 lines 2.1 KB
Raw
1 # frozen_string_literal: true
2
3 # Active Record Encryption keys for data encrypted at rest — currently the
4 # per-user GitHub OAuth token (GithubConnection#access_token) and the upstream
5 # mirror credential (Repository#upstream_token).
6 #
7 # Keys come from the environment so real secrets never live in the repo:
8 #
9 # ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY
10 # ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY
11 # ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT
12 #
13 # In production these MUST be set (generate with `bin/rails db:encryption:init`);
14 # we fail loudly at boot if they're missing rather than silently storing tokens
15 # under a predictable key. In development and test we derive deterministic keys
16 # from secret_key_base so the app and specs run without extra setup — never used
17 # for real user tokens.
18 Rails.application.configure do
19 enc = config.active_record.encryption
20
21 primary = ENV["ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY"]
22 deterministic = ENV["ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY"]
23 salt = ENV["ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT"]
24
25 if primary.blank? || deterministic.blank? || salt.blank?
26 if Rails.env.production?
27 raise "Active Record Encryption keys are not configured. Set " \
28 "ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY, " \
29 "ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY and " \
30 "ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT " \
31 "(generate with `bin/rails db:encryption:init`)."
32 end
33
34 base = Rails.application.secret_key_base.to_s
35 base = "sigitsi-dev-encryption" if base.blank?
36 derive = ->(label) { Digest::SHA256.hexdigest("#{label}:#{base}")[0, 32] }
37 primary ||= derive.call("ar-enc-primary")
38 deterministic ||= derive.call("ar-enc-deterministic")
39 salt ||= derive.call("ar-enc-salt")
40 end
41
42 enc.primary_key = primary
43 enc.deterministic_key = deterministic
44 enc.key_derivation_salt = salt
45 # Tokens are opaque and never queried by ciphertext, so non-deterministic
46 # (randomized IV) encryption is the safer default.
47 enc.support_unencrypted_data = false
48 end