Skip to content

Distributed cluster queries with interserver secret fail for JWT-authenticated users #2105

Description

@BorisTyshkevich

Summary

A query against a Hybrid table fails for an OAuth/JWT-authenticated user, although the same user can query each source independently. The failure is an internal native-TCP remote hop, not an HTTP client or SQL Browser failure.

Downstream report: Altinity/altinity-sql-browser#363

Environment

  • ClickHouse: 26.3.10.20001.altinityantalya
  • Authentication: jwt_dynamic_jwks (the user and oauth_demo_role are resolved from the presented JWT)
  • Hybrid base segment: cluster('{cluster}', ontime.fact_ontime)
  • The configured remote_servers cluster has an interserver <secret>
  • The OAuth role has SELECT on both sources and READ ON REMOTE
  • The outbound host allowlist permits the cluster peer and Iceberg endpoints

Reproduction

  1. Authenticate over HTTP with a valid OAuth/JWT identity that receives oauth_demo_role.
  2. Run a query on the Hybrid table, for example:
SELECT
    Carrier,
    count() AS flights,
    round(100 * countIf(ArrDel15 = 0) / count(), 1) AS on_time_pct
FROM ontime.fact_ontime_hybrid
WHERE Year >= 2012 AND Carrier = 'WN'
GROUP BY Carrier
ORDER BY on_time_pct DESC;
  1. The query returns partial progress, then fails with:
Code: 210. DB::Exception: Connection reset by peer ... While executing Remote

The server log for the corresponding internal connection shows:

Authentication failed: Code: 192: There is no user '<JWT subject>' in `token`
TCPHandler: Code: 516 ... authentication failed

Control tests

All queries below succeeded for a temporary static user whose only role was oauth_demo_role:

  • direct ontime.fact_ontime
  • cluster('antalya', ontime.fact_ontime)
  • ontime.fact_ontime_hybrid

The temporary user was deleted after testing. This rules out the Hybrid query plan, source-table permissions, READ ON REMOTE, and the remote host filter.

Expected behavior

The internal Distributed/Hybrid connection should be able to execute under the JWT-authenticated initiator identity, or ClickHouse should provide a supported secure way to delegate that identity/role to the internal hop.

Actual behavior

The internal native connection carries an initial username but not the JWT. The receiving server attempts to resolve that username in the token context and fails, causing the outer query to surface only a generic network error.

Impact

This prevents OAuth/JWT users from querying Hybrid tables whose native segment uses cluster(), despite having the necessary role grants.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions