Skip to content

Adding support for AWS MSK IAM authentication for rdkafka2 - #537

Open
madebydna wants to merge 1 commit into
fluent:masterfrom
madebydna:aws_msk_iam_support
Open

Adding support for AWS MSK IAM authentication for rdkafka2#537
madebydna wants to merge 1 commit into
fluent:masterfrom
madebydna:aws_msk_iam_support

Conversation

@madebydna

@madebydna madebydna commented Sep 12, 2025

Copy link
Copy Markdown

This adds support for using MSK IAM authentication with the rdkafka2 output type. Authentication and authorization with an MSK cluster are facilitated through a base64-encoded signed URL, which is generated by the aws-msk-iam-sasl-signer-ruby library.

Fixes #522

Signed-off-by: Andrea Singh <info@madebydna.com>
@github-actions

Copy link
Copy Markdown

This PR has been automatically marked as stale because it has been open 90 days with no activity. Remove stale label or comment or this PR will be closed in 30 days

@github-actions github-actions Bot added the stale label Dec 11, 2025
@Watson1978 Watson1978 removed the stale label Dec 12, 2025
@Watson1978
Watson1978 self-requested a review December 12, 2025 05:42
@github-actions

Copy link
Copy Markdown

This PR has been automatically marked as stale because it has been open 90 days with no activity. Remove stale label or comment or this PR will be closed in 30 days

@github-actions github-actions Bot added the stale label Mar 12, 2026
@github-actions

Copy link
Copy Markdown

This PR was automatically closed because of stale in 30 days

@github-actions github-actions Bot closed this May 28, 2026
@Watson1978 Watson1978 reopened this May 29, 2026
@Watson1978 Watson1978 removed the stale label May 29, 2026
@github-actions

Copy link
Copy Markdown

This PR has been automatically marked as stale because it has been open 90 days with no activity. Remove stale label or comment or this PR will be closed in 30 days

@github-actions github-actions Bot added the stale label Aug 27, 2026
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('3.0')
gem.add_dependency 'aws-msk-iam-sasl-signer', '~> 0.1.1'
end
end

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reading ENV and RUBY_VERSION in the gemspec makes the published gem's dependencies depend on how the release was built.
If USE_RDKAFKA is not set at release time, aws-msk-iam-sasl-signer is not declared, but out_rdkafka2.rb requires it unconditionally, so the plugin fails with LoadError for every user on Ruby 3.0+.
If it is set, rdkafka becomes a hard runtime dependency for everyone, which contradicts the README ("You need to install rdkafka gem") since it is an optional C extension.
Could we keep the rdkafka line in the Gemfile and declare neither gem in the gemspec?
Wrapping the require in begin/rescue PLoadErrorand raising aConfigError` only when MSK IAM is actually configured would match how rdkafka itself is already handled.

Comment on lines +23 to +25
if Gem::Version.create(RUBY_VERSION) >= Gem::Version.create('3.0')
require 'aws-msk-iam-sasl-signer'
end

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This require is not guarded, and aws-msk-iam-sasl-signer is not a dependency of the released gem, so out_rdkafka2 cannot be loaded at all on Ruby 3.0+ unless the user happens to have that gem installed.
On the PR HEAD, ruby -Ilib -e 'require "fluent/plugin/out_rdkafka2"' fails with LoadError: cannot load such file -- aws-msk-iam-sasl-signer.
This breaks users who do not use MSK IAM at all, so it is a regression for existing rdkafka2 users.
CI does not catch it because have_rdkafka in test_out_rdkafka2.rb rescues LoadError and omits the whole suite.
Could we wrap it in begin/rescue LoadError and raise a ConfigError only when MSK IAM is actually configured, the same way the optional rdkafka gem is already handled?

begin
  require 'aws-msk-iam-sasl-signer'
rescue LoadError
end

Comment on lines +308 to +312
def refresh_token(_config, _client_name)
log.info("+--- Refreshing token")
client = get_producer
# This will happen once upon initialization and is expected to fail, as the producer isnt set yet
# We will set the token manually after creation and after that this refresh method will work

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

refresh_token calls get_producer, which takes @producers_mutex, but rdkafka's NativeKafka#start runs an initial rd_kafka_poll on the calling thread, so the token refresh callback fires while that same thread already holds the mutex.
With the default share_producer false, Ruby's Mutex is not reentrant, so every write fails with ThreadError: deadlock; recursive locking.

The README says share_producer true is required, but nothing enforces it and the default is false.
Could configure() raise a ConfigError when OAUTHBEARER is configured without share_producer true?

log.info("Could not get shared client handle, unable to set/refresh token (this is expected one time on startup)")
return
end
signer = AwsMskIamSaslSigner::MSKTokenProvider.new(region: @aws_msk_region)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

generate_auth_token raises on transient AWS failures (missing credentials, STS throttling, network errors) instead of returning nil, and refresh_token has no rescue.

After startup the callback runs on rdkafka's polling thread, which sets abort_on_exception = true, so one failed refresh takes the process down.
Because the signer raises rather than returning nil, the else branch that calls oauthbearer_set_token_failure is never reached.
Could we wrap the body in begin/rescue and report the error via client.oauthbearer_set_token_failure(e.message) so librdkafka can retry?

@Watson1978 Watson1978 removed the stale label Aug 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add support for MSK IAM authentication in rdkafka2 output type

2 participants