Niranjan Kulkarni
04/12/2026, 9:28 AMRocky
04/12/2026, 9:33 AMIDENTIFIED WITH clauses for a single user record, and the authentication_chain has specific restrictions that prevent the fallback behavior you're looking for.
Why the authentication_chain doesn't work here
There are two main reasons your testing showed the fallback isn't happening:
1. Precedence: As you noticed, StarRocks prioritizes local users. If a user exists in the system (e.g., created via CREATE USER), StarRocks strictly follows the authentication method defined for that specific user identity (username@'host') and will never fall back to the authentication_chain.
2. OAuth2 Isolation: Even if you removed the local user and tried to use SECURITY INTEGRATION, StarRocks has a documented limitation: You cannot specify an OAuth 2.0 security integration alongside any other security integration in the authentication_chain. If OAuth2 is in the chain, it must be the only external method.
──────────
The Recommended Workaround: Host-Specific User Identities
Since StarRocks identifies users by the combination of username and host (the user_identity), you can create two separate identities for the same logical user. StarRocks matches the most specific host first.
If your Portal backend (Node.js) connects from a known IP range, you can differentiate the flows like this:
1. Create the JWT user for the Backend
Specify the specific IP or subnet where your Node.js app resides.
sql
CREATE USER 'my_user'@'10.0.0.5' -- Replace with your backend IP/subnet
IDENTIFIED WITH authentication_jwt AS '{
"jwks_url": "<https://login.microsoftonline.com/common/discovery/v2.0/keys>",
"principal_field": "sub",
"required_issuer": "<https://sts.windows.net/YOUR_TENANT_ID/>",
"required_audience": "YOUR_CLIENT_ID"
}';
2. Create the OAuth2 user for DBeaver/Clients
Use the wildcard host (%) for general access via the browser flow.
sql
CREATE USER 'my_user'@'%'
IDENTIFIED WITH authentication_oauth2 AS '{
"auth_server_url": "...",
"token_server_url": "...",
"client_id": "...",
...
}';
3. Sync Permissions via Roles
To ensure the user has the same permissions regardless of how they logged in, grant them the same roles:
sql
GRANT ROLE 'analyst_role' TO 'my_user'@'10.0.0.5';
GRANT ROLE 'analyst_role' TO 'my_user'@'%';
Why this works:
* When the Node.js app connects from 10.0.0.5, StarRocks finds the exact match (my_user'@'10.0.0.5') and triggers the JWT handshake.
* When a user connects from their laptop via DBeaver, they won't match the backend IP, so they fall through to the wildcard match (my_user'@'%'), which triggers the OAuth2 browser redirect.
Summary of Constraints
* One Method per Identity: Each username@'host' pair is locked to one plugin.
* MySQL Protocol limitation: The authentication plugin is negotiated at the start of the handshake. The server must tell the client which plugin to use (JWT vs OAuth2) before it knows what the client is capable of, which is why it relies on the user identity lookup.
References
• administration/management/FE_configuration.md
• administration/user_privs/authentication/oauth2_authentication.md
• administration/user_privs/authentication/jwt_authentication.md