Class: HasHelpers::ServiceTrust::KeyManager
- Inherits:
-
Object
- Object
- HasHelpers::ServiceTrust::KeyManager
- Defined in:
- lib/has_helpers/service_trust/key_manager.rb
Defined Under Namespace
Classes: EnvKey
Constant Summary collapse
- ADVISORY_LOCK_KEY =
8_472_901
Class Method Summary collapse
- .current_signing_key ⇒ Object
- .env ⇒ Object
- .generate_first_key! ⇒ Object
- .generate_keypair ⇒ Object
- .invalidate_cache! ⇒ Object
- .retire!(kid) ⇒ Object
- .rotate!(verifiable_for: 1.hour) ⇒ Object
- .verifiable_keys ⇒ Object
Class Method Details
.current_signing_key ⇒ Object
30 31 32 33 34 35 36 |
# File 'lib/has_helpers/service_trust/key_manager.rb', line 30 def current_signing_key cache.synchronize do @current_signing_key ||= load_from_env || load_or_generate_from_db raise_if_env_mismatch!(@current_signing_key) @current_signing_key end end |
.env ⇒ Object
82 83 84 |
# File 'lib/has_helpers/service_trust/key_manager.rb', line 82 def env HasHelpers::ServiceTrust.config.environment.to_s end |
.generate_first_key! ⇒ Object
69 70 71 |
# File 'lib/has_helpers/service_trust/key_manager.rb', line 69 def generate_first_key! load_or_generate_from_db end |
.generate_keypair ⇒ Object
86 87 88 |
# File 'lib/has_helpers/service_trust/key_manager.rb', line 86 def generate_keypair OpenSSL::PKey::RSA.generate(2048) end |
.invalidate_cache! ⇒ Object
78 79 80 |
# File 'lib/has_helpers/service_trust/key_manager.rb', line 78 def invalidate_cache! cache.synchronize { @current_signing_key = nil } end |
.retire!(kid) ⇒ Object
73 74 75 76 |
# File 'lib/has_helpers/service_trust/key_manager.rb', line 73 def retire!(kid) HasHelpers::ServiceTrust::Key.for_env(env).find_by!(kid: kid).update!(active: false, retired_at: Time.current, verifiable_until: Time.current) invalidate_cache! end |
.rotate!(verifiable_for: 1.hour) ⇒ Object
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/has_helpers/service_trust/key_manager.rb', line 44 def rotate!(verifiable_for: 1.hour) raise ConfigurationError, "cannot rotate ENV-backed ServiceTrust keys" if load_from_env HasHelpers::ServiceTrust::Key.transaction do with_advisory_lock do old = HasHelpers::ServiceTrust::Key.active_for_env(env).first keypair = generate_keypair # retired_at is set to a FUTURE timestamp so the key stays in JWKS # (verifiable_for_env scope keeps rows where retired_at IS NULL OR retired_at > NOW) # until the rotation overlap window elapses. old&.update!(active: false, verifiable_until: Time.current + verifiable_for, retired_at: Time.current + verifiable_for) new_key = HasHelpers::ServiceTrust::Key.create!( environment: env, kid: new_kid, public_key_pem: keypair.public_key.to_pem, private_key_pem: keypair.to_pem, algorithm: "RS256", active: true ) invalidate_cache! new_key end end end |
.verifiable_keys ⇒ Object
38 39 40 41 42 |
# File 'lib/has_helpers/service_trust/key_manager.rb', line 38 def verifiable_keys current = current_signing_key db_keys = defined?(HasHelpers::ServiceTrust::Key) ? HasHelpers::ServiceTrust::Key.verifiable_for_env(env).to_a : [] ([current] + db_keys.reject { |key| same_key?(key, current) }).uniq(&:kid) end |