awskeyring 1.2.0 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +46 -0
- data/CODE_OF_CONDUCT.md +2 -2
- data/CONTRIBUTING.md +1 -1
- data/Gemfile +1 -1
- data/README.md +23 -8
- data/Rakefile +30 -11
- data/awskeyring.gemspec +10 -2
- data/i18n/en.yml +2 -0
- data/lib/awskeyring.rb +33 -11
- data/lib/awskeyring/awsapi.rb +49 -41
- data/lib/awskeyring/validate.rb +6 -6
- data/lib/awskeyring/version.rb +17 -1
- data/lib/awskeyring_command.rb +57 -13
- data/man/awskeyring.5 +194 -0
- data/man/awskeyring.5.ronn +138 -0
- metadata +11 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ae2606582cb2a9c079bf4ebcb6223570148954cf66fe9938c9b4d969c1312da6
|
4
|
+
data.tar.gz: d6b24f01901e6c3161e1874f9bd9d018f9b62e734d7d73f5ffaed78f0125ecb1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d7704820e908585b67575c319e03493512917a9e5ea5db9620040402c49fbcd6466448e108949bcf32ea2d2f782e2ee8bf7e3e1bdd4e4138cb6d462c2c603635
|
7
|
+
data.tar.gz: 667e7d6d0417cda0a79c1d81680469f1ba2c7a03630bd8e7269e03f137ad669155126a927eb39542b1e9e0b07ee0f408678bb603bc77900cc7db9ff60e702c6b
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,51 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [v1.4.0](https://github.com/servian/awskeyring/tree/v1.4.0) (2020-06-19)
|
4
|
+
|
5
|
+
[Full Changelog](https://github.com/servian/awskeyring/compare/v1.3.3...v1.4.0)
|
6
|
+
|
7
|
+
**Implemented enhancements:**
|
8
|
+
|
9
|
+
- Import Keys and Tokens from shared credentials files. [\#65](https://github.com/servian/awskeyring/pull/65) ([tristanmorgan](https://github.com/tristanmorgan))
|
10
|
+
|
11
|
+
## [v1.3.3](https://github.com/servian/awskeyring/tree/v1.3.3) (2020-06-04)
|
12
|
+
|
13
|
+
[Full Changelog](https://github.com/servian/awskeyring/compare/v1.3.2...v1.3.3)
|
14
|
+
|
15
|
+
**Implemented enhancements:**
|
16
|
+
|
17
|
+
- Change email references from Vibrato to Servian [\#64](https://github.com/servian/awskeyring/pull/64) ([tristanmorgan](https://github.com/tristanmorgan))
|
18
|
+
|
19
|
+
## [v1.3.2](https://github.com/servian/awskeyring/tree/v1.3.2) (2020-04-27)
|
20
|
+
|
21
|
+
[Full Changelog](https://github.com/servian/awskeyring/compare/v1.3.1...v1.3.2)
|
22
|
+
|
23
|
+
**Fixed bugs:**
|
24
|
+
|
25
|
+
- Fix I18n message load when used as a library. [\#63](https://github.com/servian/awskeyring/pull/63) ([tristanmorgan](https://github.com/tristanmorgan))
|
26
|
+
|
27
|
+
## [v1.3.1](https://github.com/servian/awskeyring/tree/v1.3.1) (2020-03-19)
|
28
|
+
|
29
|
+
[Full Changelog](https://github.com/servian/awskeyring/compare/v1.3.0...v1.3.1)
|
30
|
+
|
31
|
+
**Implemented enhancements:**
|
32
|
+
|
33
|
+
- Markdown linting changes and removed Rubocop-MD. [\#61](https://github.com/servian/awskeyring/pull/61) ([tristanmorgan](https://github.com/tristanmorgan))
|
34
|
+
- Removed some redundant code. [\#60](https://github.com/servian/awskeyring/pull/60) ([tristanmorgan](https://github.com/tristanmorgan))
|
35
|
+
|
36
|
+
**Merged pull requests:**
|
37
|
+
|
38
|
+
- Update Ronn code and PR template. [\#59](https://github.com/servian/awskeyring/pull/59) ([tristanmorgan](https://github.com/tristanmorgan))
|
39
|
+
|
40
|
+
## [v1.3.0](https://github.com/servian/awskeyring/tree/v1.3.0) (2020-02-19)
|
41
|
+
|
42
|
+
[Full Changelog](https://github.com/servian/awskeyring/compare/v1.2.0...v1.3.0)
|
43
|
+
|
44
|
+
**Implemented enhancements:**
|
45
|
+
|
46
|
+
- Add a man-page and tweak README. [\#58](https://github.com/servian/awskeyring/pull/58) ([tristanmorgan](https://github.com/tristanmorgan))
|
47
|
+
- Enhanced version [\#57](https://github.com/servian/awskeyring/pull/57) ([AzySir](https://github.com/AzySir))
|
48
|
+
|
3
49
|
## [v1.2.0](https://github.com/servian/awskeyring/tree/v1.2.0) (2020-01-20)
|
4
50
|
|
5
51
|
[Full Changelog](https://github.com/servian/awskeyring/compare/v1.1.2...v1.2.0)
|
data/CODE_OF_CONDUCT.md
CHANGED
@@ -55,7 +55,7 @@ further defined and clarified by project maintainers.
|
|
55
55
|
## Enforcement
|
56
56
|
|
57
57
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
58
|
-
reported by contacting the project team at [tristan@
|
58
|
+
reported by contacting the project team at [tristan.morgan@servian.com](mailto:tristan.morgan@servian.com). All
|
59
59
|
complaints will be reviewed and investigated and will result in a response that
|
60
60
|
is deemed necessary and appropriate to the circumstances. The project team is
|
61
61
|
obligated to maintain confidentiality with regard to the reporter of an incident.
|
@@ -68,6 +68,6 @@ members of the project's leadership.
|
|
68
68
|
## Attribution
|
69
69
|
|
70
70
|
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
71
|
-
available
|
71
|
+
available [here](https://www.contributor-covenant.org/version/1/4/code-of-conduct.html)
|
72
72
|
|
73
73
|
[homepage]: https://www.contributor-covenant.org
|
data/CONTRIBUTING.md
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -9,7 +9,8 @@
|
|
9
9
|
* [![Version Downloads](https://ruby-gem-downloads-badge.herokuapp.com/awskeyring?label=downloads-current-version)](https://rubygems.org/gems/awskeyring)
|
10
10
|
* [![Documentation](https://img.shields.io/badge/yard-docs-brightgreen.svg)](https://www.rubydoc.info/gems/awskeyring)
|
11
11
|
|
12
|
-
Awskeyring is a small tool to manage AWS account keys in the macOS Keychain.
|
12
|
+
Awskeyring is a small tool to manage AWS account keys in the macOS Keychain. It has
|
13
|
+
grown to incorporate a lot of [features](https://github.com/servian/awskeyring/wiki/Awskeyring-features).
|
13
14
|
|
14
15
|
## Motivation
|
15
16
|
|
@@ -34,17 +35,19 @@ Please see the [Wiki](https://github.com/servian/awskeyring/wiki) for full usage
|
|
34
35
|
|
35
36
|
First you need to initialise your keychain to hold your AWS credentials.
|
36
37
|
|
37
|
-
awskeyring initialise
|
38
|
+
$ awskeyring initialise
|
38
39
|
|
39
40
|
Then add your keys to it.
|
40
41
|
|
41
|
-
awskeyring add personal-aws
|
42
|
+
$ awskeyring add personal-aws
|
42
43
|
|
43
44
|
Now your keys are stored safely in the macOS keychain. To print environment variables run...
|
44
45
|
|
45
|
-
awskeyring env personal-aws
|
46
|
+
$ awskeyring env personal-aws
|
46
47
|
|
47
|
-
Alternatively you can create a profile using the credential_process config variable. See the
|
48
|
+
Alternatively you can create a profile using the credential_process config variable. See the
|
49
|
+
[AWS CLI Config docs](https://docs.aws.amazon.com/cli/latest/topic/config-vars.html#cli-aws-help-config-vars) for
|
50
|
+
more details on this config option.
|
48
51
|
|
49
52
|
[profile personal]
|
50
53
|
region = us-west-1
|
@@ -62,6 +65,7 @@ The CLI is using [Thor](http://whatisthor.com) with help provided interactively.
|
|
62
65
|
awskeyring env ACCOUNT # Outputs bourne shell environment exports for an ACCOUNT
|
63
66
|
awskeyring exec ACCOUNT command... # Execute a COMMAND with the environment set for an ACCOUNT
|
64
67
|
awskeyring help [COMMAND] # Describe available commands or one specific command
|
68
|
+
awskeyring import ACCOUNT # Import an ACCOUNT to the keyring from ~/.aws/credentials
|
65
69
|
awskeyring initialise # Initialises a new KEYCHAIN
|
66
70
|
awskeyring json ACCOUNT # Outputs AWS CLI compatible JSON for an ACCOUNT
|
67
71
|
awskeyring list # Prints a list of accounts in the keyring
|
@@ -87,17 +91,28 @@ To set your environment easily the following bash function helps:
|
|
87
91
|
|
88
92
|
## Development
|
89
93
|
|
90
|
-
After checking out the repo, run `bundle update` to install dependencies. Then, run `
|
94
|
+
After checking out the repo, run `bundle update` to install dependencies. Then, run `bundle exec rake` to run the
|
95
|
+
tests. Run `bundle exec awskeyring` to use the gem in this directory, ignoring other installed copies of this gem.
|
96
|
+
Awskeyring is tested against the last two versions of Ruby shipped with macOS.
|
91
97
|
|
92
98
|
To install this gem onto your local machine, run `bundle exec rake install`.
|
93
99
|
|
94
100
|
## Security
|
95
101
|
|
96
|
-
If you believe you have found a security issue in Awskeyring, please responsibly disclose by contacting me at
|
102
|
+
If you believe you have found a security issue in Awskeyring, please responsibly disclose by contacting me at
|
103
|
+
[tristan.morgan@servian.com](mailto:tristan.morgan@servian.com). Awskeyring is a Ruby script and as such Ruby is whitelisted
|
104
|
+
to access your "awskeyring" keychain. Use a strong password and keep the unlock time short.
|
97
105
|
|
98
106
|
## Contributing
|
99
107
|
|
100
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/servian/awskeyring
|
108
|
+
Bug reports and pull requests are welcome on GitHub at [https://github.com/servian/awskeyring](https://github.com/servian/awskeyring).
|
109
|
+
This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to
|
110
|
+
the [Contributor Covenant](https://contributor-covenant.org) code of conduct.
|
111
|
+
|
112
|
+
### Contributors
|
113
|
+
|
114
|
+
* Tristan [tristanmorgan](https://github.com/tristanmorgan)
|
115
|
+
* Adam Sir [AzySir](https://github.com/AzySir)
|
101
116
|
|
102
117
|
## License
|
103
118
|
|
data/Rakefile
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
require 'bundler/gem_tasks'
|
4
4
|
require 'rspec/core/rake_task'
|
5
5
|
require 'rubocop/rake_task'
|
6
|
+
require 'ronn'
|
6
7
|
require 'github_changelog_generator/task'
|
7
8
|
require 'yard'
|
8
9
|
|
@@ -14,30 +15,48 @@ GitHubChangelogGenerator::RakeTask.new :changelog do |config|
|
|
14
15
|
end
|
15
16
|
|
16
17
|
RuboCop::RakeTask.new do |rubocop|
|
17
|
-
rubocop.options = [
|
18
|
+
rubocop.options = %w[-D --enable-pending-cops]
|
19
|
+
rubocop.requires << 'rubocop-performance'
|
20
|
+
rubocop.requires << 'rubocop-rake'
|
21
|
+
rubocop.requires << 'rubocop-rspec'
|
22
|
+
rubocop.requires << 'rubocop-rubycw'
|
18
23
|
end
|
19
24
|
|
20
|
-
RSpec
|
25
|
+
desc 'Run RSpec code examples'
|
26
|
+
task :spec do
|
27
|
+
puts 'Running RSpec...'
|
28
|
+
require 'rspec/core'
|
29
|
+
runner = RSpec::Core::Runner
|
30
|
+
xcode = runner.run(%w[--pattern spec/**{,/*/**}/*_spec.rb --order rand --format documentation --color])
|
31
|
+
abort 'RSpec failed' if xcode.positive?
|
32
|
+
end
|
21
33
|
|
22
34
|
desc 'Check filemode bits'
|
23
35
|
task :filemode do
|
24
|
-
|
25
|
-
|
26
|
-
files.
|
36
|
+
puts 'Running FileMode...'
|
37
|
+
files = Set.new(`git ls-files -z`.split("\x0"))
|
38
|
+
dirs = Set.new(files.map { |file| File.dirname(file) })
|
39
|
+
failure = []
|
40
|
+
files.merge(dirs).each do |file|
|
27
41
|
mode = File.stat(file).mode
|
28
42
|
print '.'
|
29
|
-
if (mode & 0x7) != (mode >> 3 & 0x7)
|
30
|
-
puts file
|
31
|
-
failure = true
|
32
|
-
end
|
43
|
+
failure << file if (mode & 0x7) != (mode >> 3 & 0x7)
|
33
44
|
end
|
34
|
-
abort
|
45
|
+
abort "\nError: Incorrect file mode found\n#{failure.join("\n")}" unless failure.empty?
|
35
46
|
print "\n"
|
36
47
|
end
|
37
48
|
|
49
|
+
desc 'generate manpage'
|
50
|
+
task :ronn do
|
51
|
+
puts 'Running Ronn...'
|
52
|
+
roff_text = Ronn::Document.new('man/awskeyring.5.ronn').to_roff
|
53
|
+
File.write('man/awskeyring.5', roff_text)
|
54
|
+
puts "done\n\n"
|
55
|
+
end
|
56
|
+
|
38
57
|
YARD::Rake::YardocTask.new do |t|
|
39
58
|
t.options = ['--fail-on-warning', '--no-progress']
|
40
59
|
t.stats_options = ['--list-undoc']
|
41
60
|
end
|
42
61
|
|
43
|
-
task default: %i[filemode rubocop spec yard]
|
62
|
+
task default: %i[filemode rubocop spec ronn yard]
|
data/awskeyring.gemspec
CHANGED
@@ -8,18 +8,26 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.name = 'awskeyring'
|
9
9
|
spec.version = Awskeyring::VERSION
|
10
10
|
spec.authors = ['Tristan Morgan']
|
11
|
-
spec.email =
|
11
|
+
spec.email = 'tristan.morgan@servian.com'
|
12
12
|
|
13
13
|
spec.summary = 'Manages AWS credentials in the macOS keychain'
|
14
14
|
spec.description = 'Manages AWS credentials in the macOS keychain'
|
15
15
|
spec.homepage = Awskeyring::HOMEPAGE
|
16
|
-
spec.
|
16
|
+
spec.licenses = ['MIT']
|
17
17
|
|
18
18
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^spec/|^\..*|^.*\.png}) }
|
19
19
|
spec.bindir = 'exe'
|
20
20
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
21
|
spec.require_paths = ['lib']
|
22
22
|
|
23
|
+
spec.metadata = {
|
24
|
+
'bug_tracker_uri' => "#{Awskeyring::HOMEPAGE}/issues",
|
25
|
+
'changelog_uri' => "#{Awskeyring::HOMEPAGE}/blob/master/CHANGELOG.md",
|
26
|
+
'documentation_uri' => "https://rubydoc.info/gems/#{spec.name}/#{Awskeyring::VERSION}",
|
27
|
+
'source_code_uri' => "#{Awskeyring::HOMEPAGE}/tree/v#{Awskeyring::VERSION}",
|
28
|
+
'wiki_uri' => "#{Awskeyring::HOMEPAGE}/wiki"
|
29
|
+
}
|
30
|
+
|
23
31
|
spec.add_dependency('aws-sdk-iam')
|
24
32
|
spec.add_dependency('i18n')
|
25
33
|
spec.add_dependency('ruby-keychain')
|
data/i18n/en.yml
CHANGED
@@ -14,6 +14,8 @@ en:
|
|
14
14
|
desc: Outputs bourne shell environment exports for an ACCOUNT
|
15
15
|
exec:
|
16
16
|
desc: Execute a COMMAND with the environment set for an ACCOUNT
|
17
|
+
import:
|
18
|
+
desc: Import an ACCOUNT to the keyring from ~/.aws/credentials
|
17
19
|
initialise:
|
18
20
|
desc: Initialises a new KEYCHAIN
|
19
21
|
json:
|
data/lib/awskeyring.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'i18n'
|
3
4
|
require 'json'
|
4
5
|
require 'keychain'
|
5
6
|
require 'awskeyring/validate'
|
@@ -7,6 +8,9 @@ require 'awskeyring/validate'
|
|
7
8
|
# Awskeyring Module,
|
8
9
|
# gives you an interface to access keychains and items.
|
9
10
|
module Awskeyring # rubocop:disable Metrics/ModuleLength
|
11
|
+
I18n.load_path = Dir.glob(File.join(File.realpath(__dir__), '..', 'i18n', '*.{yml,yaml}'))
|
12
|
+
I18n.backend.load_translations
|
13
|
+
|
10
14
|
# Default rpeferences fole path
|
11
15
|
PREFS_FILE = (File.expand_path '~/.awskeyring').freeze
|
12
16
|
# Prefix for Roles
|
@@ -68,18 +72,17 @@ module Awskeyring # rubocop:disable Metrics/ModuleLength
|
|
68
72
|
|
69
73
|
# Return a list of all acount items
|
70
74
|
private_class_method def self.list_items
|
71
|
-
|
72
|
-
elem_a.attributes[:label] <=> elem_b.attributes[:label]
|
73
|
-
end
|
74
|
-
items.select { |elem| elem.attributes[:label].start_with?(ACCOUNT_PREFIX) }
|
75
|
+
all_items.all.select { |elem| elem.attributes[:label].start_with?(ACCOUNT_PREFIX) }
|
75
76
|
end
|
76
77
|
|
77
78
|
# Return a list of all role items
|
78
79
|
private_class_method def self.list_roles
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
80
|
+
all_items.all.select { |elem| elem.attributes[:label].start_with?(ROLE_PREFIX) }
|
81
|
+
end
|
82
|
+
|
83
|
+
# Return a list of all acount items
|
84
|
+
private_class_method def self.list_tokens
|
85
|
+
all_items.all.select { |elem| elem.attributes[:label].start_with?(SESSION_KEY_PREFIX) }
|
83
86
|
end
|
84
87
|
|
85
88
|
# Return all keychain items
|
@@ -171,12 +174,21 @@ module Awskeyring # rubocop:disable Metrics/ModuleLength
|
|
171
174
|
|
172
175
|
# Return a list account item names
|
173
176
|
def self.list_account_names
|
174
|
-
list_items.map { |elem| elem.attributes[:label][(ACCOUNT_PREFIX.length)..-1] }
|
177
|
+
items = list_items.map { |elem| elem.attributes[:label][(ACCOUNT_PREFIX.length)..-1] }
|
178
|
+
|
179
|
+
tokens = list_tokens.map { |elem| elem.attributes[:label][(SESSION_KEY_PREFIX.length)..-1] }
|
180
|
+
|
181
|
+
(items + tokens).uniq.sort
|
175
182
|
end
|
176
183
|
|
177
184
|
# Return a list role item names
|
178
185
|
def self.list_role_names
|
179
|
-
list_roles.map { |elem| elem.attributes[:label][(ROLE_PREFIX.length)..-1] }
|
186
|
+
list_roles.map { |elem| elem.attributes[:label][(ROLE_PREFIX.length)..-1] }.sort
|
187
|
+
end
|
188
|
+
|
189
|
+
# Return a list token item names
|
190
|
+
def self.list_token_names
|
191
|
+
list_tokens.map { |elem| elem.attributes[:label][(SESSION_KEY_PREFIX.length)..-1] }.sort
|
180
192
|
end
|
181
193
|
|
182
194
|
# Return a list role item names and arns
|
@@ -242,7 +254,7 @@ module Awskeyring # rubocop:disable Metrics/ModuleLength
|
|
242
254
|
# Delete session token items if expired
|
243
255
|
private_class_method def self.delete_expired(key:, token:)
|
244
256
|
expires_at = Time.at(token.attributes[:account].to_i)
|
245
|
-
if expires_at < Time.
|
257
|
+
if expires_at < Time.new
|
246
258
|
delete_pair(key: key, token: token, message: I18n.t('message.delexpired'))
|
247
259
|
key = nil
|
248
260
|
token = nil
|
@@ -343,6 +355,16 @@ module Awskeyring # rubocop:disable Metrics/ModuleLength
|
|
343
355
|
role_name
|
344
356
|
end
|
345
357
|
|
358
|
+
# Validate token exists
|
359
|
+
#
|
360
|
+
# @param [String] token_name the associated account name.
|
361
|
+
def self.token_exists(token_name)
|
362
|
+
Awskeyring::Validate.account_name(token_name)
|
363
|
+
raise 'Token does not exist' unless list_token_names.include?(token_name)
|
364
|
+
|
365
|
+
token_name
|
366
|
+
end
|
367
|
+
|
346
368
|
# Validate role arn not exists
|
347
369
|
#
|
348
370
|
# @param [String] role_arn the associated role arn.
|
data/lib/awskeyring/awsapi.rb
CHANGED
@@ -24,6 +24,7 @@ module Awskeyring
|
|
24
24
|
|
25
25
|
# AWS Env vars
|
26
26
|
AWS_ENV_VARS = %w[
|
27
|
+
AWS_ACCOUNT_NAME
|
27
28
|
AWS_ACCESS_KEY_ID
|
28
29
|
AWS_ACCESS_KEY
|
29
30
|
AWS_SECRET_ACCESS_KEY
|
@@ -116,29 +117,23 @@ module Awskeyring
|
|
116
117
|
# Generates Environment Variables for the AWS CLI
|
117
118
|
#
|
118
119
|
# @param [Hash] params including
|
119
|
-
# [String] account The
|
120
|
+
# [String] account The aws account name
|
121
|
+
# [String] key The aws_access_key_id
|
120
122
|
# [String] secret The aws_secret_access_key
|
121
123
|
# [String] token The aws_session_token
|
122
124
|
# @return [Hash] env_var hash
|
123
125
|
def self.get_env_array(params = {})
|
124
126
|
env_var = {}
|
125
127
|
env_var['AWS_DEFAULT_REGION'] = 'us-east-1' unless region
|
126
|
-
env_var['AWS_ACCOUNT_NAME'] = params[:account] if params[:account]
|
127
128
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
env_var['AWS_SECRET_ACCESS_KEY'] = params[:secret]
|
135
|
-
env_var['AWS_SECRET_KEY'] = params[:secret]
|
129
|
+
params.each_key do |param_name|
|
130
|
+
AWS_ENV_VARS.each do |var_name|
|
131
|
+
if var_name.include?(param_name.to_s.upcase) && !params[param_name].nil?
|
132
|
+
env_var[var_name] = params[param_name]
|
133
|
+
end
|
134
|
+
end
|
136
135
|
end
|
137
136
|
|
138
|
-
if params[:token]
|
139
|
-
env_var['AWS_SECURITY_TOKEN'] = params[:token]
|
140
|
-
env_var['AWS_SESSION_TOKEN'] = params[:token]
|
141
|
-
end
|
142
137
|
env_var
|
143
138
|
end
|
144
139
|
|
@@ -146,10 +141,11 @@ module Awskeyring
|
|
146
141
|
#
|
147
142
|
# @param [String] key The aws_access_key_id
|
148
143
|
# @param [String] secret The aws_secret_access_key
|
149
|
-
|
144
|
+
# @param [String] token The aws_session_token
|
145
|
+
def self.verify_cred(key:, secret:, token:)
|
150
146
|
begin
|
151
147
|
ENV['AWS_DEFAULT_REGION'] = 'us-east-1' unless region
|
152
|
-
sts = Aws::STS::Client.new(access_key_id: key, secret_access_key: secret)
|
148
|
+
sts = Aws::STS::Client.new(access_key_id: key, secret_access_key: secret, session_token: token)
|
153
149
|
sts.get_caller_identity
|
154
150
|
rescue Aws::Errors::ServiceError => e
|
155
151
|
warn e.to_s
|
@@ -158,6 +154,26 @@ module Awskeyring
|
|
158
154
|
true
|
159
155
|
end
|
160
156
|
|
157
|
+
# Retrieve credentials from the AWS Credentials file
|
158
|
+
#
|
159
|
+
# @param [String] account the profile name wanted
|
160
|
+
# @return [Hash] with the new credentials
|
161
|
+
# key The aws_access_key_id
|
162
|
+
# secret The aws_secret_access_key
|
163
|
+
# token The aws_session_token
|
164
|
+
# expiry expiry time
|
165
|
+
def self.get_credentials_from_file(account:)
|
166
|
+
creds = Aws::SharedCredentials.new(profile_name: account)
|
167
|
+
{
|
168
|
+
account: account,
|
169
|
+
key: creds.credentials.access_key_id,
|
170
|
+
secret: creds.credentials.secret_access_key,
|
171
|
+
token: creds.credentials.session_token,
|
172
|
+
expiry: Time.new + TWELVE_HOUR,
|
173
|
+
role: nil
|
174
|
+
}
|
175
|
+
end
|
176
|
+
|
161
177
|
# Retrieves an AWS Console login url
|
162
178
|
#
|
163
179
|
# @param [String] key The aws_access_key_id
|
@@ -166,30 +182,22 @@ module Awskeyring
|
|
166
182
|
# @param [String] user The local username
|
167
183
|
# @param [String] path within the Console to access
|
168
184
|
# @return [String] login_url to access
|
169
|
-
def self.get_login_url(key:, secret:, token:, path:, user:)
|
185
|
+
def self.get_login_url(key:, secret:, token:, path:, user:)
|
170
186
|
console_url = "https://console.aws.amazon.com/#{path}/home"
|
171
187
|
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
}.to_json
|
178
|
-
else
|
179
|
-
ENV['AWS_DEFAULT_REGION'] = 'us-east-1' unless region
|
180
|
-
sts = Aws::STS::Client.new(access_key_id: key,
|
181
|
-
secret_access_key: secret)
|
182
|
-
|
183
|
-
session = sts.get_federation_token(name: user,
|
184
|
-
policy: ADMIN_POLICY,
|
185
|
-
duration_seconds: TWELVE_HOUR)
|
186
|
-
session_json = {
|
187
|
-
sessionId: session.credentials[:access_key_id],
|
188
|
-
sessionKey: session.credentials[:secret_access_key],
|
189
|
-
sessionToken: session.credentials[:session_token]
|
190
|
-
}.to_json
|
188
|
+
unless token
|
189
|
+
cred = get_token({ key: key, secret: secret, user: user, duration: TWELVE_HOUR })
|
190
|
+
key = cred[:key]
|
191
|
+
secret = cred[:secret]
|
192
|
+
token = cred[:token]
|
191
193
|
end
|
192
194
|
|
195
|
+
session_json = {
|
196
|
+
sessionId: key,
|
197
|
+
sessionKey: secret,
|
198
|
+
sessionToken: token
|
199
|
+
}.to_json
|
200
|
+
|
193
201
|
destination_param = '&Destination=' + CGI.escape(console_url)
|
194
202
|
|
195
203
|
AWS_SIGNIN_URL + '?Action=login' + token_param(session_json: session_json) + destination_param
|
@@ -235,10 +243,10 @@ module Awskeyring
|
|
235
243
|
exit 1
|
236
244
|
end
|
237
245
|
|
238
|
-
new_key = iam.create_access_key
|
246
|
+
new_key = iam.create_access_key[:access_key]
|
239
247
|
iam = Aws::IAM::Client.new(
|
240
|
-
access_key_id: new_key[:
|
241
|
-
secret_access_key: new_key[:
|
248
|
+
access_key_id: new_key[:access_key_id],
|
249
|
+
secret_access_key: new_key[:secret_access_key]
|
242
250
|
)
|
243
251
|
retry_backoff do
|
244
252
|
iam.delete_access_key(
|
@@ -247,8 +255,8 @@ module Awskeyring
|
|
247
255
|
end
|
248
256
|
{
|
249
257
|
account: account,
|
250
|
-
key: new_key[:
|
251
|
-
secret: new_key[:
|
258
|
+
key: new_key[:access_key_id],
|
259
|
+
secret: new_key[:secret_access_key]
|
252
260
|
}
|
253
261
|
end
|
254
262
|
|
data/lib/awskeyring/validate.rb
CHANGED
@@ -9,7 +9,7 @@ module Awskeyring
|
|
9
9
|
#
|
10
10
|
# @param [String] account_name the associated account name.
|
11
11
|
def self.account_name(account_name)
|
12
|
-
raise 'Invalid Account Name' unless
|
12
|
+
raise 'Invalid Account Name' unless /\S+/.match?(account_name)
|
13
13
|
|
14
14
|
account_name
|
15
15
|
end
|
@@ -18,7 +18,7 @@ module Awskeyring
|
|
18
18
|
#
|
19
19
|
# @param [String] aws_access_key The aws_access_key_id
|
20
20
|
def self.access_key(aws_access_key)
|
21
|
-
raise 'Invalid Access Key' unless
|
21
|
+
raise 'Invalid Access Key' unless /\AAKIA[A-Z0-9]{12,16}\z/.match?(aws_access_key)
|
22
22
|
|
23
23
|
aws_access_key
|
24
24
|
end
|
@@ -36,7 +36,7 @@ module Awskeyring
|
|
36
36
|
#
|
37
37
|
# @param [String] mfa_arn The users MFA arn
|
38
38
|
def self.mfa_arn(mfa_arn)
|
39
|
-
raise 'Invalid MFA ARN' unless
|
39
|
+
raise 'Invalid MFA ARN' unless %r(\Aarn:aws:iam::[0-9]{12}:mfa/\S*\z).match?(mfa_arn)
|
40
40
|
|
41
41
|
mfa_arn
|
42
42
|
end
|
@@ -45,7 +45,7 @@ module Awskeyring
|
|
45
45
|
#
|
46
46
|
# @param [String] role_name
|
47
47
|
def self.role_name(role_name)
|
48
|
-
raise 'Invalid Role Name' unless
|
48
|
+
raise 'Invalid Role Name' unless /\S+/.match?(role_name)
|
49
49
|
|
50
50
|
role_name
|
51
51
|
end
|
@@ -54,7 +54,7 @@ module Awskeyring
|
|
54
54
|
#
|
55
55
|
# @param [String] role_arn The role arn
|
56
56
|
def self.role_arn(role_arn)
|
57
|
-
raise 'Invalid Role ARN' unless
|
57
|
+
raise 'Invalid Role ARN' unless %r(\Aarn:aws:iam::[0-9]{12}:role/\S*\z).match?(role_arn)
|
58
58
|
|
59
59
|
role_arn
|
60
60
|
end
|
@@ -63,7 +63,7 @@ module Awskeyring
|
|
63
63
|
#
|
64
64
|
# @param [String] mfa_code The mfa code
|
65
65
|
def self.mfa_code(mfa_code)
|
66
|
-
raise 'Invalid MFA CODE' unless
|
66
|
+
raise 'Invalid MFA CODE' unless /\A\d{6}\z/.match?(mfa_code)
|
67
67
|
|
68
68
|
mfa_code
|
69
69
|
end
|
data/lib/awskeyring/version.rb
CHANGED
@@ -1,8 +1,24 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
# Awskeyring Module,
|
6
|
+
# Version const and query of latest.
|
3
7
|
module Awskeyring
|
4
8
|
# The Gem's version number
|
5
|
-
VERSION = '1.
|
9
|
+
VERSION = '1.4.0'
|
6
10
|
# The Gem's homepage
|
7
11
|
HOMEPAGE = 'https://github.com/servian/awskeyring'
|
12
|
+
|
13
|
+
# RubyGems Version url
|
14
|
+
GEM_VERSION_URL = 'https://rubygems.org/api/v1/versions/awskeyring/latest.json'
|
15
|
+
|
16
|
+
# Retrieve the latest version from RubyGems
|
17
|
+
#
|
18
|
+
def self.latest_version
|
19
|
+
uri = URI(GEM_VERSION_URL)
|
20
|
+
request = Net::HTTP.new(uri.host, uri.port)
|
21
|
+
request.use_ssl = true
|
22
|
+
JSON.parse(request.get(uri).body)['version']
|
23
|
+
end
|
8
24
|
end
|
data/lib/awskeyring_command.rb
CHANGED
@@ -34,9 +34,13 @@ class AwskeyringCommand < Thor # rubocop:disable Metrics/ClassLength
|
|
34
34
|
end
|
35
35
|
|
36
36
|
desc '--version, -v', I18n.t('__version.desc')
|
37
|
+
method_option 'no-remote', type: :boolean, aliases: '-r', desc: I18n.t('method_option.noremote'), default: false
|
37
38
|
# print the version number
|
38
39
|
def __version
|
39
40
|
puts "Awskeyring v#{Awskeyring::VERSION}"
|
41
|
+
if !options['no-remote'] && Awskeyring::VERSION != Awskeyring.latest_version
|
42
|
+
puts "the latest version v#{Awskeyring.latest_version}"
|
43
|
+
end
|
40
44
|
puts "Homepage #{Awskeyring::HOMEPAGE}"
|
41
45
|
end
|
42
46
|
|
@@ -118,6 +122,42 @@ class AwskeyringCommand < Thor # rubocop:disable Metrics/ClassLength
|
|
118
122
|
)
|
119
123
|
end
|
120
124
|
|
125
|
+
desc 'import ACCOUNT', I18n.t('import.desc')
|
126
|
+
method_option 'no-remote', type: :boolean, aliases: '-r', desc: I18n.t('method_option.noremote'), default: false
|
127
|
+
# Import an Account
|
128
|
+
def import(account = nil) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
129
|
+
account = ask_check(
|
130
|
+
existing: account, message: I18n.t('message.account'), validator: Awskeyring.method(:account_not_exists)
|
131
|
+
)
|
132
|
+
new_creds = Awskeyring::Awsapi.get_credentials_from_file(account: account)
|
133
|
+
unless options['no-remote']
|
134
|
+
Awskeyring::Awsapi.verify_cred(
|
135
|
+
key: new_creds[:key],
|
136
|
+
secret: new_creds[:secret],
|
137
|
+
token: new_creds[:token]
|
138
|
+
)
|
139
|
+
end
|
140
|
+
if new_creds[:token].nil?
|
141
|
+
Awskeyring.add_account(
|
142
|
+
account: new_creds[:account],
|
143
|
+
key: new_creds[:key],
|
144
|
+
secret: new_creds[:secret],
|
145
|
+
mfa: ''
|
146
|
+
)
|
147
|
+
puts I18n.t('message.addaccount', account: account)
|
148
|
+
else
|
149
|
+
Awskeyring.add_token(
|
150
|
+
account: new_creds[:account],
|
151
|
+
key: new_creds[:key],
|
152
|
+
secret: new_creds[:secret],
|
153
|
+
token: new_creds[:token],
|
154
|
+
expiry: new_creds[:expiry].to_i.to_s,
|
155
|
+
role: nil
|
156
|
+
)
|
157
|
+
puts I18n.t('message.addtoken', account: account, time: Time.at(new_creds[:expiry].to_i))
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
121
161
|
desc 'exec ACCOUNT command...', I18n.t('exec.desc')
|
122
162
|
method_option 'no-token', type: :boolean, aliases: '-n', desc: I18n.t('method_option.notoken'), default: false
|
123
163
|
# execute an external command with env set
|
@@ -159,7 +199,7 @@ class AwskeyringCommand < Thor # rubocop:disable Metrics/ClassLength
|
|
159
199
|
existing: options[:mfa], message: I18n.t('message.mfa'),
|
160
200
|
flags: 'optional', validator: Awskeyring::Validate.method(:mfa_arn)
|
161
201
|
)
|
162
|
-
Awskeyring::Awsapi.verify_cred(key: key, secret: secret) unless options['no-remote']
|
202
|
+
Awskeyring::Awsapi.verify_cred(key: key, secret: secret, token: nil) unless options['no-remote']
|
163
203
|
Awskeyring.add_account(
|
164
204
|
account: account,
|
165
205
|
key: key,
|
@@ -231,8 +271,8 @@ class AwskeyringCommand < Thor # rubocop:disable Metrics/ClassLength
|
|
231
271
|
# remove a session token
|
232
272
|
def remove_token(account = nil)
|
233
273
|
account = ask_check(
|
234
|
-
existing: account, message: I18n.t('message.account'), validator: Awskeyring.method(:
|
235
|
-
limited_to: Awskeyring.
|
274
|
+
existing: account, message: I18n.t('message.account'), validator: Awskeyring.method(:token_exists),
|
275
|
+
limited_to: Awskeyring.list_token_names
|
236
276
|
)
|
237
277
|
Awskeyring.delete_token(account: account, message: I18n.t('message.deltoken', account: account))
|
238
278
|
end
|
@@ -285,7 +325,7 @@ class AwskeyringCommand < Thor # rubocop:disable Metrics/ClassLength
|
|
285
325
|
method_option :code, type: :string, aliases: '-c', desc: I18n.t('method_option.code')
|
286
326
|
method_option :duration, type: :string, aliases: '-d', desc: I18n.t('method_option.duration')
|
287
327
|
# generate a sessiopn token
|
288
|
-
def token(account = nil, role = nil, code = nil) # rubocop:disable
|
328
|
+
def token(account = nil, role = nil, code = nil) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
289
329
|
account = ask_check(
|
290
330
|
existing: account,
|
291
331
|
message: I18n.t('message.account'),
|
@@ -305,19 +345,13 @@ class AwskeyringCommand < Thor # rubocop:disable Metrics/ClassLength
|
|
305
345
|
existing: code, message: I18n.t('message.code'), validator: Awskeyring::Validate.method(:mfa_code)
|
306
346
|
)
|
307
347
|
end
|
308
|
-
duration = options[:duration]
|
309
|
-
duration ||= Awskeyring::Awsapi::ONE_HOUR.to_s if role
|
310
|
-
duration ||= Awskeyring::Awsapi::TWELVE_HOUR.to_s if code
|
311
|
-
duration ||= Awskeyring::Awsapi::ONE_HOUR.to_s
|
312
|
-
|
313
348
|
item_hash = age_check_and_get(account: account, no_token: true)
|
314
|
-
role_arn = Awskeyring.get_role_arn(role_name: role) if role
|
315
349
|
|
316
350
|
begin
|
317
351
|
new_creds = Awskeyring::Awsapi.get_token(
|
318
352
|
code: code,
|
319
|
-
role_arn:
|
320
|
-
duration: duration,
|
353
|
+
role_arn: (Awskeyring.get_role_arn(role_name: role) if role),
|
354
|
+
duration: default_duration(options[:duration], role, code),
|
321
355
|
mfa: item_hash[:mfa],
|
322
356
|
key: item_hash[:key],
|
323
357
|
secret: item_hash[:secret],
|
@@ -417,6 +451,8 @@ class AwskeyringCommand < Thor # rubocop:disable Metrics/ClassLength
|
|
417
451
|
comp_len = 2
|
418
452
|
when '--path', '-p'
|
419
453
|
comp_len = 4
|
454
|
+
when 'remove-token', 'rmt'
|
455
|
+
comp_len = 5
|
420
456
|
end
|
421
457
|
|
422
458
|
[curr, comp_len, sub_cmd]
|
@@ -432,7 +468,7 @@ class AwskeyringCommand < Thor # rubocop:disable Metrics/ClassLength
|
|
432
468
|
self.class.map[sub_cmd].to_s
|
433
469
|
end
|
434
470
|
|
435
|
-
def print_auto_resp(curr, len, sub_cmd)
|
471
|
+
def print_auto_resp(curr, len, sub_cmd) # rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity
|
436
472
|
list = []
|
437
473
|
case len
|
438
474
|
when 0
|
@@ -445,6 +481,8 @@ class AwskeyringCommand < Thor # rubocop:disable Metrics/ClassLength
|
|
445
481
|
list = list_arguments(command: sub_cmd)
|
446
482
|
when 4
|
447
483
|
list = Awskeyring.list_console_path
|
484
|
+
when 5
|
485
|
+
list = Awskeyring.list_token_names
|
448
486
|
else
|
449
487
|
exit 1
|
450
488
|
end
|
@@ -467,6 +505,12 @@ class AwskeyringCommand < Thor # rubocop:disable Metrics/ClassLength
|
|
467
505
|
Awskeyring::Awsapi::AWS_ENV_VARS.each { |key| puts "unset #{key}" unless env_var.key?(key) }
|
468
506
|
end
|
469
507
|
|
508
|
+
def default_duration(duration, role, code)
|
509
|
+
duration ||= Awskeyring::Awsapi::ONE_HOUR.to_s if role
|
510
|
+
duration ||= Awskeyring::Awsapi::TWELVE_HOUR.to_s if code
|
511
|
+
duration || Awskeyring::Awsapi::ONE_HOUR.to_s
|
512
|
+
end
|
513
|
+
|
470
514
|
def ask_check(existing:, message:, flags: nil, validator: nil, limited_to: nil) # rubocop:disable Metrics/MethodLength
|
471
515
|
retries ||= 3
|
472
516
|
begin
|
data/man/awskeyring.5
ADDED
@@ -0,0 +1,194 @@
|
|
1
|
+
.\" generated with Ronn/v0.7.3
|
2
|
+
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
3
|
+
.
|
4
|
+
.TH "AWSKEYRING" "5" "June 2020" "" ""
|
5
|
+
.
|
6
|
+
.SH "NAME"
|
7
|
+
\fBAwskeyring\fR \- is a small tool to manage AWS account keys in the macOS Keychain
|
8
|
+
.
|
9
|
+
.SH "SYNOPSIS"
|
10
|
+
awskeyring COMMAND [ACCOUNT|ROLE] [OPTIONS]
|
11
|
+
.
|
12
|
+
.P
|
13
|
+
awskeyring help COMMAND
|
14
|
+
.
|
15
|
+
.SH "DESCRIPTION"
|
16
|
+
The Awskeyring utility stores and manages AWS access keys and provides the facility to generate access tokens with combinations of assumed roles and multi\-factor\-authentication codes\. It includes autocompletion features and multiple validation checks for input parsing\. It also includes the ability for the AWS CLI to call it directly to provide authentication\.
|
17
|
+
.
|
18
|
+
.P
|
19
|
+
The commands are as follows:
|
20
|
+
.
|
21
|
+
.TP
|
22
|
+
\-\-version, \-v:
|
23
|
+
.
|
24
|
+
.IP
|
25
|
+
Prints the version
|
26
|
+
.
|
27
|
+
.TP
|
28
|
+
add ACCOUNT:
|
29
|
+
.
|
30
|
+
.IP
|
31
|
+
Adds an ACCOUNT to the keyring
|
32
|
+
.
|
33
|
+
.TP
|
34
|
+
add\-role ROLE:
|
35
|
+
.
|
36
|
+
.IP
|
37
|
+
Adds a ROLE to the keyring
|
38
|
+
.
|
39
|
+
.TP
|
40
|
+
console ACCOUNT:
|
41
|
+
.
|
42
|
+
.IP
|
43
|
+
Open the AWS Console for the ACCOUNT
|
44
|
+
.
|
45
|
+
.TP
|
46
|
+
env ACCOUNT:
|
47
|
+
.
|
48
|
+
.IP
|
49
|
+
Outputs bourne shell environment exports for an ACCOUNT
|
50
|
+
.
|
51
|
+
.TP
|
52
|
+
exec ACCOUNT command\.\.\.:
|
53
|
+
.
|
54
|
+
.IP
|
55
|
+
Execute a COMMAND with the environment set for an ACCOUNT
|
56
|
+
.
|
57
|
+
.TP
|
58
|
+
help [COMMAND]:
|
59
|
+
.
|
60
|
+
.IP
|
61
|
+
Describe available commands or one specific command
|
62
|
+
.
|
63
|
+
.TP
|
64
|
+
import:
|
65
|
+
.
|
66
|
+
.IP
|
67
|
+
Import an ACCOUNT to the keyring from ~/\.aws/credentials
|
68
|
+
.
|
69
|
+
.TP
|
70
|
+
initialise:
|
71
|
+
.
|
72
|
+
.IP
|
73
|
+
Initialises a new KEYCHAIN
|
74
|
+
.
|
75
|
+
.TP
|
76
|
+
json ACCOUNT:
|
77
|
+
.
|
78
|
+
.IP
|
79
|
+
Outputs AWS CLI compatible JSON for an ACCOUNT
|
80
|
+
.
|
81
|
+
.TP
|
82
|
+
list:
|
83
|
+
.
|
84
|
+
.IP
|
85
|
+
Prints a list of accounts in the keyring
|
86
|
+
.
|
87
|
+
.TP
|
88
|
+
list\-role:
|
89
|
+
.
|
90
|
+
.IP
|
91
|
+
Prints a list of roles in the keyring
|
92
|
+
.
|
93
|
+
.TP
|
94
|
+
remove ACCOUNT:
|
95
|
+
.
|
96
|
+
.IP
|
97
|
+
Removes an ACCOUNT from the keyring
|
98
|
+
.
|
99
|
+
.TP
|
100
|
+
remove\-role ROLE:
|
101
|
+
.
|
102
|
+
.IP
|
103
|
+
Removes a ROLE from the keyring
|
104
|
+
.
|
105
|
+
.TP
|
106
|
+
remove\-token ACCOUNT:
|
107
|
+
.
|
108
|
+
.IP
|
109
|
+
Removes a token for ACCOUNT from the keyring
|
110
|
+
.
|
111
|
+
.TP
|
112
|
+
rotate ACCOUNT:
|
113
|
+
.
|
114
|
+
.IP
|
115
|
+
Rotate access keys for an ACCOUNT
|
116
|
+
.
|
117
|
+
.TP
|
118
|
+
token ACCOUNT [ROLE] [MFA]:
|
119
|
+
.
|
120
|
+
.IP
|
121
|
+
Create an STS Token from a ROLE or an MFA code
|
122
|
+
.
|
123
|
+
.TP
|
124
|
+
update ACCOUNT:
|
125
|
+
.
|
126
|
+
.IP
|
127
|
+
Updates an ACCOUNT in the keyring
|
128
|
+
.
|
129
|
+
.SH "ENVIRONMENT"
|
130
|
+
The AWS_DEFAULT_REGION environment variable will be used for AWS API calls where specified or fall back to us\-east\-1 when not\.
|
131
|
+
.
|
132
|
+
.SH "EXIT STATUS"
|
133
|
+
The Awskeyring utility exits 0 on success, and >0 if an error occurs\.
|
134
|
+
.
|
135
|
+
.SH "EXAMPLES"
|
136
|
+
First you need to initialise your keychain to hold your AWS credentials\.
|
137
|
+
.
|
138
|
+
.IP "" 4
|
139
|
+
.
|
140
|
+
.nf
|
141
|
+
|
142
|
+
awskeyring initialise
|
143
|
+
.
|
144
|
+
.fi
|
145
|
+
.
|
146
|
+
.IP "" 0
|
147
|
+
.
|
148
|
+
.P
|
149
|
+
Then add your keys to it\.
|
150
|
+
.
|
151
|
+
.IP "" 4
|
152
|
+
.
|
153
|
+
.nf
|
154
|
+
|
155
|
+
awskeyring add personal\-aws
|
156
|
+
.
|
157
|
+
.fi
|
158
|
+
.
|
159
|
+
.IP "" 0
|
160
|
+
.
|
161
|
+
.P
|
162
|
+
Now your keys are stored safely in the macOS keychain\. To print environment variables run\.\.\.
|
163
|
+
.
|
164
|
+
.IP "" 4
|
165
|
+
.
|
166
|
+
.nf
|
167
|
+
|
168
|
+
awskeyring env personal\-aws
|
169
|
+
.
|
170
|
+
.fi
|
171
|
+
.
|
172
|
+
.IP "" 0
|
173
|
+
.
|
174
|
+
.SH "HISTORY"
|
175
|
+
The motivation of this application is to provide a local secure store of AWS credentials using specifically in the macOS Keychain, to have them easily accessed from the Terminal, and to provide useful functions like assuming roles and opening the AWS Console from the cli\. For Enterprise environments there are better suited tools to use like HashiCorp Vault \fIhttps://vaultproject\.io/\fR\.
|
176
|
+
.
|
177
|
+
.SH "SECURITY"
|
178
|
+
If you believe you have found a security issue in Awskeyring, please responsibly disclose by contacting me at \fItristan\.morgan@servian\.com\fR\. Awskeyring is a Ruby script and as such Ruby is whitelisted to access your "awskeyring" keychain\. Use a strong password and keep the unlock time short\.
|
179
|
+
.
|
180
|
+
.SH "AUTHOR"
|
181
|
+
Tristan Morgan \fItristan\.morgan@servian\.com\fR is the maintainer of Awskeyring\.
|
182
|
+
.
|
183
|
+
.SH "CONTRIBUTORS"
|
184
|
+
.
|
185
|
+
.IP "\(bu" 4
|
186
|
+
Tristan tristanmorgan \fIhttps://github\.com/tristanmorgan\fR
|
187
|
+
.
|
188
|
+
.IP "\(bu" 4
|
189
|
+
Adam Sir AzySir \fIhttps://github\.com/AzySir\fR
|
190
|
+
.
|
191
|
+
.IP "" 0
|
192
|
+
.
|
193
|
+
.SH "LICENSE"
|
194
|
+
The gem is available as open source under the terms of the MIT License \fIhttps://opensource\.org/licenses/MIT\fR\.
|
@@ -0,0 +1,138 @@
|
|
1
|
+
# Awskeyring -- is a small tool to manage AWS account keys in the macOS Keychain
|
2
|
+
|
3
|
+
## SYNOPSIS
|
4
|
+
|
5
|
+
awskeyring COMMAND [ACCOUNT|ROLE] [OPTIONS]
|
6
|
+
|
7
|
+
awskeyring help COMMAND
|
8
|
+
|
9
|
+
## DESCRIPTION
|
10
|
+
|
11
|
+
The Awskeyring utility stores and manages AWS access keys and provides the facility to generate access tokens with
|
12
|
+
combinations of assumed roles and multi-factor-authentication codes. It includes autocompletion features and multiple
|
13
|
+
validation checks for input parsing. It also includes the ability for the AWS CLI to call it directly to provide authentication.
|
14
|
+
|
15
|
+
The commands are as follows:
|
16
|
+
|
17
|
+
* --version, -v:
|
18
|
+
|
19
|
+
Prints the version
|
20
|
+
|
21
|
+
* add ACCOUNT:
|
22
|
+
|
23
|
+
Adds an ACCOUNT to the keyring
|
24
|
+
|
25
|
+
* add-role ROLE:
|
26
|
+
|
27
|
+
Adds a ROLE to the keyring
|
28
|
+
|
29
|
+
* console ACCOUNT:
|
30
|
+
|
31
|
+
Open the AWS Console for the ACCOUNT
|
32
|
+
|
33
|
+
* env ACCOUNT:
|
34
|
+
|
35
|
+
Outputs bourne shell environment exports for an ACCOUNT
|
36
|
+
|
37
|
+
* exec ACCOUNT command...:
|
38
|
+
|
39
|
+
Execute a COMMAND with the environment set for an ACCOUNT
|
40
|
+
|
41
|
+
* help [COMMAND]:
|
42
|
+
|
43
|
+
Describe available commands or one specific command
|
44
|
+
|
45
|
+
* import:
|
46
|
+
|
47
|
+
Import an ACCOUNT to the keyring from ~/.aws/credentials
|
48
|
+
|
49
|
+
* initialise:
|
50
|
+
|
51
|
+
Initialises a new KEYCHAIN
|
52
|
+
|
53
|
+
* json ACCOUNT:
|
54
|
+
|
55
|
+
Outputs AWS CLI compatible JSON for an ACCOUNT
|
56
|
+
|
57
|
+
* list:
|
58
|
+
|
59
|
+
Prints a list of accounts in the keyring
|
60
|
+
|
61
|
+
* list-role:
|
62
|
+
|
63
|
+
Prints a list of roles in the keyring
|
64
|
+
|
65
|
+
* remove ACCOUNT:
|
66
|
+
|
67
|
+
Removes an ACCOUNT from the keyring
|
68
|
+
|
69
|
+
* remove-role ROLE:
|
70
|
+
|
71
|
+
Removes a ROLE from the keyring
|
72
|
+
|
73
|
+
* remove-token ACCOUNT:
|
74
|
+
|
75
|
+
Removes a token for ACCOUNT from the keyring
|
76
|
+
|
77
|
+
* rotate ACCOUNT:
|
78
|
+
|
79
|
+
Rotate access keys for an ACCOUNT
|
80
|
+
|
81
|
+
* token ACCOUNT [ROLE] [MFA]:
|
82
|
+
|
83
|
+
Create an STS Token from a ROLE or an MFA code
|
84
|
+
|
85
|
+
* update ACCOUNT:
|
86
|
+
|
87
|
+
Updates an ACCOUNT in the keyring
|
88
|
+
|
89
|
+
## ENVIRONMENT
|
90
|
+
|
91
|
+
The AWS_DEFAULT_REGION environment variable will be used for AWS API calls where specified or fall back to us-east-1
|
92
|
+
when not.
|
93
|
+
|
94
|
+
## EXIT STATUS
|
95
|
+
|
96
|
+
The Awskeyring utility exits 0 on success, and >0 if an error occurs.
|
97
|
+
|
98
|
+
## EXAMPLES
|
99
|
+
|
100
|
+
First you need to initialise your keychain to hold your AWS credentials.
|
101
|
+
|
102
|
+
awskeyring initialise
|
103
|
+
|
104
|
+
Then add your keys to it.
|
105
|
+
|
106
|
+
awskeyring add personal-aws
|
107
|
+
|
108
|
+
Now your keys are stored safely in the macOS keychain. To print environment variables run...
|
109
|
+
|
110
|
+
awskeyring env personal-aws
|
111
|
+
|
112
|
+
## HISTORY
|
113
|
+
|
114
|
+
The motivation of this application is to provide a local secure store of AWS
|
115
|
+
credentials using specifically in the macOS Keychain, to have them easily accessed
|
116
|
+
from the Terminal, and to provide useful functions like assuming roles and opening
|
117
|
+
the AWS Console from the cli.
|
118
|
+
For Enterprise environments there are better suited tools to use
|
119
|
+
like [HashiCorp Vault](https://vaultproject.io/).
|
120
|
+
|
121
|
+
## SECURITY
|
122
|
+
|
123
|
+
If you believe you have found a security issue in Awskeyring, please responsibly disclose by contacting me at
|
124
|
+
[tristan.morgan@servian.com](mailto:tristan.morgan@servian.com). Awskeyring is a Ruby script and as such Ruby is whitelisted to
|
125
|
+
access your "awskeyring" keychain. Use a strong password and keep the unlock time short.
|
126
|
+
|
127
|
+
## AUTHOR
|
128
|
+
|
129
|
+
Tristan Morgan <tristan.morgan@servian.com> is the maintainer of Awskeyring.
|
130
|
+
|
131
|
+
## CONTRIBUTORS
|
132
|
+
|
133
|
+
* Tristan [tristanmorgan](https://github.com/tristanmorgan)
|
134
|
+
* Adam Sir [AzySir](https://github.com/AzySir)
|
135
|
+
|
136
|
+
## LICENSE
|
137
|
+
|
138
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: awskeyring
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tristan Morgan
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-06-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk-iam
|
@@ -67,8 +67,7 @@ dependencies:
|
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
description: Manages AWS credentials in the macOS keychain
|
70
|
-
email:
|
71
|
-
- tristan@vibrato.com.au
|
70
|
+
email: tristan.morgan@servian.com
|
72
71
|
executables:
|
73
72
|
- awskeyring
|
74
73
|
extensions: []
|
@@ -90,10 +89,17 @@ files:
|
|
90
89
|
- lib/awskeyring/validate.rb
|
91
90
|
- lib/awskeyring/version.rb
|
92
91
|
- lib/awskeyring_command.rb
|
92
|
+
- man/awskeyring.5
|
93
|
+
- man/awskeyring.5.ronn
|
93
94
|
homepage: https://github.com/servian/awskeyring
|
94
95
|
licenses:
|
95
96
|
- MIT
|
96
|
-
metadata:
|
97
|
+
metadata:
|
98
|
+
bug_tracker_uri: https://github.com/servian/awskeyring/issues
|
99
|
+
changelog_uri: https://github.com/servian/awskeyring/blob/master/CHANGELOG.md
|
100
|
+
documentation_uri: https://rubydoc.info/gems/awskeyring/1.4.0
|
101
|
+
source_code_uri: https://github.com/servian/awskeyring/tree/v1.4.0
|
102
|
+
wiki_uri: https://github.com/servian/awskeyring/wiki
|
97
103
|
post_install_message:
|
98
104
|
rdoc_options: []
|
99
105
|
require_paths:
|