heroku-config 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/Gemfile.lock +1 -1
- data/README.md +29 -2
- data/lib/heroku_config/aws_key.rb +19 -5
- data/lib/heroku_config/aws_rotate.rb +9 -2
- data/lib/heroku_config/aws_rotate_all.rb +24 -0
- data/lib/heroku_config/cli.rb +8 -2
- data/lib/heroku_config/config.rb +2 -1
- data/lib/heroku_config/help/aws_rotate.md +3 -1
- data/lib/heroku_config/help/aws_rotate_all.md +27 -0
- data/lib/heroku_config/version.rb +1 -1
- data/spec/fixtures/heroku-apps.txt +2 -0
- data/spec/lib/cli_spec.rb +5 -1
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 52a0676bf09a3f428fafa5a9c04dc2199f8b7c86712c406591ee300c7725a851
|
4
|
+
data.tar.gz: 3b4c9a26b6f26788a07a5cecd85de0c16a317f4b174aed58dfa43b02b2b5796a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5840cceab8d8bb86d4a2bc126f8e1e132cb7e4849e2b7b31a475cf37ed80b9aa25f60e94afc8b7611ec4e2c9517cd48c1a2779e3b4b4b2b0c989c48307781dee
|
7
|
+
data.tar.gz: e07acd595822a3c66c53f3b727180bf87e9d30aae5f9fc26db4374035a6786859736bb58597402349bdfee96c56219688defb6285cf78d0ca71b73c9a7c2dadd
|
data/CHANGELOG.md
CHANGED
@@ -3,6 +3,10 @@
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
4
4
|
This project *tries* to adhere to [Semantic Versioning](http://semver.org/), even before v1.0.
|
5
5
|
|
6
|
+
## [0.3.0]
|
7
|
+
- add aws-rotate-all command
|
8
|
+
- friendly error if access key does not exist on heroku app
|
9
|
+
|
6
10
|
## [0.2.0]
|
7
11
|
- check if new key is useable before completing rotation
|
8
12
|
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -4,12 +4,18 @@
|
|
4
4
|
|
5
5
|
Quickly rotate [AWS credential keys](https://docs.aws.amazon.com/general/latest/gr/aws-security-credentials.html) and [heroku configs](https://devcenter.heroku.com/articles/config-vars).
|
6
6
|
|
7
|
-
Do you have long-term AWS credentials like `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` deployed to your Heroku applications? When was the last time they were rotated?
|
7
|
+
Do you have long-term AWS credentials like `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` deployed to your Heroku applications? When was the last time they were rotated?
|
8
8
|
|
9
9
|
Rotating AWS keys is one of the simplest security measures to take. Usually though, we're too busy with developing features and rotating keys take a back seat. This tool automates the boring and manual process of rotating keys. Run this on your CodeBuild, jenkins server, a lambda function, or just manually when you have to.
|
10
10
|
|
11
11
|
## Usage
|
12
12
|
|
13
|
+
Switch to an AWS_PROFILE with the permissions to create and delete AWS keys, usually an admin.
|
14
|
+
|
15
|
+
export AWS_PROFILE=yourprofile
|
16
|
+
|
17
|
+
Run the `aws-rotate` command.
|
18
|
+
|
13
19
|
heroku-config aws-rotate APP
|
14
20
|
|
15
21
|
## Example with Output
|
@@ -27,9 +33,30 @@ Rotating AWS keys is one of the simplest security measures to take. Usually thou
|
|
27
33
|
Old access key deleted: AKIAXZ6ODJLQSGEXAMPLE
|
28
34
|
$
|
29
35
|
|
36
|
+
## Rotate Multiple Apps
|
37
|
+
|
38
|
+
You can use the `aws-rotate-all` command to rotate a list of heroku apps.
|
39
|
+
|
40
|
+
heroku-config aws-rotate-all FILE
|
41
|
+
|
42
|
+
The FILE should contain a list of apps separated by new lines. Example:
|
43
|
+
|
44
|
+
~/heroku-apps.txt:
|
45
|
+
|
46
|
+
radiant-fortress-40674
|
47
|
+
protected-oasis-24054
|
48
|
+
|
49
|
+
Then the command would be:
|
50
|
+
|
51
|
+
heroku-config aws-rotate-all ~/heroku-apps.txt
|
52
|
+
|
53
|
+
For more help:
|
54
|
+
|
55
|
+
heroku-config aws-rotate-all -h
|
56
|
+
|
30
57
|
## Installation
|
31
58
|
|
32
|
-
|
59
|
+
Install with:
|
33
60
|
|
34
61
|
gem install heroku-config
|
35
62
|
|
@@ -2,6 +2,7 @@ module HerokuConfig
|
|
2
2
|
class AwsKey < Base
|
3
3
|
include AwsServices
|
4
4
|
class MaxKeysError < StandardError; end
|
5
|
+
class AccessKeyNotFound < StandardError; end
|
5
6
|
|
6
7
|
def initialize(options, access_key_id)
|
7
8
|
@options, @access_key_id = options, access_key_id
|
@@ -26,13 +27,25 @@ module HerokuConfig
|
|
26
27
|
true
|
27
28
|
end
|
28
29
|
|
29
|
-
def get_user_name
|
30
|
+
def get_user_name(quiet_error: true)
|
30
31
|
return "fakeuser" if @options[:noop]
|
31
32
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
33
|
+
begin
|
34
|
+
resp = iam.get_access_key_last_used(
|
35
|
+
access_key_id: @access_key_id,
|
36
|
+
)
|
37
|
+
resp.user_name
|
38
|
+
rescue Aws::IAM::Errors::AccessDenied => e # "obscure" error if access key is not found also
|
39
|
+
puts "#{e.class} #{e.message}".color(:red)
|
40
|
+
puts <<~EOL
|
41
|
+
Are you sure the access key exists?
|
42
|
+
You can try running the following with an admin user to see if the key exists:
|
43
|
+
|
44
|
+
aws iam get-access-key-last-used --access-key-id #{@access_key_id}
|
45
|
+
|
46
|
+
EOL
|
47
|
+
@options[:cli] ? exit(1) : raise(AccessKeyNotFound)
|
48
|
+
end
|
36
49
|
end
|
37
50
|
|
38
51
|
def wait_until_usable(key, secret)
|
@@ -44,6 +57,7 @@ module HerokuConfig
|
|
44
57
|
)
|
45
58
|
begin
|
46
59
|
sts.get_caller_identity
|
60
|
+
puts "Confirmed that new AWS key is usable."
|
47
61
|
true
|
48
62
|
rescue Aws::STS::Errors::InvalidClientTokenId => e
|
49
63
|
puts "#{e.class}: #{e.message}"
|
@@ -1,5 +1,7 @@
|
|
1
1
|
module HerokuConfig
|
2
2
|
class AwsRotate < Base
|
3
|
+
class MaxKeysError < StandardError; end
|
4
|
+
|
3
5
|
def initialize(options={})
|
4
6
|
@options = options
|
5
7
|
@app = options[:app]
|
@@ -8,8 +10,13 @@ module HerokuConfig
|
|
8
10
|
def run
|
9
11
|
key_id = config.get("AWS_ACCESS_KEY_ID")
|
10
12
|
unless key_id
|
11
|
-
puts "WARN: No AWS_ACCESS_KEY_ID found for #{@app.color(:green)} app.
|
12
|
-
|
13
|
+
puts "WARN: No AWS_ACCESS_KEY_ID found for #{@app.color(:green)} app."
|
14
|
+
if @options[:cli]
|
15
|
+
puts "Exiting"
|
16
|
+
exit 0
|
17
|
+
else
|
18
|
+
return
|
19
|
+
end
|
13
20
|
end
|
14
21
|
|
15
22
|
aws_key = AwsKey.new(@options, key_id)
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module HerokuConfig
|
2
|
+
class AwsRotateAll < Base
|
3
|
+
def initialize(options={})
|
4
|
+
@options = options
|
5
|
+
@file = options[:file]
|
6
|
+
end
|
7
|
+
|
8
|
+
def run
|
9
|
+
if ENV['HEROKU_CONFIG_TEST']
|
10
|
+
puts "NOOP"
|
11
|
+
return
|
12
|
+
end
|
13
|
+
|
14
|
+
apps.each do |app|
|
15
|
+
AwsRotate.new(@options.merge(app: app)).run
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def apps
|
20
|
+
IO.readlines(@file).map(&:strip).reject(&:empty?)
|
21
|
+
end
|
22
|
+
memoize :apps
|
23
|
+
end
|
24
|
+
end
|
data/lib/heroku_config/cli.rb
CHANGED
@@ -3,10 +3,16 @@ module HerokuConfig
|
|
3
3
|
class_option :verbose, type: :boolean
|
4
4
|
class_option :noop, type: :boolean
|
5
5
|
|
6
|
-
desc "aws-rotate APP", "
|
6
|
+
desc "aws-rotate APP", "Rotates AWS key for app"
|
7
7
|
long_desc Help.text(:aws_rotate)
|
8
8
|
def aws_rotate(app)
|
9
|
-
AwsRotate.new(options.merge(app: app)).run
|
9
|
+
AwsRotate.new(options.merge(app: app, cli: true)).run
|
10
|
+
end
|
11
|
+
|
12
|
+
desc "aws-rotate-all FILE", "Rotates AWS key for list of apps"
|
13
|
+
long_desc Help.text(:aws_rotate_all)
|
14
|
+
def aws_rotate_all(file)
|
15
|
+
AwsRotateAll.new(options.merge(file: file)).run
|
10
16
|
end
|
11
17
|
|
12
18
|
desc "completion *PARAMS", "Prints words for auto-completion."
|
data/lib/heroku_config/config.rb
CHANGED
@@ -8,11 +8,13 @@
|
|
8
8
|
=> heroku config:get AWS_ACCESS_KEY_ID -a protected-oasis-24054
|
9
9
|
Updating access key for user: bob
|
10
10
|
Created new access key: AKIAXZ6ODJLQQEXAMPLE
|
11
|
+
Checking if new AWS key is usable yet.
|
12
|
+
Confirmed that new AWS key is usable.
|
11
13
|
=> heroku config:set AWS_ACCESS_KEY_ID=AKIAXZ6ODJLQQEXAMPLE AWS_SECRET_ACCESS_KEY=sp4gmsuif0XgYG2cPiZbkvl93kTGaeDDhEXAMPLE -a protected-oasis-24054
|
12
14
|
Setting heroku config variables
|
13
15
|
Setting AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and restarting protected-oasis-24054... done, v21
|
14
16
|
|
15
17
|
AWS_ACCESS_KEY_ID: AKIAXZ6ODJLQQEXAMPLE
|
16
18
|
AWS_SECRET_ACCESS_KEY: sp4gmsuif0XgYG2cPiZbkvl93kTGaeDDhEXAMPLE
|
17
|
-
Old access key deleted:
|
19
|
+
Old access key deleted: AKIAXZ6ODJLQSEXAMPLE
|
18
20
|
$
|
@@ -0,0 +1,27 @@
|
|
1
|
+
## Examples
|
2
|
+
|
3
|
+
heroku-config aws-rotate-all
|
4
|
+
|
5
|
+
## Example with Output
|
6
|
+
|
7
|
+
$ cat ~/heroku-apps.txt
|
8
|
+
radiant-fortress-40674
|
9
|
+
protected-oasis-24054
|
10
|
+
$ heroku-config aws-rotate-all ~/heroku-apps.txt
|
11
|
+
=> heroku config:get AWS_ACCESS_KEY_ID -a radiant-fortress-40674
|
12
|
+
WARN: No AWS_ACCESS_KEY_ID found for radiant-fortress-40674 app.
|
13
|
+
=> heroku config:get AWS_ACCESS_KEY_ID -a protected-oasis-24054
|
14
|
+
Updating access key for user: bob
|
15
|
+
Created new access key: AKIAXZ6ODJLQSEXAMPLE
|
16
|
+
Checking if new AWS key is usable yet.
|
17
|
+
Aws::STS::Errors::InvalidClientTokenId: The security token included in the request is invalid.
|
18
|
+
New IAM key not usable yet. Delaying for 5 seconds and retrying...
|
19
|
+
Confirmed that new AWS key is usable.
|
20
|
+
=> heroku config:set AWS_ACCESS_KEY_ID=AKIAXZ6ODJLQSEXAMPLE AWS_SECRET_ACCESS_KEY=SGxokj5/9PYaAtqu3C6UOqPPUi+C0yPT6EXAMPLE -a protected-oasis-24054
|
21
|
+
Setting heroku config variables
|
22
|
+
Setting AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and restarting protected-oasis-24054... done, v27
|
23
|
+
|
24
|
+
AWS_ACCESS_KEY_ID: AKIAXZ6ODJLQSEXAMPLE
|
25
|
+
AWS_SECRET_ACCESS_KEY: SGxokj5/9PYaAtqu3C6UOqPPUi+C0yPT6EXAMPLE
|
26
|
+
Old access key deleted: AKIAXZ6ODJLQZEXAMPLE
|
27
|
+
$
|
data/spec/lib/cli_spec.rb
CHANGED
@@ -6,8 +6,12 @@ describe HerokuConfig::CLI do
|
|
6
6
|
describe "heroku-config" do
|
7
7
|
it "aws-rotate" do
|
8
8
|
out = execute("exe/heroku-config aws-rotate #{@args}")
|
9
|
-
puts out
|
10
9
|
expect(out).to include("NOOP: Updating access key for user: fakeuser")
|
11
10
|
end
|
11
|
+
|
12
|
+
it "aws-rotate-all" do
|
13
|
+
out = execute("exe/heroku-config aws-rotate-all spec/fixtures/heroku-apps.txt")
|
14
|
+
expect(out).to include("NOOP")
|
15
|
+
end
|
12
16
|
end
|
13
17
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: heroku-config
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tung Nguyen
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-11-
|
11
|
+
date: 2019-11-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -202,6 +202,7 @@ files:
|
|
202
202
|
- lib/heroku_config/autoloader.rb
|
203
203
|
- lib/heroku_config/aws_key.rb
|
204
204
|
- lib/heroku_config/aws_rotate.rb
|
205
|
+
- lib/heroku_config/aws_rotate_all.rb
|
205
206
|
- lib/heroku_config/aws_services.rb
|
206
207
|
- lib/heroku_config/base.rb
|
207
208
|
- lib/heroku_config/cli.rb
|
@@ -212,9 +213,11 @@ files:
|
|
212
213
|
- lib/heroku_config/config.rb
|
213
214
|
- lib/heroku_config/help.rb
|
214
215
|
- lib/heroku_config/help/aws_rotate.md
|
216
|
+
- lib/heroku_config/help/aws_rotate_all.md
|
215
217
|
- lib/heroku_config/help/completion.md
|
216
218
|
- lib/heroku_config/help/completion_script.md
|
217
219
|
- lib/heroku_config/version.rb
|
220
|
+
- spec/fixtures/heroku-apps.txt
|
218
221
|
- spec/lib/cli_spec.rb
|
219
222
|
- spec/spec_helper.rb
|
220
223
|
homepage: https://github.com/tongueroo/heroku-config
|
@@ -241,5 +244,6 @@ signing_key:
|
|
241
244
|
specification_version: 4
|
242
245
|
summary: Heroku Config AWS Access Key Rotator
|
243
246
|
test_files:
|
247
|
+
- spec/fixtures/heroku-apps.txt
|
244
248
|
- spec/lib/cli_spec.rb
|
245
249
|
- spec/spec_helper.rb
|