Skip to content

[helm] Enable SASL authentication configurations#2506

Open
morazow wants to merge 2 commits intoapache:mainfrom
morazow:mor-2503
Open

[helm] Enable SASL authentication configurations#2506
morazow wants to merge 2 commits intoapache:mainfrom
morazow:mor-2503

Conversation

@morazow
Copy link
Contributor

@morazow morazow commented Jan 28, 2026

Purpose

Linked issue: close #2503

Brief change log

Adds configuration options to Helm charts to enable SASL authentication.

Tests

API and Format

Documentation

Updated the deploying-with-helm documentation

@morazow morazow marked this pull request as ready for review January 29, 2026 11:09
@morazow morazow force-pushed the mor-2503 branch 6 times, most recently from ebf267c to 743acef Compare February 6, 2026 16:27
Copy link
Contributor

@affo affo left a comment

Choose a reason for hiding this comment

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

Thanks for the great job!
I think there is a bit of confusion 👍

I left many comments here and there, but let me wrap up my thoughts:

About the JAAS configuration, I think we can safely move the helper to directly template stringData into the secret and also remove all the clutter in the command section to avoid setting things there 👍

In general, I think the values provided are not enough: if INTERNAL does not have any SASL enabled, then FlussClient is not required to be configured, as Fluss needs to authenticate only if the internal listener is protected. I think this demands for a re-design of this feature 🤝

@morazow morazow requested a review from affo February 10, 2026 07:47
@morazow
Copy link
Contributor Author

morazow commented Feb 10, 2026

Hello @affo ,

Thanks for the review! Please have another look 🤝

Copy link
Contributor

@affo affo left a comment

Choose a reason for hiding this comment

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

Just a couple of nits 🤝

Copy link
Contributor

@affo affo left a comment

Choose a reason for hiding this comment

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

Looks good now 🚀

@swuferhong what do you think?

Copy link
Contributor

@xx789633 xx789633 left a comment

Choose a reason for hiding this comment

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

Hi @morazow thanks for the pull request. I left some comments.

@morazow
Copy link
Contributor Author

morazow commented Feb 17, 2026

Hello @xx789633, @affo

Thanks for the suggestions! Please have a look to the PR again.

I have identified two follow-up issues that need to be addressed separately.

  • Separate SASL communication for inter tablets and clients
  • Special character escaping

I will follow up with issues and PR for each.

[DONE] Separating SASL Communication

For this to work we would need to prefix the JAAS contents with listener name, for example:

internal.FlussServer {
    ...
}

But this does not work for the client, as on this line the client listener name is hard coded as null. So we will have to fix the core also and then enable separate SASL for inter tablets and clients in helm charts.

Special Character for SASL Usernames and Passwords

This is also indeed an issue, which requires core change for SASL client authentication.

Without escaping we would have something like below jaas.conf file:

root@coordinator-server-0:/opt/fluss# cat /etc/fluss/conf/jaas.conf

FlussServer {
   org.apache.fluss.security.auth.sasl.plain.PlainLoginModule required
   user_admin="pa$$wo\rd!@#%&""
   user_user1="5zFqhXGY0FgXzxUVpzRoA";
};

FlussClient {
   org.apache.fluss.security.auth.sasl.plain.PlainLoginModule required
   username="admin"
   password="pa$$wo\rd!@#%&"";
};

This fails on server with configuration error.

It should be correctly escaped as below:

FlussServer {
   org.apache.fluss.security.auth.sasl.plain.PlainLoginModule required
   user_admin="pa$$wo\\rd!@#%&\""
   user_user1="5zFqhXGY0FgXzxUVpzRoA";
};

FlussClient {
   org.apache.fluss.security.auth.sasl.plain.PlainLoginModule required
   username="admin"
   password="pa$$wo\\rd!@#%&\"";
};

But this again causes issues on client side since the SaslClientAuthenticator does not escape the user provided username and password.

This is the failing test for SaslAuthenticationITCase:

@Test
void testSpecialCharactersForPassword() throws Exception {
    final String specialPassword = "pa$$wo\\rd!@#%&\"";
    final Configuration clientConfig = new Configuration();
    clientConfig.setString("client.security.protocol", "sasl");
    clientConfig.setString("client.security.sasl.username", "admin");
    clientConfig.setString("client.security.sasl.password", specialPassword);
    testAuthentication(clientConfig, getDefaultServerConfig());
}

