Skip to content

[Feature] Support SASL/SCRAM-SHA-256 authentication for Fluss RPC #3881

Description

@litiliu

Search before asking

  • I searched in the issues and found nothing similar.

Motivation

Fluss currently supports built-in SASL/PLAIN authentication, and #3495 tracks SASL/OAUTHBEARER for deployments backed by OAuth2/OIDC. However, some deployments need password-based authentication without operating an external identity provider, while avoiding the weaknesses of sending the password in the SASL exchange and keeping recoverable plaintext credentials on the server.

SCRAM-SHA-256, standardized by RFC 7677, provides a salted challenge-response flow:

  • The client proves possession of the password without transmitting the password.
  • The server can store a salt, iteration count, StoredKey, and ServerKey instead of a recoverable plaintext password.
  • Client and server nonces provide replay resistance.
  • The client verifies the server signature, providing mutual authentication.

This would complement the existing PLAIN mechanism and the planned OAUTHBEARER mechanism. It is also useful for the Helm security configuration discussed in #2503, which already anticipates SCRAM as a selectable mechanism but currently has no native Fluss RPC implementation.

Solution

Add SCRAM-SHA-256 as a built-in SASL mechanism for the native Fluss RPC authentication layer.

Client-side example:

client.security.protocol=SASL
client.security.sasl.mechanism=SCRAM-SHA-256
client.security.sasl.username=user
client.security.sasl.password=secret

Server-side example:

security.protocol.map=CLIENT:SASL
security.sasl.enabled.mechanisms=SCRAM-SHA-256

Proposed implementation direction:

  • Build on the mechanism-extensible SASL foundation in [security] Make SASL mechanisms extensible #3865.
  • Implement connection-local SCRAM client and server sessions using the existing RPC authentication token/challenge exchange. The multi-round SCRAM handshake should not require a protobuf change.
  • Introduce a server-side SCRAM credential representation containing the username, salt, iteration count, StoredKey, and ServerKey. The server should not require a recoverable plaintext password for authentication.
  • Define a minimal bootstrap/configuration path for precomputed SCRAM credentials. Dynamic credential management or an external credential-provider SPI can be evaluated separately if it would significantly expand the first PR.
  • Preserve existing SASL/PLAIN behavior, configuration, and compatibility.
  • Create the effective FlussPrincipal only after the client proof has been verified.
  • Use TLS as the transport-security layer. SCRAM-SHA-256-PLUS channel binding can be handled separately.

Suggested test coverage:

  • Successful authentication and server-signature verification.
  • Wrong password, unknown user, invalid proof, malformed messages, and nonce mismatch.
  • Replay attempts using an old proof/nonce.
  • Salt and iteration-count handling.
  • Independent state for concurrent connections.
  • Regression coverage confirming that PLAIN remains unchanged.

Initial scope:

  • Support only the standards-track SCRAM-SHA-256 mechanism.
  • Do not add SCRAM-SHA-1, SCRAM-SHA-256-PLUS, or other SCRAM variants in the first version.
  • Default the authorization identity to the authenticated identity. Extending the impersonation behavior from Support impersonation via SASL/PLAIN authorization id #3837 to SCRAM can be considered separately.

Anything else?

Related work:

Willingness to contribute

  • I'm willing to submit a PR!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions