kryptos 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +74 -0
- data/Rakefile +1 -0
- data/kryptos.gemspec +21 -0
- data/lib/kryptos/secret.rb +49 -0
- data/lib/kryptos/version.rb +3 -0
- data/lib/kryptos.rb +19 -0
- metadata +71 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
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
|
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: []
|