Search before asking
Motivation
Middle-tier services (gateways, web consoles, query services) often connect to Fluss with their own service credentials but need to run operations on behalf of end users, so that ACLs are evaluated against the end user rather than the service account. This "impersonation" (a.k.a. doAs / proxy user) capability is standard in comparable systems: Hadoop proxy user, Hive doAs, Pulsar originalPrincipal, Trino impersonation.
The SASL/PLAIN protocol (RFC 4616) already carries this semantic natively via the optional authorization id:
message = [authzid] UTF8NUL authcid UTF8NUL passwd
Fluss currently parses the authorization id in PlainSaslServer.evaluateResponse() but unconditionally rejects any value different from the authenticated username, and the client hard-codes it to null in SaslServerFactory.createSaslClient(). The rest of the plumbing is already in place: SaslServerAuthenticator.createPrincipal() builds the principal from saslServer.getAuthorizationID().
Solution
Enable the RFC 4616 authorization id end-to-end, gated by an explicit server-side allowlist. No wire protocol change, no new SPI.
Client: new config option client.security.sasl.authorization-id (String, no default). When set, it is passed to Sasl.createSaslClient(...) and the JDK PlainClient encodes it per RFC 4616. When unset, the bytes on the wire are identical to today.
Server: allow authzid != authcid only if granted via a JAAS option on PlainLoginModule, consistent with the existing user_<name> style:
security.sasl.plain.jaas.config: |
org.apache.fluss.security.auth.sasl.plain.PlainLoginModule required
user_admin="admin-pass"
user_gateway="gw-pass"
user_alice="alice-pass"
impersonate_admin="*" # admin may impersonate any user
impersonate_gateway="alice,bob"; # gateway may only impersonate alice/bob
-
If the check passes, the effective principal becomes the authorization id, and an INFO log records the impersonation for auditing. All downstream ACL checks apply to the effective principal, matching the existing createPrincipal() behavior.
-
If impersonate_<authcid> is not configured, the request is rejected exactly as today — fully backward compatible, and impersonation cannot be enabled from the client side alone.
-
The impersonator must still present its own valid password; the authorization id does not weaken authentication. Docs will keep the existing recommendation to use TLS with SASL/PLAIN.
Out of scope (possible follow-ups, would need a FIP): exposing original/effective principal on Session, an IMPERSONATE ACL operation type, and impersonation for future non-PLAIN mechanisms.
Anything else?
No response
Willingness to contribute
Search before asking
Motivation
Middle-tier services (gateways, web consoles, query services) often connect to Fluss with their own service credentials but need to run operations on behalf of end users, so that ACLs are evaluated against the end user rather than the service account. This "impersonation" (a.k.a. doAs / proxy user) capability is standard in comparable systems: Hadoop proxy user, Hive doAs, Pulsar originalPrincipal, Trino impersonation.
The SASL/PLAIN protocol (RFC 4616) already carries this semantic natively via the optional authorization id:
Fluss currently parses the authorization id in
PlainSaslServer.evaluateResponse()but unconditionally rejects any value different from the authenticated username, and the client hard-codes it tonullinSaslServerFactory.createSaslClient(). The rest of the plumbing is already in place:SaslServerAuthenticator.createPrincipal()builds the principal fromsaslServer.getAuthorizationID().Solution
Enable the RFC 4616 authorization id end-to-end, gated by an explicit server-side allowlist. No wire protocol change, no new SPI.
Client: new config option
client.security.sasl.authorization-id(String, no default). When set, it is passed toSasl.createSaslClient(...)and the JDKPlainClientencodes it per RFC 4616. When unset, the bytes on the wire are identical to today.Server: allow
authzid != authcidonly if granted via a JAAS option onPlainLoginModule, consistent with the existinguser_<name>style:If the check passes, the effective principal becomes the authorization id, and an INFO log records the impersonation for auditing. All downstream ACL checks apply to the effective principal, matching the existing
createPrincipal()behavior.If
impersonate_<authcid>is not configured, the request is rejected exactly as today — fully backward compatible, and impersonation cannot be enabled from the client side alone.The impersonator must still present its own valid password; the authorization id does not weaken authentication. Docs will keep the existing recommendation to use TLS with SASL/PLAIN.
Out of scope (possible follow-ups, would need a FIP): exposing original/effective principal on
Session, anIMPERSONATEACL operation type, and impersonation for future non-PLAIN mechanisms.Anything else?
No response
Willingness to contribute