heroku-config 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9f2111e59e572f3463941128576134d04698f17a13fd133c1213a420b8aa59dd
4
- data.tar.gz: 77deca42ebf969b897016d61895c61c9c401a0d1833e5f0a2bbbb2a65a021e51
3
+ metadata.gz: 52a0676bf09a3f428fafa5a9c04dc2199f8b7c86712c406591ee300c7725a851
4
+ data.tar.gz: 3b4c9a26b6f26788a07a5cecd85de0c16a317f4b174aed58dfa43b02b2b5796a
5
5
  SHA512:
6
- metadata.gz: 077a3d0563fb87a77786a1e714a0c1674f6efbcf0deb97df964d02cb32018ceb9d77dcb9b6234a95db9ac2f5e9c8e61f5698e8542ad0746d7025325740e8db71
7
- data.tar.gz: b2f1d704ee3de001475569491e09368c41ba22258d64d15b88e0e1a4ff92f44f8553d1007d6f1b1472e816963837320bf40f3b5e357fb280b3f0568c193f3648
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
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- heroku-config (0.1.0)
4
+ heroku-config (0.2.0)
5
5
  activesupport
6
6
  aws-sdk-core
7
7
  aws-sdk-iam
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
- Or install with RubyGems.
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
- resp = iam.get_access_key_last_used(
33
- access_key_id: @access_key_id,
34
- )
35
- resp.user_name
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. Exiting."
12
- exit 0
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
@@ -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", "Say aws_rotate to 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."
@@ -9,7 +9,8 @@ module HerokuConfig
9
9
 
10
10
  def get(name)
11
11
  return "fakevalue" if ENV['HEROKU_CONFIG_TEST']
12
- sh "heroku config:get #{name} -a #{@app}"
12
+ out = sh "heroku config:get #{name} -a #{@app}"
13
+ return out if !out&.empty?
13
14
  end
14
15
 
15
16
  def set(*params)
@@ -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: AKIAXZ6ODJLQSGGE27KK
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
+ $
@@ -1,3 +1,3 @@
1
1
  module HerokuConfig
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -0,0 +1,2 @@
1
+ radiant-fortress-40674
2
+ protected-oasis-24054
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.2.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-16 00:00:00.000000000 Z
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