Skip to content

Commit

Permalink
Merge pull request #228 from 18F/stages/rc-2021-04-22
Browse files Browse the repository at this point in the history
Deploy RC 19 to Prod
  • Loading branch information
amathews-fs committed Apr 22, 2021
2 parents 71bba84 + 17aed6e commit b7b3bbe
Show file tree
Hide file tree
Showing 39 changed files with 308 additions and 370 deletions.
4 changes: 2 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:
- run:
name: Test Setup
command: |
cp config/application.yml.example config/application.yml
cp config/application.yml.default config/application.yml
bundle exec rake db:setup --trace
- run:
Expand Down Expand Up @@ -108,7 +108,7 @@ jobs:
- run:
name: Test Setup
command: |
cp config/application.yml.example config/application.yml
cp config/application.yml.default config/application.yml
bundle exec rake db:setup --trace
- run:
name: Check for expiring certs
Expand Down
4 changes: 2 additions & 2 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ gem 'rails', '~> 6.1.3'
gem 'activerecord-import', '>= 1.0.2'
gem 'aws-sdk', require: false
gem 'bloomfilter-rb'
gem 'figaro'
gem 'health_check', '>= 3.0.0'
gem 'identity-hostdata', github: '18F/identity-hostdata', tag: 'v1.0.1'
gem 'identity-hostdata', github: '18F/identity-hostdata', tag: 'v3.1.0'
gem 'identity-logging', github: '18F/identity-logging', tag: 'v0.1.0'
gem 'mini_cache'
gem 'newrelic_rpm'
gem 'pg'
gem 'pry-rails'
gem 'puma', '~> 3.12', '>= 3.12.6'
gem 'redacted_struct', '~> 1.0'
gem 'rgl'

group :development, :test do
Expand Down
14 changes: 7 additions & 7 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
GIT
remote: https://github.com/18F/identity-hostdata.git
revision: 0f8d4626709d6031acdfe0b024faefede928f8aa
tag: v1.0.1
revision: 4f978b9f2e573e99f54c69869846c7aae983c4ae
tag: v3.1.0
specs:
identity-hostdata (1.0.1)
identity-hostdata (3.1.0)
activesupport (~> 6.1)
aws-sdk-s3 (~> 1.8)

GIT
Expand Down Expand Up @@ -1109,8 +1110,6 @@ GEM
colorize (~> 0.7)
ruby_parser (>= 3.14.1)
ffi (1.13.1)
figaro (1.2.0)
thor (>= 0.14.0, < 2)
formatador (0.2.5)
get_process_mem (0.2.7)
ffi (~> 1.0)
Expand Down Expand Up @@ -1236,6 +1235,7 @@ GEM
rb-fsevent (0.10.4)
rb-inotify (0.10.1)
ffi (~> 1.0)
redacted_struct (1.1.0)
redis (4.2.4)
regexp_parser (1.8.2)
request_store (1.5.0)
Expand Down Expand Up @@ -1348,7 +1348,6 @@ DEPENDENCIES
factory_bot_rails (>= 5.2.0)
fakefs
fasterer
figaro
guard-rspec
health_check (>= 3.0.0)
identity-hostdata!
Expand All @@ -1364,6 +1363,7 @@ DEPENDENCIES
rails (~> 6.1.3)
rails-controller-testing (>= 1.0.4)
rails-erd (>= 1.6.0)
redacted_struct (~> 1.0)
rgl
rspec-rails (>= 3.8.3)
rubocop
Expand All @@ -1380,4 +1380,4 @@ RUBY VERSION
ruby 2.6.5p114

BUNDLED WITH
2.1.4
2.2.16
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ PORT ?= 8443

all: check

setup $(CONFIG): config/application.yml.example
setup $(CONFIG): config/application.yml.default
bin/setup

fast_setup:
Expand Down
4 changes: 2 additions & 2 deletions app/controllers/identify_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def certificate_none_error
def client_cert
cert_pem = request.headers[CERT_HEADER] || request.headers.env['rack.peer_cert']
return unless cert_pem
if Figaro.env.client_cert_escaped == 'true'
if IdentityConfig.store.client_cert_escaped
CGI.unescape(cert_pem)
else
cert_pem.delete("\t")
Expand Down Expand Up @@ -93,7 +93,7 @@ def referrer
end

def allowed_referrer?(uri)
allowed_host = Figaro.env.identity_idp_host
allowed_host = IdentityConfig.store.identity_idp_host
!allowed_host || uri.host == allowed_host
end
end
2 changes: 1 addition & 1 deletion app/policies/certificate_policies.rb
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,6 @@ def get_extension(oid)
end

