Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement web identity credentials for irsa #208

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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