Since both of these points require changes to Fluss core packages, let's address them separately.

@morazow morazow requested review from affo and xx789633 February 17, 2026 08:13
@morazow
Copy link
Contributor Author

morazow commented Feb 17, 2026

Discussed offline with @affo, we don't have to worry about the prefixing the FlussClient block in JAAS configuration file, since there would be only one client for inter tablet communication 🤝

@morazow morazow force-pushed the mor-2503 branch 4 times, most recently from 05999c4 to f6d123b Compare February 19, 2026 12:30
@swuferhong
Copy link
Contributor

LGTM. @loserwang1024 Could you take a look at this PR?

port: 9123
security:
mechanism: PLAIN
users:
Copy link
Contributor

Choose a reason for hiding this comment

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

This is a bit confusing. Like Kafka, Fluss SASL authentication also does not require each listener to have unique usernames and passwords. Multiple listeners can share the SASL/PLAIN mechanism, but your example seems to suggest that client and internal listeners can enforce account isolation. How does this work?

Copy link
Contributor Author

@morazow morazow Feb 25, 2026

Choose a reason for hiding this comment

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

Hello @loserwang1024 👋 ,

Yes, indeed. It works because of the SASL listener prefix, JaasContext#126.

For example, with both internal and client SASL enabled, the following jaas file will be created:

$ root@coordinator-server-0:/opt/fluss# cat /etc/fluss/conf/jaas.conf

internal.FlussServer {
   org.apache.fluss.security.auth.sasl.plain.PlainLoginModule required
   "user_internal-hfpjhuc1gtbq"="yOxDGiWv4QD0XILF2KBlXoStM9ITavux";
};

client.FlussServer {
   org.apache.fluss.security.auth.sasl.plain.PlainLoginModule required
   "user_mtoraz"="passWA";
};

FlussClient {
   org.apache.fluss.security.auth.sasl.plain.PlainLoginModule required
   username="internal-hfpjhuc1gtbq"
   password="yOxDGiWv4QD0XILF2KBlXoStM9ITavux";
};

ZookeeperClient {
   org.apache.fluss.shaded.zookeeper3.org.apache.zookeeper.server.auth.DigestLoginModule required
   username="zk-admin"
   password="zk-password";
};

As you can see the FlussServers are prefixed for internal and client. The FlussClient doesn't have any prefix, but it is fine since here it acts as client only for the internal communications.

The to run the client jobs:

FLUSS_TEST_BOOTSTRAP=coordinator-server-0.coordinator-server-hs.fluss.svc.cluster.local:9124 \
FLUSS_TEST_USERNAME=mtoraz \
FLUSS_TEST_PASSWORD=passWA \
java -jar fluss-smoke-test-sasl.jar test

users can use the client username and password.

Copy link
Contributor

@affo affo left a comment

Choose a reason for hiding this comment

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

@morazow thanks for the work that you are putting in!
See comments 🤝

Set these values for additional configurations:

```yaml
listeners:
Copy link
Contributor

Choose a reason for hiding this comment

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

Before putting the focus on punctual comments, I would stop one second and think about the design of this.

I really like placing the security bit directly into the listener config, e.g.: listeners.internal.security.

However, I don't think that this schema:

internal:
  protocol: SASL
  security:
    mechanism: PLAIN
     users: []

Is actually the best way to proceed, given that different security protocols are going to require different keys to be provided. Just as an example, for SASL/OAUTHBEARER, users and password won't fit.

Given that every supported protocol will probably have different inputs, why not:

internal:
  security:
    saslPlain:
      ssl: false
      users: []
    saslScram: {}
    saslOAuthBearer: {}

So that every protocol can specify the required inputs without further validation?

@morazow @loserwang1024 what do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hey @affo ,

Yeah could be simpler, but I think will again complicate in other parts.

For example, for setting security map protocol or client security mechanism would require complex parsing logic:

echo "security.protocol.map: INTERNAL:<?>,CLIENT:<?>" >> $FLUSS_HOME/conf/server.yaml && \

Here for the question marks, we directly reference the Values.listener.<internal|client>.protocol, no we would need parsing logic to determine the protocol.

But let's think for user friendly and semi future proof design.

Co-authored-by: Lorenzo Affetti <lorenzo.affetti@gmail.com>
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.

[helm] Enable SASL authentication configurations

5 participants