def required_policies
JSON.parse(Figaro.env.required_policies || '[]')
IdentityConfig.store.required_policies
end
end
2 changes: 1 addition & 1 deletion app/services/certificate_logger_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def log_ocsp_response(response)

def bucket
@bucket ||= begin
bucket_name = Figaro.env.client_cert_logger_s3_bucket_name
bucket_name = IdentityConfig.store.client_cert_logger_s3_bucket_name
Aws::S3::Resource.new.bucket(bucket_name) if bucket_name.present?
end
end
Expand Down
6 changes: 3 additions & 3 deletions app/services/certificate_store.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def self.reset
end

# load all of the files in config/certs
def load_certs!(dir: Figaro.env.certificate_store_directory)
def load_certs!(dir: IdentityConfig.store.certificate_store_directory)
Dir.chdir(dir) do
Dir.glob(File.join('**', '*.pem')).each do |file|
next if file == 'all_certs_deploy.pem'
Expand Down Expand Up @@ -107,12 +107,12 @@ def all_certificates_valid?

def self.trusted_ca_root_identifiers
@trusted_ca_root_identifiers ||=
(Figaro.env.trusted_ca_root_identifiers || '').split(',').map(&:strip).select(&:present?)
IdentityConfig.store.trusted_ca_root_identifiers.map(&:strip).select(&:present?)
end

def self.dod_root_identifiers
@dod_root_identifiers ||=
(Figaro.env.dod_root_identifiers || '').split(',').map(&:strip).select(&:present?)
IdentityConfig.store.dod_root_identifiers.map(&:strip).select(&:present?)
end

def self.clear_root_identifiers
Expand Down
2 changes: 1 addition & 1 deletion app/services/issuing_ca_service.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
class IssuingCaService
CA_ISSUER_HOST_ALLOW_LIST = Figaro.env.ca_issuer_host_allow_list.split(',')
CA_ISSUER_HOST_ALLOW_LIST = IdentityConfig.store.ca_issuer_host_allow_list

class UnexpectedPKCS7Response < StandardError; end

Expand Down
5 changes: 2 additions & 3 deletions app/services/ocsp_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,8 @@ def make_single_http_request(uri, request, retries = 0)

def make_single_http_request!(uri, request)
http = Net::HTTP.new(uri.hostname, uri.port)
env = Figaro.env
http.open_timeout = env.http_open_timeout.to_i
http.read_timeout = env.http_read_timeout.to_i
http.open_timeout = IdentityConfig.store.http_open_timeout
http.read_timeout = IdentityConfig.store.http_read_timeout
http.post(uri.path.presence || '/', request, 'content-type' => 'application/ocsp-request')
end

Expand Down
70 changes: 27 additions & 43 deletions app/services/token_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ class TokenService
RANDOM_BYTES = 8

