kryptos 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in kryptos.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 William Lipa
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,74 @@
1
+ # Kryptos
2
+
3
+ Kryptos provides a way to avoid checking in unencrypted application secrets such as API keys. The secrets will be encrypted using a key stored in the database. The assumption is that if an attacker can get to your database, you're in big trouble anyway. But at least we can avoid giving away our API keys to people with access to the repository. We still have to check in database access configuration, so you should use a firewall or equivalent to protect that.
4
+
5
+ Your typical workflow should be unaffected, as Kryptos handles decryption and encryption automatically. The encrypted file will be version controlled and deployed. There is a one time cost to set up the db secret, but after that, Kryptos should be out of your way.
6
+
7
+ Kryptos depends on Rails and has one gem dependency - the 'gibberish' library, which has no other dependencies. Kryptos itself is less than 100 lines of code and does not do any weird
8
+ monkeypatching. So overhead should be quite light.
9
+
10
+
11
+ ## Installation
12
+
13
+ Add this line to your application's Gemfile:
14
+
15
+ gem 'kryptos'
16
+
17
+ And then execute:
18
+
19
+ $ bundle
20
+
21
+ Or install it yourself as:
22
+
23
+ $ gem install kryptos
24
+
25
+
26
+ Next, add config/kryptos.rb to your .gitignore. That's the main point of all this. The gem checks that this file is ignored, so do that step now before even creating the file itself.
27
+
28
+ Add a migration for the KryptosSecrets table. This table will contain one row with your randomly generated secret. The migration should look like:
29
+
30
+ class AddKryptosSecrets < ActiveRecord::Migration
31
+ def change
32
+ create_table :kryptos_secrets do |t|
33
+ t.string :secret
34
+ end
35
+ end
36
+ end
37
+
38
+ You can use OpenSSL or an equivalent tool to generate a random password.
39
+
40
+ $ openssl rand -base64 32
41
+ RANDOMSECRET
42
+
43
+ Then use the console to add your secret to the database. Do not use 'RANDOMSECRET' literally; I hope that is obvious...
44
+
45
+ $ rails console
46
+ > KryptosSecret.create({ :secret => 'RANDOMSECRET'}, :without_protection => true)
47
+
48
+ Now create a file config/kryptos.rb that will contain the actual secrets. This file can be any ruby code, for example:
49
+
50
+ module AppSecrets
51
+
52
+ AWS = Struct.new(:public_key, :private_key).new.tap do |s|
53
+ s.public_key = "foo"
54
+ s.private_key = "bar"
55
+ end
56
+
57
+ end
58
+
59
+ ## Usage
60
+
61
+ Fire up the console again. You should be able to access the config data:
62
+
63
+ $ rails console
64
+ > AppSecrets::AWS.public_key
65
+ => "foo"
66
+
67
+
68
+ ## Contributing
69
+
70
+ 1. Fork it
71
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
72
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
73
+ 4. Push to the branch (`git push origin my-new-feature`)
74
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/kryptos.gemspec ADDED
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'kryptos/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "kryptos"
8
+ gem.version = Kryptos::VERSION
9
+ gem.authors = ["wlipa"]
10
+ gem.email = ["dojo@masterleep.com"]
11
+ gem.description = %q{Supports keeping your application configuration secrets in source control, but encrypted using a key from the database.}
12
+ gem.summary = %q{Encrypt app secrets in source control using a db based key}
13
+ gem.homepage = ""
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_dependency 'gibberish'
21
+ end
@@ -0,0 +1,49 @@
1
+ class KryptosSecret < ActiveRecord::Base
2
+
3
+ def gitignore_path
4
+ "#{Rails.root}/.gitignore"
5
+ end
6
+
7
+ def cleartext_path
8
+ "#{Rails.root}/config/kryptos.rb"
9
+ end
10
+
11
+ def encrypted_path
12
+ "#{cleartext_path}.enc"
13
+ end
14
+
15
+ def clandestine_operations
16
+ check_gitignore
17
+ if File.exists? cleartext_path
18
+ # If the encrypted version is out of date, regenerate it
19
+ enc_mtime = File.exists?(encrypted_path) && File.mtime(encrypted_path)
20
+ encrypt_secrets if !enc_mtime || enc_mtime < File.mtime(cleartext_path)
21
+ else
22
+ decrypt_secrets
23
+ end
24
+ require cleartext_path
25
+ end
26
+
27
+ def check_gitignore
28
+ return unless Rails.env.development?
29
+ to_ignore = "config/kryptos.rb"
30
+ ignores = IO.read(gitignore_path)
31
+ raise "gitignore must ignore #{to_ignore}" unless ignores =~ /^#{to_ignore}$/
32
+ end
33
+
34
+ def encrypt_secrets
35
+ return unless Rails.env.development?
36
+ Rails.logger.info "kryptos encrypt_secrets"
37
+ cipher = Gibberish::AES.new(secret)
38
+ IO.write(encrypted_path, cipher.encrypt(IO.read(cleartext_path)))
39
+ end
40
+
41
+ def decrypt_secrets
42
+ Rails.logger.info "kryptos decrypt_secrets"
43
+ cipher = Gibberish::AES.new(secret)
44
+ IO.write(cleartext_path, cipher.decrypt(IO.read(encrypted_path)))
45
+ prev_time = File.mtime(encrypted_path)
46
+ File.utime(prev_time, prev_time, cleartext_path) # avoid round-trip
47
+ end
48
+
49
+ end
@@ -0,0 +1,3 @@
1
+ module Kryptos
2
+ VERSION = "1.0.0"
3
+ end
data/lib/kryptos.rb ADDED
@@ -0,0 +1,19 @@
1
+ require 'kryptos/secret'
2
+ require 'kryptos/version'
3
+ require 'gibberish'
4
+
5
+ module Kryptos
6
+
7
+ # Hook Rails init process
8
+ class Railtie < Rails::Railtie
9
+ initializer 'kryptos', :before => 'load_environment_config' do |app|
10
+ ks = KryptosSecret.last rescue nil
11
+ if ks
12
+ ks.clandestine_operations
13
+ else
14
+ Rails.logger.info "no kryptos secret defined -- skipping"
15
+ end
16
+ end
17
+ end
18
+
19
+ end
metadata ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: kryptos
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - wlipa
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-02-15 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: gibberish
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ description: Supports keeping your application configuration secrets in source control,
31
+ but encrypted using a key from the database.
32
+ email:
33
+ - dojo@masterleep.com
34
+ executables: []
35
+ extensions: []
36
+ extra_rdoc_files: []
37
+ files:
38
+ - .gitignore
39
+ - Gemfile
40
+ - LICENSE.txt
41
+ - README.md
42
+ - Rakefile
43
+ - kryptos.gemspec
44
+ - lib/kryptos.rb
45
+ - lib/kryptos/secret.rb
46
+ - lib/kryptos/version.rb
47
+ homepage: ''
48
+ licenses: []
49
+ post_install_message:
50
+ rdoc_options: []
51
+ require_paths:
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ! '>='
57
+ - !ruby/object:Gem::Version
58
+ version: '0'
59
+ required_rubygems_version: !ruby/object:Gem::Requirement
60
+ none: false
61
+ requirements:
62
+ - - ! '>='
63
+ - !ruby/object:Gem::Version
64
+ version: '0'
65
+ requirements: []
66
+ rubyforge_project:
67
+ rubygems_version: 1.8.25
68
+ signing_key:
69
+ specification_version: 3
70
+ summary: Encrypt app secrets in source control using a db based key
71
+ test_files: []