diff --git a/README.md b/README.md index 7b80675..941a9f8 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,7 @@ Options: # Default: main [--access-key-id=ACCESS_KEY_ID] # The access key for connecting to S3. [--secret-access-key=SECRET_ACCESS_KEY] # The secret key for connecting to S3. + [--role-arn=ROLE_ARN] # The IAM role to assume for connecting to S3. (optional) [--s3-region=S3_REGION] # The region for connecting to S3. # Default: us-east-1 [--force-path-style], [--no-force-path-style] # Use S3 path style instead of subdomains. diff --git a/lib/deb/s3/cli.rb b/lib/deb/s3/cli.rb index 0176536..9b2fd3d 100644 --- a/lib/deb/s3/cli.rb +++ b/lib/deb/s3/cli.rb @@ -56,6 +56,10 @@ class Deb::S3::CLI < Thor :type => :string, :desc => "The secret key for connecting to S3." + class_option :role_arn, + :type => :string, + :desc => "The IAM role to assume for connecting to S3." + class_option :s3_region, :type => :string, :desc => "The region for connecting to S3.", @@ -579,14 +583,32 @@ class Deb::S3::CLI < Thor def configure_s3_client error("No value provided for required options '--bucket'") unless options[:bucket] - settings = { - :region => options[:s3_region], - :http_proxy => options[:proxy_uri], - :force_path_style => options[:force_path_style] - } - settings.merge!(provider) + if options[:role_arn] + # The below STS auth code is based on the example here: + # http://blog.jfabre.net/2016/02/28/aws-cross-account-role-ruby/ + sts = Aws::STS::Client.new( + access_key_id: provider[:access_key_id], + secret_access_key: provider[:secret_access_key], + region: options[:s3_region], + http_proxy: options[:proxy_uri] + ) + # With the STS client we can then instantiate the credentials with the Role we want to use + role_credentials = Aws::AssumeRoleCredentials.new( + client: sts, + role_arn: options[:role_arn], + role_session_name: 'temp' + ) + Deb::S3::Utils.s3 = Aws::S3::Client.new(credentials: role_credentials) + else + settings = { + :region => options[:s3_region], + :http_proxy => options[:proxy_uri], + :force_path_style => options[:force_path_style] + } + settings.merge!(provider) + Deb::S3::Utils.s3 = Aws::S3::Client.new(settings) + end - Deb::S3::Utils.s3 = Aws::S3::Client.new(settings) Deb::S3::Utils.bucket = options[:bucket] Deb::S3::Utils.signing_key = options[:sign] Deb::S3::Utils.gpg_options = options[:gpg_options]