class << self
def box(data)
def box(data, encryptor = nil)
encryptor ||= message_encryptor
# The RANDOM_BYTES are there to introduce some entropy since we aren't putting a lot
# of information into the token. Ruby hashes serialize in the order the keys are
# introduced, so the data is sandwiched between two random strings, though that is
# sandwiched in non-random strings -- namely, `{` and `}` to open/close the JSON object.
message_encryptor.encrypt_and_sign(
encryptor.encrypt_and_sign(
{ r1: SecureRandom.base64(RANDOM_BYTES) }.
merge(data).
merge(r2: SecureRandom.base64(RANDOM_BYTES)).to_json,
Expand All @@ -30,7 +31,7 @@ def open(crypt, hmac_header = '')
private

def authentic?(token, hmac_header)
secret = Figaro.env.piv_cac_verify_token_secret
secret = IdentityConfig.store.piv_cac_verify_token_secret
# TODO: once everything is deployed and configured and working, we'll
# switch to requiring the secret be configured
# return true if secret.blank?
Expand Down Expand Up @@ -65,35 +66,43 @@ def bloom_filter
end

def bloom_filter_spec
env = Figaro.env
size = (env.nonce_bloom_filter_size || 100_000).to_i
{ identifier: env.nonce_bloom_filter_prefix || 'nonce',
ttl: env.nonce_bloom_filter_ttl || TOKEN_LIFESPAN,
hashes: env.nonce_bloom_filter_hash_count || 4,
size: size,
env = IdentityConfig.store
{ identifier: env.nonce_bloom_filter_prefix,
ttl: env.nonce_bloom_filter_ttl,
hashes: env.nonce_bloom_filter_hash_count,
size: env.nonce_bloom_filter_size,
seed: 123_456_789 }
end

def bloom_filter_server
{ url: Figaro.env.nonce_bloom_filter_server || 'redis://localhost/' }
{ url: IdentityConfig.store.nonce_bloom_filter_server }
end

def message_encryptor
@message_encryptor ||= begin
encryptor = ActiveSupport::MessageEncryptor.new(current_key, cipher: 'aes-256-gcm')
prior_keys.each { |key| encryptor.rotate key }
encryptor
return @message_encryptor if @message_encryptor

encryptor = ActiveSupport::MessageEncryptor.new(current_key, cipher: 'aes-256-gcm')
old_key = prior_key

if old_key
encryptor.rotate prior_key
end

@message_encryptor = encryptor
end

def current_key
salt, pepper = key_salt_and_pepper
salt = IdentityConfig.store.token_encryption_key_salt
pepper = IdentityConfig.store.token_encryption_key_pepper

truncate_key(ActiveSupport::KeyGenerator.new(pepper).generate_key(salt))
end

def prior_keys
prior_key_signifiers.map do |ending|
old_salt, old_pepper = key_salt_and_pepper(ending)
def prior_key
old_salt = IdentityConfig.store.token_encryption_key_salt_old
old_pepper = IdentityConfig.store.token_encryption_key_pepper_old

if old_salt.present? && old_pepper.present?
truncate_key(ActiveSupport::KeyGenerator.new(old_pepper).generate_key(old_salt))
end
end
Expand All @@ -104,30 +113,5 @@ def prior_keys
def truncate_key(key)
key[0...32]
end

def key_salt_and_pepper(ordinal = nil)
env = Figaro.env
if ordinal
[env.send(:"token_encryption_key_salt_#{ordinal}!"),
env.send(:"token_encryption_key_pepper_#{ordinal}!")]
else
[env.token_encryption_key_salt!,
env.token_encryption_key_pepper!]
end
end

def prior_key_signifiers
salt_endings = gather_env_key_endings('token_encryption_key_salt_')
pepper_endings = gather_env_key_endings('token_encryption_key_pepper_')
(salt_endings & pepper_endings).sort_by(&:to_i)
end

def gather_env_key_endings(prefix)
range = prefix.length..-1
ENV.
keys.
select { |name| name.start_with?(prefix) }.
map { |name| name[range] }
end
end
end
6 changes: 3 additions & 3 deletions bin/activate
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/env ruby

load File.expand_path('../lib/deploy/activate.rb', File.dirname(__FILE__))

Deploy::Activate.new.run
puts '
bin/activate is a noop and can be removed!
'
6 changes: 3 additions & 3 deletions bin/fast_setup
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ chdir APP_ROOT do
|___/ |___/
]

puts "== Copying application.yml =="
run "test -L config/application.yml || cp config/application.yml.example config/application.yml"

puts '== Setting up config overrides =='
default_application_yml = { 'development' => { 'config_key' => nil } }
File.write('config/application.yml', default_application_yml.to_yaml) unless File.exists?('config/application.yml')

puts '== Installing dependencies =='
system! 'gem install bundler --conservative'
Expand Down
7 changes: 4 additions & 3 deletions bin/setup
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/env ruby
require 'pathname'
require 'fileutils'
require 'yaml'
include FileUtils

# path to your application root.
Expand Down Expand Up @@ -29,9 +30,9 @@ chdir APP_ROOT do
|___/ |___/
]

puts "== Copying application.yml =="
run "test -L config/application.yml || cp config/application.yml.example config/application.yml"

puts '== Setting up config overrides =='
default_application_yml = { 'development' => { 'config_key' => nil } }
File.write('config/application.yml', default_application_yml.to_yaml) unless File.exists?('config/application.yml')

puts '== Installing dependencies =='
system! 'gem install bundler --conservative'
Expand Down
6 changes: 6 additions & 0 deletions config/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
require 'action_controller/railtie'
require 'action_view/railtie'
require 'identity/logging/railtie'
require_relative '../lib/identity_config'

# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Expand All @@ -15,6 +16,11 @@ class Application < Rails::Application
# Initialize configuration defaults for originally generated Rails version.
config.load_defaults 5.1

configuration = Identity::Hostdata::ConfigReader.new(app_root: Rails.root).read_configuration(
Rails.env, write_copy_to: Rails.root.join('tmp/application.yml')
)
IdentityConfig.build_store(configuration)

# Settings in config/environments/* take precedence over those specified here.
# Application configuration should go into files in config/initializers
# -- all .rb files in that directory are automatically loaded.
Expand Down
Loading

0 comments on commit b7b3bbe

Please sign in to comment.