aws-google 0.1.2 → 0.1.3
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/README.md +14 -5
- data/aws-google.gemspec +3 -3
- data/exe/aws-google +73 -0
- data/lib/aws/google.rb +30 -17
- data/lib/aws/google/version.rb +1 -1
- metadata +12 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 29e2bac01a2d62b1b156badf3fda404596d56fef92f5b8de438095362abea600
|
4
|
+
data.tar.gz: d25ac4ca974f4991120814679678a923375ede8bbfd0b189917344596f0d79ec
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e2e26e77654e356c81c424dd76d679c09304f44a846bff66d6d204c845d9a918e0bac3dd99d6922c9e4cfb363d773dbcfd679c29f736e46eb52acccb5f4ba0f6
|
7
|
+
data.tar.gz: 9226a37c273473589a4f56ea3e49a7a9bb652d42b436e39f62f41124ccbd36bf101e4edbd6ee7d5a44e4138e91c135f72d5a6292f8149cc4e3f2272b809add19
|
data/README.md
CHANGED
@@ -21,8 +21,8 @@ Or install it yourself as:
|
|
21
21
|
## Usage
|
22
22
|
|
23
23
|
- Visit the [Google API Console](https://console.developers.google.com/) to create/obtain OAuth 2.0 Client ID credentials (client ID and client secret) for an application in your Google account.
|
24
|
-
- Create an AWS IAM Role with the desired IAM policies attached, and a 'trust
|
25
|
-
|
24
|
+
- Create an AWS IAM Role with the desired IAM policies attached, and a ['trust policy'](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_terms-and-concepts.html#term_trust-policy) ([`AssumeRolePolicyDocument`](https://docs.aws.amazon.com/IAM/latest/APIReference/API_CreateRole.html)) allowing the [`sts:AssumeRoleWithWebIdentity`](https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithWebIdentity.html) action with [Web Identity Federation condition keys](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_iam-condition-keys.html#condition-keys-wif) authorizing
|
25
|
+
your Google Client ID (`accounts.google.com:aud`) and a specific set of Google Account IDs (`accounts.google.com:sub`):
|
26
26
|
|
27
27
|
```json
|
28
28
|
{
|
@@ -36,9 +36,7 @@ by your Google Client ID and a specific set of Google Account IDs:
|
|
36
36
|
"Action": "sts:AssumeRoleWithWebIdentity",
|
37
37
|
"Condition": {
|
38
38
|
"StringEquals": {
|
39
|
-
"accounts.google.com:aud": "123456789012-abcdefghijklmnopqrstuvwzyz0123456.apps.googleusercontent.com"
|
40
|
-
},
|
41
|
-
"ForAnyValue:StringEquals": {
|
39
|
+
"accounts.google.com:aud": "123456789012-abcdefghijklmnopqrstuvwzyz0123456.apps.googleusercontent.com",
|
42
40
|
"accounts.google.com:sub": [
|
43
41
|
"000000000000000000000",
|
44
42
|
"111111111111111111111"
|
@@ -79,6 +77,17 @@ Aws::Google.config = {
|
|
79
77
|
puts Aws::STS::Client.new.get_caller_identity
|
80
78
|
```
|
81
79
|
|
80
|
+
- Or, set `credential_process` in your AWS config profile ([`~/.aws/config`](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html#cli-configure-files-where)) to `aws-google` to [Source Credentials with an External Process](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sourcing-external.html) without any change to your application code:
|
81
|
+
|
82
|
+
```
|
83
|
+
[profile my_google]
|
84
|
+
credential_process = aws-google --profile my_google
|
85
|
+
aws_role = arn:aws:iam::[AccountID]:role/[Role]
|
86
|
+
google_client_id = 123456789012-abcdefghijklmnopqrstuvwzyz0123456.apps.googleusercontent.com
|
87
|
+
google_client_secret = 01234567890abcdefghijklmn
|
88
|
+
|
89
|
+
```
|
90
|
+
|
82
91
|
## Development
|
83
92
|
|
84
93
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/aws-google.gemspec
CHANGED
@@ -23,11 +23,11 @@ Gem::Specification.new do |spec|
|
|
23
23
|
|
24
24
|
spec.add_dependency 'aws-sdk-core', '~> 3'
|
25
25
|
spec.add_dependency 'google-api-client', '~> 0.23'
|
26
|
-
spec.add_dependency 'launchy', '~> 2'
|
26
|
+
spec.add_dependency 'launchy', '~> 2'
|
27
27
|
|
28
28
|
spec.add_development_dependency 'activesupport', '~> 5'
|
29
|
-
spec.add_development_dependency 'bundler'
|
30
|
-
spec.add_development_dependency 'minitest', '~> 5.
|
29
|
+
spec.add_development_dependency 'bundler'
|
30
|
+
spec.add_development_dependency 'minitest', '~> 5.14.2'
|
31
31
|
spec.add_development_dependency 'mocha', '~> 1.5'
|
32
32
|
spec.add_development_dependency 'rake', '~> 12'
|
33
33
|
spec.add_development_dependency 'timecop', '~> 0.8'
|
data/exe/aws-google
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# CLI to retrieve AWS credentials in credential_process format.
|
4
|
+
# Ref: https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sourcing-external.html
|
5
|
+
|
6
|
+
require 'aws/google'
|
7
|
+
require 'time'
|
8
|
+
require 'json'
|
9
|
+
require 'optparse'
|
10
|
+
|
11
|
+
def error(msg)
|
12
|
+
puts msg
|
13
|
+
exit 1
|
14
|
+
end
|
15
|
+
|
16
|
+
options = {}
|
17
|
+
OptionParser.new do |opts|
|
18
|
+
opts.on('-p PROFILE', '--profile PROFILE', 'Profile') do |p|
|
19
|
+
options[:profile] = p
|
20
|
+
end
|
21
|
+
opts.on('-v', '--version', 'Version') do
|
22
|
+
require 'aws/google/version'
|
23
|
+
puts Aws::Google::VERSION
|
24
|
+
exit 0
|
25
|
+
end
|
26
|
+
opts.on('-r ROLE', '--role ROLE', 'AWS Role arn') do |r|
|
27
|
+
options[:role_arn] = r
|
28
|
+
end
|
29
|
+
opts.on('-i ID', '--client-id ID', 'Google Client ID') do |id|
|
30
|
+
options[:google_client_id] = id
|
31
|
+
end
|
32
|
+
opts.on('-s SECRET', '--client-secret SECRET', 'Google Client Secret') do |secret|
|
33
|
+
options[:google_client_secret] = secret
|
34
|
+
end
|
35
|
+
opts.on('-h DOMAIN', '--domain DOMAIN', 'Google Domain') do |hd|
|
36
|
+
options[:domain] = hd
|
37
|
+
end
|
38
|
+
opts.on('-d DURATION', '--duration DURATION', 'Duration in seconds') do |d|
|
39
|
+
options[:duration_seconds] = d.to_i
|
40
|
+
end
|
41
|
+
opts.on('--port PORT', 'Port number for local server') do |p|
|
42
|
+
options[:port] = p.to_i
|
43
|
+
end
|
44
|
+
opts.on('--online', 'Online authentication, no refresh token') do |o|
|
45
|
+
options[:online] = true
|
46
|
+
end
|
47
|
+
end.parse!
|
48
|
+
|
49
|
+
config = Aws.shared_config
|
50
|
+
profile = options[:profile] || ENV['AWS_PROFILE'] || 'default'
|
51
|
+
|
52
|
+
options[:role_arn] ||= config.get('aws_role', profile: profile) ||
|
53
|
+
error('Missing config: aws_role')
|
54
|
+
options[:google_client_id] ||= config.get('google_client_id', profile: profile) ||
|
55
|
+
error('Missing config: google_client_id')
|
56
|
+
options[:google_client_secret] ||= config.get('google_client_secret', profile: profile) ||
|
57
|
+
error('Missing config: google_client_secret')
|
58
|
+
|
59
|
+
# Cache temporary-session credentials in a separately-named profile.
|
60
|
+
# Stored credentials take priority over credential_process,
|
61
|
+
# so they would never be refreshed if stored in the same profile.
|
62
|
+
options[:profile] += '_session'
|
63
|
+
google = Aws::Google.new(options)
|
64
|
+
credentials = google.credentials
|
65
|
+
output = {
|
66
|
+
Version: 1,
|
67
|
+
AccessKeyId: credentials.access_key_id,
|
68
|
+
SecretAccessKey: credentials.secret_access_key,
|
69
|
+
SessionToken: credentials.session_token,
|
70
|
+
Expiration: Time.at(google.expiration.to_i).iso8601
|
71
|
+
}
|
72
|
+
require 'json'
|
73
|
+
puts output.to_json
|
data/lib/aws/google.rb
CHANGED
@@ -39,7 +39,7 @@ module Aws
|
|
39
39
|
# @option options [String] :online if `true` only a temporary access token will be provided,
|
40
40
|
# a long-lived refresh token will not be created and stored on the filesystem.
|
41
41
|
# @option options [String] :port port for local server to listen on to capture oauth browser redirect.
|
42
|
-
# Defaults to an out-of-band authentication process.
|
42
|
+
# Defaults to 1234. Set to nil or 0 to use an out-of-band authentication process.
|
43
43
|
# @option options [::Google::Auth::ClientId] :google_id
|
44
44
|
def initialize(options = {})
|
45
45
|
@oauth_attempted = false
|
@@ -56,7 +56,7 @@ module Aws
|
|
56
56
|
@client = options[:client] || Aws::STS::Client.new(credentials: nil)
|
57
57
|
@domain = options[:domain]
|
58
58
|
@online = options[:online]
|
59
|
-
@port = options[:port]
|
59
|
+
@port = options[:port] || 1234
|
60
60
|
|
61
61
|
# Use existing AWS credentials stored in the shared config if available.
|
62
62
|
# If this is `nil` or expired, #refresh will be called on the first AWS API service call
|
@@ -105,8 +105,18 @@ module Aws
|
|
105
105
|
credentials.tap(&storage.method(:write_credentials))
|
106
106
|
end
|
107
107
|
|
108
|
+
def silence_output
|
109
|
+
outs = [$stdout, $stderr]
|
110
|
+
clones = outs.map(&:clone)
|
111
|
+
outs.each { |io| io.reopen '/dev/null'}
|
112
|
+
yield
|
113
|
+
ensure
|
114
|
+
outs.each_with_index { |io, i| io.reopen(clones[i]) }
|
115
|
+
end
|
116
|
+
|
108
117
|
def get_oauth_code(client, options)
|
109
|
-
raise 'fallback' unless @port
|
118
|
+
raise 'fallback' unless @port && !@port.zero?
|
119
|
+
|
110
120
|
require 'launchy'
|
111
121
|
require 'webrick'
|
112
122
|
code = nil
|
@@ -123,26 +133,29 @@ module Aws
|
|
123
133
|
end
|
124
134
|
trap('INT') { server.shutdown }
|
125
135
|
client.redirect_uri = "http://localhost:#{@port}"
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
136
|
+
silence_output do
|
137
|
+
launchy = Launchy.open(client.authorization_uri(options).to_s)
|
138
|
+
server_thread = Thread.new do
|
139
|
+
begin
|
140
|
+
server.start
|
141
|
+
ensure server.shutdown
|
142
|
+
end
|
143
|
+
end
|
144
|
+
while server_thread.alive?
|
145
|
+
raise 'fallback' if !launchy.alive? && !launchy.value.success?
|
146
|
+
|
147
|
+
sleep 0.1
|
131
148
|
end
|
132
|
-
end
|
133
|
-
while server_thread.alive?
|
134
|
-
raise 'fallback' if !launchy.alive? && !launchy.value.success?
|
135
|
-
sleep 0.1
|
136
149
|
end
|
137
150
|
code || raise('fallback')
|
138
151
|
rescue StandardError
|
139
152
|
trap('INT', 'DEFAULT')
|
140
153
|
# Fallback to out-of-band authentication if browser launch failed.
|
141
154
|
client.redirect_uri = 'oob'
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
155
|
+
return ENV['OAUTH_CODE'] if ENV['OAUTH_CODE']
|
156
|
+
|
157
|
+
raise RuntimeError, 'Open the following URL in a browser to get a code,' \
|
158
|
+
"export to $OAUTH_CODE and rerun:\n#{client.authorization_uri(options)}", []
|
146
159
|
end
|
147
160
|
|
148
161
|
def refresh
|
@@ -176,7 +189,7 @@ module Aws
|
|
176
189
|
raise e, "\nYour Google ID does not have access to the requested AWS Role. Ask your administrator to provide access.
|
177
190
|
Role: #{@assume_role_params[:role_arn]}
|
178
191
|
Email: #{token_params['email']}
|
179
|
-
Google ID: #{token_params['sub']}",
|
192
|
+
Google ID: #{token_params['sub']}", []
|
180
193
|
end
|
181
194
|
|
182
195
|
c = assume_role.credentials
|
data/lib/aws/google/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aws-google
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Will Jordan
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-10-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk-core
|
@@ -70,30 +70,30 @@ dependencies:
|
|
70
70
|
name: bundler
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - "
|
73
|
+
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
75
|
+
version: '0'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- - "
|
80
|
+
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
82
|
+
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: minitest
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version:
|
89
|
+
version: 5.14.2
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version:
|
96
|
+
version: 5.14.2
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: mocha
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -153,7 +153,8 @@ dependencies:
|
|
153
153
|
description: Use Google OAuth as an AWS credential provider.
|
154
154
|
email:
|
155
155
|
- will@code.org
|
156
|
-
executables:
|
156
|
+
executables:
|
157
|
+
- aws-google
|
157
158
|
extensions: []
|
158
159
|
extra_rdoc_files: []
|
159
160
|
files:
|
@@ -166,6 +167,7 @@ files:
|
|
166
167
|
- aws-google.gemspec
|
167
168
|
- bin/console
|
168
169
|
- bin/setup
|
170
|
+
- exe/aws-google
|
169
171
|
- lib/aws/google.rb
|
170
172
|
- lib/aws/google/credential_provider.rb
|
171
173
|
- lib/aws/google/version.rb
|
@@ -189,8 +191,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
189
191
|
- !ruby/object:Gem::Version
|
190
192
|
version: '0'
|
191
193
|
requirements: []
|
192
|
-
|
193
|
-
rubygems_version: 2.7.4
|
194
|
+
rubygems_version: 3.1.2
|
194
195
|
signing_key:
|
195
196
|
specification_version: 4
|
196
197
|
summary: Use Google OAuth as an AWS credential provider
|