Raghav Rajagopalan
03/31/2026, 11:42 PMRocky
03/31/2026, 11:43 PMRaghav Rajagopalan
03/31/2026, 11:53 PMRocky
03/31/2026, 11:59 PMfe/conf/fe.conf file and restarting the FE:
* jwt_jwks_url: The URL to the JSON Web Key Set (JWKS) service or the local path to your public key file.
* jwt_principal_field: The field in the JWT claim that represents the StarRocks username (e.g., sub or preferred_username).
* jwt_required_issuer (Optional): The expected issuer (iss) of the token.
* jwt_required_audience (Optional): The expected audience (aud) of the token.
Example `fe.conf`:
properties
jwt_jwks_url = <http://your-auth-server/protocol/openid-connect/certs>
jwt_principal_field = sub
2. Create a User with JWT Authentication
In StarRocks, you must create a user that is mapped to the identity provided in the JWT. The principal_field value in your token must match the username you create.
sql
-- Replace 'tom' with the value from the 'sub' field in your JWT
CREATE USER tom IDENTIFIED WITH authentication_jwt;
If you didn't set global configurations in fe.conf, you can specify them per user:
sql
CREATE USER tom IDENTIFIED WITH authentication_jwt AS
'{"jwks_url": "<http://your-auth-server/certs>", "principal_field": "sub"}';
3. Call the HTTP SQL API using the Bearer Token
Once the user is created and JWT is configured, you can call the HTTP SQL API by passing the token in the Authorization header as a Bearer token.
Endpoint: http://<fe_ip>:<fe_http_port>/api/v1/catalogs/default_catalog/databases/<db_name>/sql
Example using `curl`:
bash
curl -X POST 'http://<fe_ip>:8030/api/v1/catalogs/default_catalog/databases/test_db/sql' \
-H "Authorization: Bearer <your_jwt_token>" \
-H "Content-Type: application/json" \
-d '{"query": "SELECT * FROM my_table LIMIT 10;"}'
Important Notes:
* Compatibility: This feature requires v3.5.0+.
* Username Match: The value in the JWT's principal_field must exactly match the StarRocks username.
* No Password: Since the user is identified with authentication_jwt, no password is required or used for this account when authenticating via token.
References
• developers/code-style-guides/restful-api-standard.md
• sql-reference/http_sql_api.md
• administration/user_privs/authentication/jwt_authentication.md
• administration/user_privs/authentication/oauth2_authentication.md
• administration/http_interface.mdRaghav Rajagopalan
04/01/2026, 4:53 PMCREATE USER `system:serviceaccount:my-namespace:my-service-account-name`
IDENTIFIED WITH authentication_jwt AS '{
"jwks_url": "<https://oidc.eks.us-east-2.amazonaws.com/id/cluster-id/keys>",
"principal_field": "sub",
"required_issuer": "<https://oidc.eks.us-east-2.amazonaws.com/id/cluster-id>",
"required_audience": "<http://pods.eks.amazonaws.com|pods.eks.amazonaws.com>"
}';
I'm not able to create a user with this username however ( I believe the : character is special ). What can I do instead?Rocky
04/01/2026, 4:54 PM: is indeed a special character that is not currently permitted in StarRocks user identities.
Since the sub claim in Kubernetes OIDC tokens for service accounts follows the format system:serviceaccount:<namespace>:<name>, it cannot be used directly as a username in StarRocks.
Recommended Solution: Use a Different principal_field
EKS OIDC tokens typically include additional claims that provide the service account name without the full system:serviceaccount prefix. You can switch the principal_field to use one of these claims instead.
Common Kubernetes claims available in the token include:
• `kubernetes.io/serviceaccount/name`: Contains only the name of the service account (e.g., my-service-account-name).
• `kubernetes.io/serviceaccount/namespace`: Contains only the namespace (e.g., my-namespace).
How to update your configuration:
1. Create the user using only the service account name (or an underscored version):
sql
CREATE USER `my_service_account_name` -- Use underscores or just the name
IDENTIFIED WITH authentication_jwt AS '{
"jwks_url": "<https://oidc.eks.us-east-2.amazonaws.com/id/cluster-id/keys>",
"principal_field": "<http://kubernetes.io/serviceaccount/name|kubernetes.io/serviceaccount/name>", -- Use the specific name claim
"required_issuer": "<https://oidc.eks.us-east-2.amazonaws.com/id/cluster-id>",
"required_audience": "<http://pods.eks.amazonaws.com|pods.eks.amazonaws.com>"
}';
2. Note on Uniqueness: If you have multiple namespaces and need to ensure uniqueness, you'll need to be careful as StarRocks currently requires the principal_field value to match the username exactly and doesn't support regex transformation or claim concatenation (like namespace_name) within the JWT property itself. If this is a requirement, you might consider using a custom claim if you control the token generation, or using a unique naming convention for your service accounts across the cluster.
Alternative: Security Integration (v3.4+)
If you are on version 3.4 or later, you can also use Security Integration to manage JWT authentication globally, but the same naming restrictions apply to the "virtual users" or mapped users created during the login process.
Let me know if you have more questions about how to map these claims!
References
• administration/management/FE_configuration.md
• administration/user_privs/authentication/security_integration.mdRaghav Rajagopalan
04/02/2026, 4:20 PM{"status":"FAILED","code":"1","msg":"invalid Base64 input character: 46 (decimal)","message":"invalid Base64 input character: 46 . I'm making a request like:
curl -X PUT <http://localhost:8030/api/mydatabase/mytable/_stream_load> -H "Content-Type: application/json" -H "Authorization: Bearer $(cat /path/tojwt/file)" -d '{}' -vRocky
04/02/2026, 4:21 PMinvalid Base64 input character: 46 (decimal) occurs because the decimal value 46 corresponds to the dot character (.).
A JWT token consists of three parts separated by dots (header.payload.signature). When you send the header -H "Authorization: Bearer <JWT>", the StarRocks Front-End (FE) is likely attempting to parse this header using its default Basic Authentication handler. Basic Auth expects a Base64-encoded string (which does not contain dots), and when the decoder encounters a dot in your JWT, it throws this error.
Here are the reasons why this is happening and how to resolve it:
1. Version Requirement
StarRocks introduced support for JWT authentication in v3.5.0. If you are using a version earlier than v3.5.0, JWT is not supported, and the FE will only recognize Basic Authentication (username and password).
* Action: Check your StarRocks version using SELECT aurora_version(); or SHOW FRONTENDS;. If it's earlier than 3.5.0, you must use Basic Auth.
2. Stream Load Authentication Support
Even in v3.5.0+, JWT authentication is primarily supported for the MySQL protocol and specific HTTP interfaces (like the Web UI and JDBC over HTTP). The Stream Load API (/api/.../_stream_load) in many current implementations still expects Basic Authentication.
The standard way to authenticate a Stream Load request is via the -u flag in curl, which generates a Basic auth header:
bash
curl --location-trusted -u "username:password" -X PUT ...
3. JWT Configuration (v3.5.0+)
If you are on v3.5.0 or later and want to use JWT, ensure the following are correctly configured:
* FE Configuration: Your fe.conf must have JWT properties configured (e.g., jwt_jwks_url).
* User Creation: The user must be created with the JWT authentication method:
sql
CREATE USER 'your_user' IDENTIFIED WITH authentication_jwt;
* Principal Mapping: Ensure the sub (subject) claim in your JWT matches the StarRocks username exactly.
Recommendation
If you are trying to automate loading and want to avoid using a plaintext password:
1. Use Basic Auth: This is the most reliable method for Stream Load. You can pass the credentials via curl -u "user:pass".
2. Check for "Bearer" support: If you are on 3.5.0+, verify if your specific build supports Bearer tokens for the Stream Load endpoint. If the error persists, it indicates the endpoint is still defaulting to the Basic Auth parser.
3. Ensure no newlines: If you continue with the file approach, ensure the JWT file doesn't have hidden trailing newlines:
bash
# Use -n to avoid newlines if manually creating, or use $(cat ... | tr -d '\n')
-H "Authorization: Bearer $(cat /path/tojwt/file | tr -d '\n')"
Summary: The FE is misinterpreting your Bearer token as an invalid Basic auth string. For Stream Load, stick to Basic Authentication (-u username:password) unless you are on a version that explicitly documents Bearer support for the _stream_load endpoint.
References
• sql-reference/sql-functions/crytographic-functions/to_base64.md
• sql-reference/sql-functions/crytographic-functions/base64_decode_string.md
• sql-reference/sql-functions/crytographic-functions/from_base64.md
• sql-reference/sql-functions/crytographic-functions/base64_decode_binary.md
• sql-reference/sql-functions/bitmap-functions/base64_to_bitmap.md
• administration/Meta_recovery.mdRocky
04/02/2026, 4:21 PMRaghav Rajagopalan
04/02/2026, 4:53 PMcurl -X PUT <http://localhost:8030/api/mydatabase/mytable/_stream_load> -H "Content-Type: application/json" -u "your_user:$(cat /path/tojwt/file)" -d '{}' -v
When I do this, I get HTTP 401 Unauthorized, {"status":"FAILED","code":"1","msg":"Access
denied for your_user@127.0.0.1","message":"Access denied for
your_user@127.0.0.1"}Rocky
04/02/2026, 4:54 PM-u flag) for Stream Load.
Using -u "your_user:token" tells curl to send a Basic Authentication header (Authorization: Basic <base64>). StarRocks then interprets this as a standard username and literal password login. When you provide a JWT as the password, StarRocks fails to authenticate it because it expects a standard password hash comparison.
Starting from StarRocks v3.5.0, JWT authentication is supported for REST APIs (including Stream Load). To use it correctly, you should pass the token in the Authorization: Bearer header instead.
Recommended Steps:
1. Verify Version: Ensure you are using StarRocks v3.5.0 or later.
2. Create the User: The user must be created with the authentication_jwt method.
sql
CREATE USER your_user IDENTIFIED WITH authentication_jwt AS
'{
"jwks_url": "<http://your-auth-server/certs>",
"principal_field": "sub"
}';
_(Note: The principal_field in your JWT, typically sub, must match the StarRocks username your_user.)_
3. Correct curl Syntax: Use the -H "Authorization: Bearer ..." header and remove the -u flag.
bash
curl -X PUT "<http://localhost:8030/api/mydatabase/mytable/_stream_load>" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $(cat /path/tojwt/file)" \
-H "Expect: 100-continue" \
-T /path/to/data.json -v
Why you received the error:
* Version: If you are on a version earlier than v3.5.0, JWT authentication is not supported.
* Auth Type Mismatch: Even in v3.5.0+, the system expects the token in a Bearer header for REST APIs. When sent via -u, the backend tries to validate it as a standard password, which results in Access denied.
* Principal Match: Ensure the sub (or your configured principal_field) inside the JWT matches the username exactly.
References
• developers/code-style-guides/restful-api-standard.md
• administration/management/FE_configuration.md
• administration/user_privs/authentication/oauth2_authentication.md
• administration/management/BE_configuration.md
• best_practices/authentication_authorization.mdRaghav Rajagopalan
04/02/2026, 8:21 PM{"status":"FAILED","code":"1","msg":"Access denied for user \u0027tenant-user\u0027@\u0027%\u0027. Please ask the admin to grant permission(s) or try activating existing roles using \u003cset [default] role\u003e. Current role(s): []. Inactivated role(s): [root].","message":"Access denied for user \u0027tenant-user\u0027@\u0027%\u0027. Please ask the admin to grant permission(s) or try activating existing roles using \u003cset [default] role\u003e. Current role(s): []. Inactivated role(s): [root]."}
I did GRANT root to tenant-pipelineRocky
04/02/2026, 8:21 PMroot role has been granted to your user, it is currently inactivated by default. In StarRocks, simply granting a role doesn't always make it active automatically, especially for HTTP-based operations like Stream Load where you cannot manually run a SET ROLE command before the request.
To fix this, you need to set the root role as a default role for that user. This ensures the role is automatically activated whenever the user connects or sends a request.
Solution 1: Set the Default Role
Run the following SQL command (as a user with administrative privileges):
sql
-- Replace 'tenant-user'@'%' with the exact user identity from your error message
SET DEFAULT ROLE 'root' TO 'tenant-user'@'%';
Or using the ALTER USER syntax:
sql
ALTER USER 'tenant-user'@'%' DEFAULT ROLE 'root';
Solution 2: Activate all roles on login (Global)
If you want all users to have their granted roles automatically activated upon login without having to set default roles individually, you can change this global setting:
sql
SET GLOBAL activate_all_roles_on_login = TRUE;
Why this happens:
* Inactivated Roles: StarRocks allows a user to have many roles, but only "Default Roles" are active at the start of a session.
* Stream Load: Since Stream Load is a single HTTP request, it relies on the user's default configuration. If the required permissions (like INSERT) are inside a role that isn't set as default, the request will fail with "Access denied."
Note: Based on your error message, ensure you are granting the role to the correct user identity. Your error mentions tenant-user while your command mentioned tenant-pipeline. Make sure they match!
References
• faq/loading/Stream_load_faq.md
• administration/user_privs/authorization/privilege_faq.md
• administration/user_privs/authorization/user_privs.md
• administration/user_privs/authorization/User_privilege.md
• loading/StreamLoad.md
• sql-reference/sql-statements/account-management/SET_DEFAULT_ROLE.mdRaghav Rajagopalan
04/30/2026, 10:03 PMjti as principal as it's at the top-level of the claim:
CREATE USER `jti-uuid`
IDENTIFIED WITH authentication_jwt AS '{
"jwks_url": "<https://oidc.eks.us-east-2.amazonaws.com/id/cluster-id/keys>",
"principal_field": "jti",
"required_issuer": "<https://oidc.eks.us-east-2.amazonaws.com/id/cluster-id>",
"required_audience": "starrocks"
}';
I get the same illegal base64 decimal character error.
When I parse out the second part of the token by doing: curl <http://mystarrockscluster:8030/api/catalogs/default_catalog/databases/yipyip/sql> -H "Content-Type: application/json" -H "Authorization: Bearer $(cat /var/run/secrets/tokens/starrocks/starrocks-token | cut -d. -f2)" -H "Content-Type: application/json" -d '{"query": "SELECT * FROM mytable LIMI
T 10;"}' -v
I get:
:"Access denied for {\"aud\"@192.168.87.73","message":"Access denied for {\"aud\"@192.168.87.73"}Rocky
04/30/2026, 10:03 PMAuthorization: Bearer header.
Based on the errors you're seeing and the current implementation of the StarRocks HTTP SQL API, here is what’s happening and how to fix it:
The Problem
The Authorization: Bearer scheme is not natively supported by the StarRocks HTTP SQL endpoint (/api/v1/.../sql) in a way that automatically extracts the principal from the JWT. Currently:
1. The "illegal base64" error: When you send a full JWT (header.payload.signature), the dots (.) in the token are causing the FE's header decoder to fail, as it expects a standard base64 string.
2. The "Access denied for {JSON}" error: When you manually extracted the payload (cut -d. -f2), StarRocks successfully decoded the base64 part but treated the entire resulting JSON string as the StarRocks username. It did not extract the jti claim because it isn't treating that header as a JWT; it's treating it like an opaque identity string.
The Solution: Use Basic Auth with the JWT as the Password
To use JWT authentication with the HTTP SQL API, you should use the Basic Authentication format. In StarRocks, when a user is created with IDENTIFIED WITH authentication_jwt, the FE expects the full JWT token to be passed as the password for that specific user.
1. Verify your User Setup
Ensure the StarRocks username matches the value of the jti claim in your token.
sql
CREATE USER `jti-uuid`
IDENTIFIED WITH authentication_jwt AS '{
"jwks_url": "<https://oidc.eks.us-east-2.amazonaws.com/id/cluster-id/keys>",
"principal_field": "jti",
"required_issuer": "<https://oidc.eks.us-east-2.amazonaws.com/id/cluster-id>",
"required_audience": "starrocks"
}';
2. Correct curl Command
Pass the username and the full token (with all three parts) using the -u flag. curl will automatically format this into a Basic auth header.
bash
# Get the full token
TOKEN=$(cat /var/run/secrets/tokens/starrocks/starrocks-token)
# Use Basic Auth: -u 'username:password' where password is the full JWT
curl -X POST "<http://mystarrockscluster:8030/api/v1/catalogs/default_catalog/databases/yipyip/sql>" \
-H "Content-Type: application/json" \
-u "jti-uuid:$TOKEN" \
-d '{"query": "SELECT * FROM mytable LIMIT 10;"}'
Key Requirements
* Full Token: Do not cut the token. Use the entire string: header.payload.signature.
* Username Mapping: The username provided in the -u flag (jti-uuid) must exactly match the value inside the jti claim of the JWT you are providing.
* FE Config: If you are using a custom principal_field globally, make sure jwt_principal_field is set correctly in your fe.conf, though the CREATE USER ... AS '{...}' syntax you used overrides this for that specific user.
If you continue to see the "illegal base64" error even when using -u, ensure your token doesn't contain unusual trailing whitespace or hidden characters from the cat command. Using echo -n or ensuring the environment variable is clean can help.
References
• administration/user_privs/authentication/jwt_authentication.md
• sql-reference/http_sql_api.md
• administration/user_privs/authentication/security_integration.md