Skip to content

Commit

Permalink
Implement web identity credentials for irsa (#208)
Browse files Browse the repository at this point in the history
* Add support for AssumeRoleWebIdentityCredentials

This commit adds a web_identity_credentials config section and
handler for supporting IRSA.

Thus, we can use identity file within EKS.

Signed-off-by: Hiroshi Hatake <[email protected]>

* Add documentation for web_identity_credentials

Signed-off-by: Hiroshi Hatake <[email protected]>
  • Loading branch information
cosmo0920 authored Nov 2, 2020
1 parent 35ce739 commit 19cba46
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 0 deletions.
44 changes: 44 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,50 @@ It should be added to assume_role_credentials configuration stanza in the next f

STS API endpoint url. This can be used to override the default global STS API endpoint of sts.amazonaws.com. Using regional endpoints may be preferred to reduce latency, and are required if utilizing a PrivateLink VPC Endpoint for STS API calls.


### web_identity_credentials

Similar to the assume_role_credentials, but for usage in EKS.

<match *>
@type kinesis_streams

<web_identity_credentials>
role_arn ROLE_ARN
role_session_name ROLE_SESSION_NAME
web_identity_token_file AWS_WEB_IDENTITY_TOKEN_FILE
</web_identity_credentials>
</match>

See also:

* [Using IAM Roles - AWS Identity and Access Management](http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html)
* [IAM Roles For Service Accounts](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts-technical-overview.html)
* [Aws::STS::Client](http://docs.aws.amazon.com/sdkforruby/api/Aws/STS/Client.html)
* [Aws::AssumeRoleWebIdentityCredentials](https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/AssumeRoleWebIdentityCredentials.html)

**role_arn (required)**

The Amazon Resource Name (ARN) of the role to assume.

**role_session_name (required)**

An identifier for the assumed role session.

**web_identity_token_file (required)**

The absolute path to the file on disk containing the OIDC token

**policy**

An IAM policy in JSON format.

**duration_seconds**

The duration, in seconds, of the role session. The value can range from
900 seconds (15 minutes) to 43200 seconds (12 hours). By default, the value
is set to 3600 seconds (1 hour).

### instance_profile_credentials

Retrieve temporary security credentials via HTTP request. This is useful on EC2 instance.
Expand Down
25 changes: 25 additions & 0 deletions lib/fluent/plugin/kinesis_helper/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,20 @@ module ClientParams
desc "A URL for a regional STS API endpoint, the default is global"
config_param :sts_endpoint_url, :string, default: nil
end
# Refer to the following link for additional parameters that could be added:
# https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/STS/Client.html#assume_role_with_web_identity-instance_method
config_section :web_identity_credentials, multi: false do
desc "The Amazon Resource Name (ARN) of the role to assume"
config_param :role_arn, :string
desc "An identifier for the assumed role session"
config_param :role_session_name, :string
desc "The absolute path to the file on disk containing the OIDC token"
config_param :web_identity_token_file, :string, default: nil #required
desc "An IAM policy in JSON format"
config_param :policy, :string, default: nil
desc "The duration, in seconds, of the role session (900-43200)"
config_param :duration_seconds, :time, default: nil
end
config_section :instance_profile_credentials, multi: false do
desc "Number of times to retry when retrieving credentials"
config_param :retries, :integer, default: nil
Expand Down Expand Up @@ -149,6 +163,17 @@ def setup_credentials
credentials_options[:client] = Aws::STS::Client.new(region: @region)
end
options[:credentials] = Aws::AssumeRoleCredentials.new(credentials_options)
when @web_identity_credentials
c = @web_identity_credentials
credentials_options[:role_arn] = c.role_arn
credentials_options[:role_session_name] = c.role_session_name
credentials_options[:web_identity_token_file] = c.web_identity_token_file
credentials_options[:policy] = c.policy if c.policy
credentials_options[:duration_seconds] = c.duration_seconds if c.duration_seconds
if @region
credentials_options[:client] = Aws::STS::Client.new(:region => @region)
end
options[:credentials] = Aws::AssumeRoleWebIdentityCredentials.new(credentials_options)
when @instance_profile_credentials
c = @instance_profile_credentials
credentials_options[:retries] = c.retries if c.retries
Expand Down
49 changes: 49 additions & 0 deletions test/kinesis_helper/test_client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

require_relative '../helper'
require 'fluent/plugin/kinesis_helper/client'
require 'tempfile'

class KinesisHelperClientTest < Test::Unit::TestCase
class ProcessCredentials
Expand Down Expand Up @@ -56,6 +57,19 @@ def request_type
end
end

class MockWebIndentityCredentials
include Fluent::Plugin::KinesisHelper::Client
include Fluent::Configurable

def initialize
@region = 'us-east-1'
end

def request_type
:firehose
end
end

def self.startup
Aws::Firehose::Client.new(region: 'us-east-1')
end
Expand Down Expand Up @@ -104,6 +118,41 @@ def test_process_credentials_config_error
end
end

class WebIdentityCredentialsTest < self
def setup
sts = Aws::STS::Client.new(region: 'us-east-1', stub_responses: true)
Aws::STS::Client.stubs(:new).with(anything).returns(sts)
end

def test_web_identity_credentials
omit_if(Gem::Version.new(Aws::CORE_GEM_VERSION) < Gem::Version.new('3.65.0'))

Tempfile.open("kinesis-") do |token_file|
token_file.write("a token!")
token_file.flush

config = Fluent::Config::Element.new(
'ROOT', '', {'region' => 'us-east-1'}, [
Fluent::Config::Element.new('web_identity_credentials', '', {
'role_arn' => 'arn',
'web_identity_token_file' => token_file.path,
'role_session_name' => 'session-name',
}, [])
])
credentials = MockWebIndentityCredentials.new
credentials.configure(config)
creds = credentials.client.config.credentials
assert_true creds.is_a?(Aws::AssumeRoleWebIdentityCredentials)
expected_creds = Aws::AssumeRoleCredentials.new(
role_arn: 'arn',
web_identity_token_file: token_file.path,
role_session_name: 'session-name',
)
assert_equal expected_creds.client, creds.client
end
end
end

private

def setup_instance_profile(expiration = Time.now.utc + 3600)
Expand Down

0 comments on commit 19cba46

Please sign in to comment.