-
-
Notifications
You must be signed in to change notification settings - Fork 519
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
Allow injecting authentication mechanisms #1101
Conversation
AuthenticationMechanisms are now exported from the top level, and allows users to add their own custom implementations as needed.
…b.com:tulios/kafkajs into 840-allow-injecting-authentication-mechanisms
Tested out and documented the typescript usage. The documentation has been updated accordingly. |
Couldn't get ESLint to use the Typescript parser for Typescript files and the default parser for JS files.
It seems this change has not had any updates and has not been merged in a while. @Nevon will this end up getting added? I'm going to be using Kerberos, so I could definitely use this... |
I think it should definitely end up getting added, as there are already several use-cases we know of where this is necessary (aws-iam-msk & kerberos), but since this is a public API that people will be building on top of, we have to make sure that the interface works and makes sense. I tried implementing aws-iam-msk authentication on top of this interface to test it out, and ran into some rough edges when using Typescript. It was a few weeks ago now, so the details a fussy, but from what I recall the issues were around making sure that if a user adds a new authentication mechanism, the options they pass in to import { Kafka, AuthenticationMechanisms, AuthenticationMechanism } from 'kafkajs'
import { MskIamMechanism } from './MskIamMechanism'
// Augmenting the SASLMechanismsOptionsMap with the new mechanism
declare module 'kafkajs' {
interface SASLMechanismOptionsMap {
AWS_MSK_IAM: {
credentialProvider: CredentialProvider
}
}
}
/**
* Here's the ugly part where in order to be able to actually add the custom authentication mechanism
* to the mechanisms, I have to cast AuthenticationMechanisms to my own custom type, which first
* requires casting to unknown. This has to be done by the user, which sucks, but it's the only way I've found
* that allows `sasl` to use the type provided by the custom mechanism.
*/
type ExtraAuthenticationMechanisms = AuthenticationMechanism & {
AWS_MSK_IAM: () => typeof MskIamMechanism
}
;(AuthenticationMechanisms as unknown as ExtraAuthenticationMechanisms)['AWS_MSK_IAM'] = () =>
MskIamMechanism
// On the bright side, now when I select `AWS_MSK_IAM` as a mechanism, it tells me I need to provide the
// "credentialProvider" property and what type it should have
const kafka = new Kafka({
brokers: [
'b-1.fake-test-broker.abc123.kafka.eu-north-1.amazonaws.com:9098',
],
ssl: true,
sasl: {
mechanism: 'AWS_MSK_IAM',
credentialProvider: defaultProvider(),
},
connectionTimeout: 5000,
}) My suggestion would be to attempt to implement Kerberos authentication on top of this interface, and then come back with concrete feedback on what worked well, what didn't, and what the user experience will be like. Maybe we can make some improvements to make it less of a hassle for the user. The current implementation should work just fine for the built-in authentication mechanisms, so as a pure refactor of the existing functionality, I consider it good enough. But before we cut a stable release containing this, I'd like to improve the interface. Maybe @tulios could help out with a review so that we can get this merged in the current state, and then refactor the plugin interface once we have some feedback to work from. |
I am wanting to run a few nodejs lambda's against a MSK Kafka with IAM auth enabled, so I am very interested in this pull request. I am wondering if a slightly different approach would make the new API slightly easier to type. Would it be possible to instead of using a JSON config, passing a instantiated const kafka = new Kafka({
brokers: [
'b-1.fake-test-broker.abc123.kafka.eu-north-1.amazonaws.com:9098',
],
ssl: true,
sasl: new AwsMSKIamMechanisim({ credentials } ),
connectionTimeout: 5000,
}) This would simplify the type definitions as you could do:
This concept is similar to how the aws elstaic search connector works, where you are allowed to override the |
Hello, I just have a question about this PR regarding the ability to implement a custom auth mechanism to set the username / password based on an async call. Our kafka servers have ssl in place but we need to retrieve the username / password from a vault since they cannot be stored in the stash repo, very similar to the way the "oauthBearer" option is implemented. Below would be a very crude idea (interface and type taken from the index.d.ts file). Would the above PR allow for this? Thank you.
|
Hi, any chance of this PR being merged? |
@Nevon I would like to use this feature ! :) |
This would be immensely useful |
Hi, @Nevon When can we expect this to be released? Thanks. |
bump |
I'm going to close this PR since it's not particularly useful at the moment. The branch will remain, in case someone wants to take a crack at reworking it. I spent some time last week trying to refactor it with a better interface, and also make the necessary adjustments from the changes to the Connection that are in master, but didn't finish. One thing to note about blacha's suggestion is that the authentication mechanism needs to expose a name that we can use in the protocol negotiation, so the |
Please keep the branch available, we’re using that branch already successfully in our project. 😬 Hope there will be a final solution someday in the main branch. 🤞 Thanks for your work here! |
That seems incredibly dangerous. I would suggest that you fork the repo so that you have your own copy of the branch, rather than rely on me not clicking that "Delete branch" button. |
FYI, @markgaylard has completed the work to allow custom authentication mechanisms and has raised a PR here: #1372 |
This is available now in a beta release. See #1372 (comment) for details. |
This allows users to inject their own custom authentication mechanisms, similar to what's done for compression codecs.
The existing authentication mechanisms use the same interface, which meant I had to rework them some. Primarily, I moved them from being classes to functions. This isn't strictly necessary, but I find it easier to have people implement a function than to have them extend a class or similar - especially if they are using different compile-to-js languages.
The other thing was that I changed the interface to not expose any internal classes. That means moving from Encoders/Decoders to just buffers, and to not pass in the Connection anymore, and instead provide the
sasl
options and the broker host + port.Fixes #840