aws_assume_role 1.0.6-linux
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 +7 -0
- data/.gitignore +9 -0
- data/.rubocop.yml +57 -0
- data/.ruby-version +1 -0
- data/.simplecov +22 -0
- data/.travis.yml +21 -0
- data/CHANGELOG.md +57 -0
- data/Gemfile +18 -0
- data/LICENSE.md +201 -0
- data/README.md +303 -0
- data/Rakefile +47 -0
- data/aws_assume_role.gemspec +56 -0
- data/bin/aws-assume-role +4 -0
- data/i18n/en.yml +109 -0
- data/lib/aws_assume_role/cli/actions/abstract_action.rb +61 -0
- data/lib/aws_assume_role/cli/actions/configure_profile.rb +24 -0
- data/lib/aws_assume_role/cli/actions/configure_role_assumption.rb +22 -0
- data/lib/aws_assume_role/cli/actions/console.rb +70 -0
- data/lib/aws_assume_role/cli/actions/delete_profile.rb +22 -0
- data/lib/aws_assume_role/cli/actions/includes.rb +12 -0
- data/lib/aws_assume_role/cli/actions/list_profiles.rb +12 -0
- data/lib/aws_assume_role/cli/actions/migrate_profile.rb +20 -0
- data/lib/aws_assume_role/cli/actions/reset_environment.rb +50 -0
- data/lib/aws_assume_role/cli/actions/run.rb +36 -0
- data/lib/aws_assume_role/cli/actions/set_environment.rb +62 -0
- data/lib/aws_assume_role/cli/actions/test.rb +35 -0
- data/lib/aws_assume_role/cli/commands/configure.rb +32 -0
- data/lib/aws_assume_role/cli/commands/console.rb +19 -0
- data/lib/aws_assume_role/cli/commands/delete.rb +13 -0
- data/lib/aws_assume_role/cli/commands/environment.rb +34 -0
- data/lib/aws_assume_role/cli/commands/list.rb +12 -0
- data/lib/aws_assume_role/cli/commands/migrate.rb +13 -0
- data/lib/aws_assume_role/cli/commands/run.rb +19 -0
- data/lib/aws_assume_role/cli/commands/test.rb +20 -0
- data/lib/aws_assume_role/cli/includes.rb +3 -0
- data/lib/aws_assume_role/cli.rb +20 -0
- data/lib/aws_assume_role/configuration.rb +30 -0
- data/lib/aws_assume_role/core_ext/aws-sdk/credential_provider_chain.rb +4 -0
- data/lib/aws_assume_role/core_ext/aws-sdk/includes.rb +9 -0
- data/lib/aws_assume_role/credentials/factories/abstract_factory.rb +33 -0
- data/lib/aws_assume_role/credentials/factories/assume_role.rb +39 -0
- data/lib/aws_assume_role/credentials/factories/default_chain_provider.rb +113 -0
- data/lib/aws_assume_role/credentials/factories/environment.rb +26 -0
- data/lib/aws_assume_role/credentials/factories/includes.rb +15 -0
- data/lib/aws_assume_role/credentials/factories/instance_profile.rb +19 -0
- data/lib/aws_assume_role/credentials/factories/repository.rb +37 -0
- data/lib/aws_assume_role/credentials/factories/shared.rb +19 -0
- data/lib/aws_assume_role/credentials/factories/static.rb +18 -0
- data/lib/aws_assume_role/credentials/factories.rb +11 -0
- data/lib/aws_assume_role/credentials/includes.rb +6 -0
- data/lib/aws_assume_role/credentials/providers/assume_role_credentials.rb +60 -0
- data/lib/aws_assume_role/credentials/providers/includes.rb +9 -0
- data/lib/aws_assume_role/credentials/providers/mfa_session_credentials.rb +119 -0
- data/lib/aws_assume_role/credentials/providers/shared_keyring_credentials.rb +41 -0
- data/lib/aws_assume_role/includes.rb +38 -0
- data/lib/aws_assume_role/logging.rb +27 -0
- data/lib/aws_assume_role/profile_configuration.rb +73 -0
- data/lib/aws_assume_role/runner.rb +40 -0
- data/lib/aws_assume_role/store/includes.rb +8 -0
- data/lib/aws_assume_role/store/keyring.rb +61 -0
- data/lib/aws_assume_role/store/serialization.rb +20 -0
- data/lib/aws_assume_role/store/shared_config_with_keyring.rb +250 -0
- data/lib/aws_assume_role/types.rb +31 -0
- data/lib/aws_assume_role/ui.rb +57 -0
- data/lib/aws_assume_role/vendored/aws/README.md +2 -0
- data/lib/aws_assume_role/vendored/aws/assume_role_credentials.rb +67 -0
- data/lib/aws_assume_role/vendored/aws/includes.rb +9 -0
- data/lib/aws_assume_role/vendored/aws/refreshing_credentials.rb +58 -0
- data/lib/aws_assume_role/vendored/aws/shared_config.rb +223 -0
- data/lib/aws_assume_role/vendored/aws.rb +4 -0
- data/lib/aws_assume_role/version.rb +5 -0
- data/lib/aws_assume_role.rb +4 -0
- metadata +438 -0
data/README.md
ADDED
@@ -0,0 +1,303 @@
|
|
1
|
+
aws-assume-role
|
2
|
+
---------------
|
3
|
+
[](https://travis-ci.org/scalefactory/aws-assume-role)
|
4
|
+
[](https://coveralls.io/github/scalefactory/aws-assume-role?branch=master)
|
5
|
+
[](https://codeclimate.com/github/scalefactory/aws-assume-role)
|
6
|
+
[](https://badge.fury.io/rb/aws_assume_role)
|
7
|
+
|
8
|
+
aws-assume-role is a utility intended for developer and operator environments
|
9
|
+
who need to use 2FA and role assumption to access AWS services.
|
10
|
+
|
11
|
+
aws-assume-role can store both AWS access keys and ephemeral session tokens in
|
12
|
+
OS credential vaults - Keychain on OSX and Keyring on Gnome.
|
13
|
+
|
14
|
+
Why?
|
15
|
+
---
|
16
|
+
|
17
|
+
This keeps your credentials safe in the keystore, and exist as
|
18
|
+
environment variables for the duration and context of the executing command.
|
19
|
+
This helps prevent credential leaking and theft, and means they aren't stored on
|
20
|
+
disk as unencrypted files.
|
21
|
+
|
22
|
+
It allows easy credential management and role assumption with a 2FA/MFA device.
|
23
|
+
|
24
|
+
For more information on role assumption, see the [AWS documentation](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html).
|
25
|
+
|
26
|
+
Requirements
|
27
|
+
------------
|
28
|
+
* Ruby ≥ 2.2
|
29
|
+
* macOS Keychain / GNOME Keyring
|
30
|
+
* At least one account with Amazon Web Services
|
31
|
+
* An IAM role configured in the target account
|
32
|
+
* An IAM user with rights to assume that role
|
33
|
+
|
34
|
+
Install
|
35
|
+
-------
|
36
|
+
|
37
|
+
```sh
|
38
|
+
gem install aws_assume_role
|
39
|
+
```
|
40
|
+
|
41
|
+
### Platform notes
|
42
|
+
|
43
|
+
Gnome Keyring uses the [GirFFI](https://github.com/mvz/gir_ffi) bindings, which
|
44
|
+
require introspection bindings as well as Gnone Keyring, by installing one of the following packages:
|
45
|
+
|
46
|
+
``` sh
|
47
|
+
# Debian/Ubuntu
|
48
|
+
apt-get install gnome-keyring libgirepository1.0-dev libgnome-keyring-common libgnome-keyring-dev
|
49
|
+
|
50
|
+
# Fedora
|
51
|
+
dnf install gobject-introspection-devel
|
52
|
+
|
53
|
+
# CentOS
|
54
|
+
yum install gobject-introspection-devel
|
55
|
+
```
|
56
|
+
Setup
|
57
|
+
-----
|
58
|
+
|
59
|
+
You should already have an IAM user that you can log in to via AWS' console.
|
60
|
+
If you do not already have an AWS access key and matching secret key for your
|
61
|
+
own IAM user, use the AWS console to create that credential pair.
|
62
|
+
|
63
|
+
aws-assume-role works best if you also store permanent credentials in your keystore:
|
64
|
+
|
65
|
+
``` sh
|
66
|
+
> aws-assume-role configure
|
67
|
+
Enter the profile name to save into configuration
|
68
|
+
company_sso
|
69
|
+
Enter the AWS region you would like to default to:
|
70
|
+
eu-west-1
|
71
|
+
Enter the AWS Access Key ID to use for this profile:
|
72
|
+
1234567890010
|
73
|
+
Enter the AWS Secret Access Key to use for this profile:
|
74
|
+
abcdefghijklmnopqrstuvwzyx1
|
75
|
+
Profile `company_sso` saved to '/home/growthsmith/.aws/config'
|
76
|
+
```
|
77
|
+
|
78
|
+
### Configuring roles
|
79
|
+
Now that you've set up permanent credentials in your OS credential store, you can now
|
80
|
+
set up a role that you will assume in every day use:
|
81
|
+
|
82
|
+
``` sh
|
83
|
+
> aws-assume-role configure role -p company-dev --source-profile company_sso \
|
84
|
+
--role-arn=arn:aws:iam::000000000001:role/ViewEC2 --role-session-name=growthsmith \
|
85
|
+
--mfa-serial automatic
|
86
|
+
```
|
87
|
+
`--mfa-serial automatic` will look up your default attached multi-factor device, but you can specify a specific ARN.
|
88
|
+
|
89
|
+
More options are available in the application help.
|
90
|
+
Use `> aws-assume-role --help ` for help at any time.
|
91
|
+
|
92
|
+
Using MFA TOTP with a Yubikey
|
93
|
+
-----------------------------
|
94
|
+
|
95
|
+
[Yubikeys support TOTP](https://developers.yubico.com/OATH/) this offers some
|
96
|
+
benefits over using a phone. One benefit is the TOTP token can be retrieved by
|
97
|
+
an API call rather than a user reading the token from the device.
|
98
|
+
|
99
|
+
This allows developers to call AWS through aws-assume-role, providing an MFA
|
100
|
+
token without prompting for user input. To use this specify
|
101
|
+
`--yubikey-oath-name` when calling configure role.
|
102
|
+
|
103
|
+
``` sh
|
104
|
+
> aws-assume-role configure role -p company-dev --source-profile company_sso \
|
105
|
+
--role-arn=arn:aws:iam::000000000001:role/ViewEC2 --role-session-name=growthsmith \
|
106
|
+
--mfa-serial automatic --yubikey-oath-name "Amazon Web Services:myuser@company_sso"
|
107
|
+
```
|
108
|
+
|
109
|
+
_Yubikey Support_: `aws-assume-role` uses the [smartcard gem](https://rubygems.org/gems/smartcard)
|
110
|
+
to connect to the Yubikey, this itself depends upon some C libraries being installed. They provide
|
111
|
+
[platform specific instructions](https://github.com/costan/smartcard/blob/master/BUILD#L19)
|
112
|
+
for installing these libraries PC/SC.
|
113
|
+
|
114
|
+
Testing a profile
|
115
|
+
-----------------
|
116
|
+
You can test a profile using
|
117
|
+
```sh
|
118
|
+
> aws-assume-role test -p company_sso
|
119
|
+
Logged in as:
|
120
|
+
User: 9999999999
|
121
|
+
Account: arn:aws:iam::3333333333:user/username
|
122
|
+
ARN: AIDAIOSWINGTB
|
123
|
+
|
124
|
+
```
|
125
|
+
|
126
|
+
Running applications
|
127
|
+
--------------------
|
128
|
+
|
129
|
+
You can run another application using
|
130
|
+
|
131
|
+
``` sh
|
132
|
+
aws-assume-role run -p company-dev -- aws ec2 describe-instances --query \
|
133
|
+
"Reservations[*].Instances[*].PrivateIpAddress" --output=text
|
134
|
+
10.254.4.20
|
135
|
+
10.254.4.15
|
136
|
+
10.254.0.10
|
137
|
+
10.254.4.5
|
138
|
+
```
|
139
|
+
|
140
|
+
Because we've enabled MFA, aws-assume-role will ask for your MFA token:
|
141
|
+
```
|
142
|
+
Please provide an MFA token
|
143
|
+
000000
|
144
|
+
```
|
145
|
+
|
146
|
+
Listing available profiles
|
147
|
+
--------------------------
|
148
|
+
Configured profiles can be listed:
|
149
|
+
```sh
|
150
|
+
> aws-assume-role list
|
151
|
+
company_sso
|
152
|
+
company2_sso
|
153
|
+
company3_sso
|
154
|
+
```
|
155
|
+
|
156
|
+
Deleting a profile
|
157
|
+
------------------
|
158
|
+
If a set of credentials key needs revoking, or the profile isn't relevant anymore:
|
159
|
+
``` sh
|
160
|
+
> aws-assume-role delete -p company_sso
|
161
|
+
Please type the name of the profile, i.e. company_sso , to continue deletion.
|
162
|
+
company_sso
|
163
|
+
Profile company_sso deleted
|
164
|
+
```
|
165
|
+
|
166
|
+
Migrating AWS CLI profiles
|
167
|
+
------------------
|
168
|
+
It's better to revoke the existing keys and generate new ones. We try to overwrite the plaintext configuration
|
169
|
+
file with random data, but this does not take care of ~/.aws/credentials and does not account for SSD wear
|
170
|
+
levelling or copy-on-write snapshots.
|
171
|
+
```
|
172
|
+
aws-assume-role migrate -p company_sso
|
173
|
+
Profile 'company_sso' migrated to keyring.
|
174
|
+
```
|
175
|
+
|
176
|
+
Exporting environment variables
|
177
|
+
-------------------------------
|
178
|
+
You can use a session token in your shell any supported application without using
|
179
|
+
`aws-assume-role`.
|
180
|
+
|
181
|
+
You can also remove environment variables after finishing using the reset command.
|
182
|
+
|
183
|
+
#### Bourne Shell and friends
|
184
|
+
``` sh
|
185
|
+
> eval `./bin/aws-assume-role environment set -p company-dev`
|
186
|
+
> eval `./bin/aws-assume-role environment reset`
|
187
|
+
```
|
188
|
+
|
189
|
+
#### fish
|
190
|
+
``` fish
|
191
|
+
> set creds (bin/aws-assume-role environment set -s fish -p company-dev); eval $creds; set -e creds
|
192
|
+
> set creds (bin/aws-assume-role environment reset -s fish); eval $creds; set -e creds
|
193
|
+
```
|
194
|
+
|
195
|
+
#### PowerShell
|
196
|
+
``` powershell
|
197
|
+
> aws-assume-role environment set -s powershell -p company-dev | invoke-expression
|
198
|
+
> aws-assume-role environment reset -s powershell | invoke-expression
|
199
|
+
```
|
200
|
+
|
201
|
+
Launch the AWS console
|
202
|
+
---------------------
|
203
|
+
Given that `aws-assume-role` has knowledge of your role ARNs via AWS CLI profiles, you can
|
204
|
+
get to the AWS console for that role/account using
|
205
|
+
|
206
|
+
``` sh
|
207
|
+
> aws-assume-role console -p company_sso
|
208
|
+
```
|
209
|
+
|
210
|
+
`aws-assume-role` will first attempt to log in and get a federated UI link, and
|
211
|
+
otherwise fall back to the "switch role" page.
|
212
|
+
|
213
|
+
Using inside Ruby
|
214
|
+
-----------------
|
215
|
+
To get a set of credentials via the OS credential store, or using console-based MFA, use
|
216
|
+
the following:
|
217
|
+
```
|
218
|
+
require "aws_assume_role"
|
219
|
+
|
220
|
+
AwsAssumeRole::DefaultProvider.new(options).resolve
|
221
|
+
```
|
222
|
+
where options is a hash with the following symbol keys:
|
223
|
+
* `access_key_id`
|
224
|
+
* `secret_access_key`
|
225
|
+
* `session_token`
|
226
|
+
* `persist_session`
|
227
|
+
* `duration_seconds`
|
228
|
+
* `role_arn`
|
229
|
+
* `role_session_name`
|
230
|
+
* `serial_number`
|
231
|
+
* `source_profile`
|
232
|
+
* `region`
|
233
|
+
|
234
|
+
`aws_assume_role` resolves credentials in almost the same way as the AWS SDK, i.e.:
|
235
|
+
|
236
|
+
```no-highlight
|
237
|
+
static credentials ⟶ environment variables ⟶ configured profiles role ⟶ assumption (look up source profile and check for 2FA)
|
238
|
+
```
|
239
|
+
|
240
|
+
Any of the above may get chained to do MFA or role assumption, or both,
|
241
|
+
in the following order:
|
242
|
+
|
243
|
+
```no-highlight
|
244
|
+
second factor ⟶ ecs/instance profile
|
245
|
+
```
|
246
|
+
|
247
|
+
These are the same as the AWS SDK equivalents whereever possible. The command line help will give an explanation of the rest.
|
248
|
+
|
249
|
+
### Monkeypatching the AWS SDK
|
250
|
+
You can also override the standard AWS SDK credential resolution system by including the following:
|
251
|
+
```
|
252
|
+
require "aws_assume_role/core_ext/aws-sdk/credential_provider_chain"
|
253
|
+
```
|
254
|
+
|
255
|
+
Using any standard AWS SDK for Ruby v2 client will then use aws_assume_role for credential resolution.
|
256
|
+
|
257
|
+
|
258
|
+
Please do not use this in production systems.
|
259
|
+
|
260
|
+
Other keyring backends
|
261
|
+
----------------------
|
262
|
+
`aws-assume-role` uses the Keyring gem for secure secret storage. By default, this will use OS X keycain
|
263
|
+
or GNOME Keyring. To load alternatives, set the following environment variables:
|
264
|
+
|
265
|
+
* `AWS_ASSUME_ROLE_KEYRING_BACKEND`: Which backend to use, as the name of the Ruby class.
|
266
|
+
* `AWS_ASSUME_ROLE_KEYRING_PLUGIN` : Name of a gem to load.
|
267
|
+
|
268
|
+
These are also available in Ruby as the `AwsAssumeRole.Config.backend_plugin` and
|
269
|
+
`AwsAssumeRole.Config.backend_plugin` attributes.
|
270
|
+
|
271
|
+
|
272
|
+
Development
|
273
|
+
-----------
|
274
|
+
|
275
|
+
Tests are conducted by Travis.
|
276
|
+
|
277
|
+
You can run these locally using Rake:
|
278
|
+
|
279
|
+
```shell
|
280
|
+
bundle exec rake test
|
281
|
+
```
|
282
|
+
|
283
|
+
License
|
284
|
+
-------
|
285
|
+
|
286
|
+
This library and program is distributed under the
|
287
|
+
[Apache License, version 2.0](http://www.apache.org/licenses/LICENSE-2.0.html)
|
288
|
+
|
289
|
+
```no-highlight
|
290
|
+
Copyright 2017. The Scale Factory Ltd. All Rights Reserved.
|
291
|
+
Portions Copyright 2013. Amazon Web Services, Inc. All Rights Reserved.
|
292
|
+
|
293
|
+
licensed under the apache license, version 2.0 (the "license");
|
294
|
+
you may not use this file except in compliance with the license.
|
295
|
+
you may obtain a copy of the license at
|
296
|
+
|
297
|
+
http://www.apache.org/licenses/license-2.0
|
298
|
+
|
299
|
+
unless required by applicable law or agreed to in writing, software
|
300
|
+
distributed under the license is distributed on an "as is" basis,
|
301
|
+
without warranties or conditions of any kind, either express or implied.
|
302
|
+
see the license for the specific language governing permissions and
|
303
|
+
limitations under the license.
|
data/Rakefile
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "aws_assume_role/version"
|
4
|
+
require "bundler/gem_tasks"
|
5
|
+
|
6
|
+
task default: :test
|
7
|
+
|
8
|
+
begin
|
9
|
+
require "rspec/core/rake_task"
|
10
|
+
RSpec::Core::RakeTask.new(:spec)
|
11
|
+
rescue LoadError # rubocop:disable Lint/HandleExceptions
|
12
|
+
end
|
13
|
+
|
14
|
+
begin
|
15
|
+
require "rubocop/rake_task"
|
16
|
+
RuboCop::RakeTask.new(:rubocop)
|
17
|
+
rescue LoadError # rubocop:disable Lint/HandleExceptions
|
18
|
+
end
|
19
|
+
|
20
|
+
task test: %i[no_pry rubocop spec]
|
21
|
+
|
22
|
+
DISTRIBUTIONS = [
|
23
|
+
"universal-linux",
|
24
|
+
"universal-freebsd",
|
25
|
+
"universal-darwin",
|
26
|
+
"universal-openbsd",
|
27
|
+
].freeze
|
28
|
+
|
29
|
+
namespace :build_arch do
|
30
|
+
DISTRIBUTIONS.each do |arch|
|
31
|
+
desc "build binary gem for #{arch}"
|
32
|
+
task arch do
|
33
|
+
sh "cd #{File.dirname(__FILE__)} && PLATFORM=#{arch} gem build aws_assume_role.gemspec"
|
34
|
+
sh "cd #{File.dirname(__FILE__)} && mkdir -p pkg"
|
35
|
+
sh "cd #{File.dirname(__FILE__)} && mv *.gem pkg/"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
task build: DISTRIBUTIONS.map { |d| "build_arch:#{d}" }
|
41
|
+
|
42
|
+
task :no_pry do
|
43
|
+
files = Dir.glob("**/**").reject { |x| x.match(/^spec|Gemfile|coverage|\.gemspec$|Rakefile/) || File.directory?(x) }
|
44
|
+
files.each do |file|
|
45
|
+
raise "Use of pry found in #{file}." if File.read(file) =~ /"pry"/
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
$LOAD_PATH << File.expand_path("../lib", __FILE__)
|
4
|
+
require "aws_assume_role/version"
|
5
|
+
|
6
|
+
PLATFORM = ENV.fetch("PLATFORM", Gem::Platform.local.os)
|
7
|
+
|
8
|
+
Gem::Specification.new do |spec|
|
9
|
+
spec.name = "aws_assume_role"
|
10
|
+
spec.version = AwsAssumeRole::VERSION
|
11
|
+
spec.authors = ["Jon Topper", "Jack Thomas", "Naadir Jeewa", "David King", "Tim Bannister", "Phil Potter", "Tom Haynes"]
|
12
|
+
spec.email = ["jon@scalefactory.com", "jack@scalefactory.com", "naadir@scalefactory.com", "tim@scalefactory.com"]
|
13
|
+
|
14
|
+
spec.description = "Used to fetch multiple AWS Role Credential "\
|
15
|
+
"Keys using different Session Keys "\
|
16
|
+
"and store them securely using Gnome Keyring "\
|
17
|
+
"or OSX keychain"
|
18
|
+
spec.summary = "Manage AWS STS credentials with MFA"
|
19
|
+
spec.homepage = "https://github.com/scalefactory/aws-assume-role"
|
20
|
+
spec.license = "Apache-2.0"
|
21
|
+
|
22
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f|
|
23
|
+
f.match(%r{^(test|spec|features)/})
|
24
|
+
}
|
25
|
+
spec.bindir = "bin"
|
26
|
+
spec.executables = spec.files.grep(%r{^bin/aws}) { |f| File.basename(f) }
|
27
|
+
spec.require_paths = ["lib"]
|
28
|
+
spec.platform = PLATFORM
|
29
|
+
spec.add_runtime_dependency "activesupport", "~> 4.2"
|
30
|
+
spec.add_runtime_dependency "aws-sdk", "~> 2.7"
|
31
|
+
spec.add_runtime_dependency "dry-configurable", "~> 0.5"
|
32
|
+
spec.add_runtime_dependency "dry-struct", "~> 0.1"
|
33
|
+
spec.add_runtime_dependency "dry-types", "~> 0.12"
|
34
|
+
spec.add_runtime_dependency "dry-validation", "~> 0.10"
|
35
|
+
spec.add_runtime_dependency "gli", "~> 2.15"
|
36
|
+
spec.add_runtime_dependency "highline", "~> 1.6"
|
37
|
+
spec.add_runtime_dependency "i18n", "~> 0.7"
|
38
|
+
spec.add_runtime_dependency "inifile", "~> 3.0"
|
39
|
+
spec.add_runtime_dependency "launchy", "~> 2.4"
|
40
|
+
spec.add_runtime_dependency "keyring", "~> 0.4", ">= 0.4.1"
|
41
|
+
spec.add_runtime_dependency "pastel", "~> 0.7"
|
42
|
+
spec.add_runtime_dependency "smartcard", "~> 0.5.6"
|
43
|
+
spec.add_runtime_dependency "yubioath", "~> 1.2", ">= 1.2.1"
|
44
|
+
spec.add_development_dependency "rspec", "~> 3.5"
|
45
|
+
spec.add_development_dependency "rubocop", "0.50"
|
46
|
+
spec.add_development_dependency "yard", "~> 0.9"
|
47
|
+
spec.add_development_dependency "simplecov", "~> 0.13"
|
48
|
+
spec.add_development_dependency "webmock", "~> 2.3"
|
49
|
+
|
50
|
+
case PLATFORM
|
51
|
+
when /linux|bsd/
|
52
|
+
spec.add_dependency "gir_ffi-gnome_keyring", "~> 0.0", ">= 0.0.3"
|
53
|
+
when /darwin/
|
54
|
+
spec.add_dependency "ruby-keychain", "~> 0.3", ">= 0.3.2"
|
55
|
+
end
|
56
|
+
end
|
data/bin/aws-assume-role
ADDED
data/i18n/en.yml
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
en:
|
2
|
+
commands:
|
3
|
+
configure:
|
4
|
+
desc: Configure AWS
|
5
|
+
long_desc: |
|
6
|
+
Configure AWS profiles. If this command is run with no arguments,
|
7
|
+
you will be prompted for configuration values such as your AWS Access
|
8
|
+
Key Id and you AWS Secret Access Key. You can configure a named pro-
|
9
|
+
file using the --profile argument. If your config file does not exist
|
10
|
+
(the default location is ~/.aws/config), the AWS CLI will create it for
|
11
|
+
you. To keep an existing value, hit enter when prompted for the value.
|
12
|
+
When you are prompted for information, the current value will be dis-
|
13
|
+
played in [brackets]. If the config item has no value, it be displayed
|
14
|
+
as [None]. Note that the configure command only work with values from
|
15
|
+
the config file. It does not use any configuration values from envi-
|
16
|
+
ronment variables or the IAM role.
|
17
|
+
|
18
|
+
Note: The values you provide for the AWS Access Key ID and the AWS
|
19
|
+
Secret Access Key will be written to your keyring backend.
|
20
|
+
saved: Profile %s saved to %s
|
21
|
+
console:
|
22
|
+
desc: Launch the AWS console to switch to the profile role.
|
23
|
+
long_desc: |
|
24
|
+
Looks up the Role ARN in the profile, constructs the AWS console
|
25
|
+
URL and launches your browser with it. It's a convenience, doesn't
|
26
|
+
use any of the credentials.
|
27
|
+
set_environment:
|
28
|
+
desc: Export assumed credentials to your shell environment.
|
29
|
+
long_desc: |
|
30
|
+
Set up environment variables in your shell so that you can run AWS CLI
|
31
|
+
or other apps using those credentials without running aws-assume-role
|
32
|
+
again.
|
33
|
+
Supports Bourne, CSh, Fish and PowerShell.
|
34
|
+
shells:
|
35
|
+
powershell: Use `aws-assume-role environment set -s powershell -p <profile_name> | Invoke-Expression` to load into environment
|
36
|
+
others: Use `eval aws-assume-role environment set -p <profile_name>` to load into environment
|
37
|
+
fish: Use `set creds (bin/aws-assume-role environment set -s fish); eval $creds; set -e creds`
|
38
|
+
reset_environment:
|
39
|
+
desc: Delete AWS environment variables.
|
40
|
+
long_desc: |
|
41
|
+
Cleans up your shell environment by removing the following environment variables:
|
42
|
+
AWS_ACCESS_KEY_ID
|
43
|
+
AWS_SECRET_ACCESS_KEY
|
44
|
+
AWS_DEFAULT_REGION
|
45
|
+
AWS_PROFILE
|
46
|
+
AWS_ASSUME_ROLE_LOG_LEVEL
|
47
|
+
GLI_DEBUG
|
48
|
+
Supports Bourne, CSh, Fish and PowerShell.
|
49
|
+
shells:
|
50
|
+
powershell: Use `aws-assume-role environment reset -s powershell -p <profile_name> | Invoke-Expression` to load into environment
|
51
|
+
others: Use `eval aws-assume-role environment reset -p <profile_name>` to load into environment
|
52
|
+
fish: Use `set creds (bin/aws-assume-role environment reset -s fish); eval $creds; set -e creds`
|
53
|
+
run:
|
54
|
+
desc: Run a program with credentials set in the environment.
|
55
|
+
delete:
|
56
|
+
desc: Delete a profile
|
57
|
+
completed: "Profile %s deleted"
|
58
|
+
not_found: "Cannot find profile %s. Try running `aws-assume-role list`"
|
59
|
+
list:
|
60
|
+
desc: List configured profiles
|
61
|
+
migrate:
|
62
|
+
desc: Migrate a store to secure storage.
|
63
|
+
not_found: "Cannot find profile %s. Try running `aws-assume-role list`"
|
64
|
+
saved: Profile %s migrated within %s
|
65
|
+
test:
|
66
|
+
desc: Check that credentials work
|
67
|
+
output: |
|
68
|
+
Logged in as:
|
69
|
+
User: %s
|
70
|
+
Account: %s
|
71
|
+
ARN: %s
|
72
|
+
options:
|
73
|
+
aws_access_key_id: "Enter the AWS Access Key ID to use for this profile"
|
74
|
+
aws_secret_access_key: "Enter the AWS Secret Access Key to use for this profile"
|
75
|
+
region: Enter the AWS region you would like to default to
|
76
|
+
profile_name: Enter the profile name to save into configuration
|
77
|
+
mfa_token:
|
78
|
+
first_time: "Please provide an MFA token"
|
79
|
+
other_times: "Credentials have expired, please provide another MFA"
|
80
|
+
smartcard_not_supported: "Smartcard drivers not installed, see https://github.com/scalefactory/aws-assume-role/blob/master/README.md for details"
|
81
|
+
default_role: "A default role to assume (leave blank to not use)"
|
82
|
+
external_id: String provided by the external account holder to uniquely identify you.
|
83
|
+
source_profile: Which profile to use to assume this role.
|
84
|
+
role_session_name: Name to uniquely identify your session
|
85
|
+
mfa_serial: The identification number of the MFA device. Leave blank to determine dynamically at run time.
|
86
|
+
role_arn: The Amazon Resource Name (ARN) of the role to assume.
|
87
|
+
duration_seconds: Default session length
|
88
|
+
shell_type: What type of shell to use.
|
89
|
+
name_to_delete: Please type the name of the profile, i.e. %s , to continue deletion.
|
90
|
+
yubikey_oath_name: Identifier of the OATH / TOTP secret stored on the yubikey.
|
91
|
+
program_description: "A tool for AWS credential management"
|
92
|
+
errors:
|
93
|
+
NoSuchProfileError: Profile %s not found in shared configuration.
|
94
|
+
SmartcardException: No YubiKey found!
|
95
|
+
MissingCredentialsError: No credentials found!
|
96
|
+
rules:
|
97
|
+
profile:
|
98
|
+
filled?: --profile must be specified.
|
99
|
+
role-arn:
|
100
|
+
format?: "--role-arn must be specified as an ARN in the format `arn:aws:iam::account-id:role/role-name`"
|
101
|
+
filled?: --role-arn is required.
|
102
|
+
serial-number:
|
103
|
+
format?: "--mfa-serial must be specified as an ARN in the format `arn:aws:iam::account-id:mfa/virtual-device-name`"
|
104
|
+
filled?: --mfa-serial is required.
|
105
|
+
region:
|
106
|
+
format?: "--region must be a valid AWS Standard, China or GovCloud region"
|
107
|
+
filled?: --region is required
|
108
|
+
role_specification:
|
109
|
+
filled?: "Either specify --profile OR (--role-arn AND --role-session-name, or neither)"
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "includes"
|
4
|
+
require_relative "../../profile_configuration"
|
5
|
+
|
6
|
+
class AwsAssumeRole::Cli::Actions::AbstractAction
|
7
|
+
include AwsAssumeRole
|
8
|
+
include AwsAssumeRole::Types
|
9
|
+
include AwsAssumeRole::Ui
|
10
|
+
include AwsAssumeRole::Logging
|
11
|
+
CommandSchema = proc { raise "CommandSchema Not implemented" }
|
12
|
+
|
13
|
+
def initialize(global_options, options, args)
|
14
|
+
config = ProfileConfiguration.new_from_cli(global_options, options, args)
|
15
|
+
logger.debug "Config initialized with #{config.to_hash}"
|
16
|
+
result = validate_options(config.to_hash)
|
17
|
+
logger.debug "Config validated as #{result.to_hash}"
|
18
|
+
result.success? ? act_on(config) : Ui.show_validation_errors(result)
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def try_for_credentials(config)
|
24
|
+
@provider ||= AwsAssumeRole::Credentials::Factories::DefaultChainProvider.new(config.to_hash)
|
25
|
+
creds = @provider.resolve(nil_with_role_not_set: true)
|
26
|
+
logger.debug "Got credentials #{creds}"
|
27
|
+
return creds unless creds.nil?
|
28
|
+
rescue Smartcard::PCSC::Exception
|
29
|
+
error t("errors.SmartcardException")
|
30
|
+
exit 403
|
31
|
+
rescue NoMethodError
|
32
|
+
error t("errors.MissingCredentialsError")
|
33
|
+
exit 404
|
34
|
+
end
|
35
|
+
|
36
|
+
def resolved_region
|
37
|
+
@provider.region
|
38
|
+
end
|
39
|
+
|
40
|
+
def resolved_profile
|
41
|
+
@provider.profile
|
42
|
+
end
|
43
|
+
|
44
|
+
def validate_options(options)
|
45
|
+
command_schema = self.class::CommandSchema
|
46
|
+
::Dry::Validation.Schema do
|
47
|
+
configure { config.messages = :i18n }
|
48
|
+
instance_eval(&command_schema)
|
49
|
+
end.call(options)
|
50
|
+
end
|
51
|
+
|
52
|
+
def prompt_for_option(key, option_name, validator, fmt: nil)
|
53
|
+
text_lookup = t("options.#{key}")
|
54
|
+
text = fmt.nil? ? text_lookup : format(text_lookup, fmt)
|
55
|
+
Ui.ask_with_validation(option_name, text) { instance_eval(&validator) }
|
56
|
+
end
|
57
|
+
|
58
|
+
def act_on(_options)
|
59
|
+
raise "Act On Not Implemented"
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "abstract_action"
|
4
|
+
require_relative "../../store/shared_config_with_keyring"
|
5
|
+
|
6
|
+
class AwsAssumeRole::Cli::Actions::ConfigureProfile < AwsAssumeRole::Cli::Actions::AbstractAction
|
7
|
+
CommandSchema = proc do
|
8
|
+
required(:profile)
|
9
|
+
optional(:region) { filled? > format?(REGION_REGEX) }
|
10
|
+
optional(:mfa_serial)
|
11
|
+
optional(:profile_name)
|
12
|
+
optional(:yubikey_oath_name)
|
13
|
+
end
|
14
|
+
|
15
|
+
def act_on(config)
|
16
|
+
new_hash = config.to_h
|
17
|
+
profile = config.profile || prompt_for_option(:profile_name, "profile", proc { filled? })
|
18
|
+
new_hash[:region] = prompt_for_option(:region, "region", proc { filled? > format?(REGION_REGEX) })
|
19
|
+
new_hash[:aws_access_key_id] = prompt_for_option(:aws_access_key_id, "aws_access_key_id", ACCESS_KEY_VALIDATOR)
|
20
|
+
new_hash[:aws_secret_access_key] = prompt_for_option(:aws_secret_access_key, "aws_secret_access_key", proc { filled? })
|
21
|
+
AwsAssumeRole.shared_config.save_profile(profile, new_hash)
|
22
|
+
out format(t("commands.configure.saved"), profile, AwsAssumeRole.shared_config.config_path)
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "abstract_action"
|
4
|
+
|
5
|
+
class AwsAssumeRole::Cli::Actions::ConfigureRoleAssumption < AwsAssumeRole::Cli::Actions::AbstractAction
|
6
|
+
CommandSchema = proc do
|
7
|
+
required(:profile)
|
8
|
+
required(:source_profile) { str? }
|
9
|
+
optional(:region) { filled? > format?(REGION_REGEX) }
|
10
|
+
optional(:serial_number) { filled? > format?(MFA_REGEX) }
|
11
|
+
required(:role_session_name).filled?
|
12
|
+
required(:role_arn) { filled? & format?(ROLE_REGEX) }
|
13
|
+
required(:external_id).filled?
|
14
|
+
required(:duration_seconds).filled?
|
15
|
+
optional(:yubikey_oath_name)
|
16
|
+
end
|
17
|
+
|
18
|
+
def act_on(config)
|
19
|
+
AwsAssumeRole.shared_config.save_profile(config.profile, config.to_h.compact)
|
20
|
+
out format(t("commands.configure.saved"), config.profile, AwsAssumeRole.shared_config.config_path)
|
21
|
+
end
|
22
|
+
end
|