bug: OpenRPC UDS transport drops X-Hero-Context and X-Hero-Claims headers #42
Labels
No labels
prio_critical
prio_low
type_bug
type_contact
type_issue
type_lead
type_question
type_story
type_task
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
lhumina_code/hero_rpc#42
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
While investigating
hero_bizissue #37, a fundamental issue was discovered inhero_rpc'sOsisClientandOpenRpcTransportthat breaks context selection across the Hero OS ecosystem.Root Causes
1. URL Path Construction (Layer 1)
OsisClient::new(Native) andendpoint(WASM) incorrectly construct the RPC endpoint using legacy per-domain or context-prefixed paths (e.g.,{base_url}/hero_osis_{domain}/rpc).Requirement: Per
hero_contextand the Unified OSIS Server model, the endpoint must be a simple{base_url}/rpc. Routing is handled via method prefixes and theX-Hero-Contextheader.2. Header Forwarding on UDS (Layer 2)
The
OpenRpcTransportimplementation for Unix Domain Sockets (UDS) was found to drop HTTP headers. A comment intransport.rsstated: "Unix-socket transport currently drops the headers — raw socket framing has no place to carry them".Correction: Since we use HTTP-over-UDS, we can and must carry headers like
X-Hero-ContextandX-Hero-Claimsin the HTTP request framing over the socket. These headers are mandatory for context isolation and claim-based authorization.Impact
All services using
hero_rpcfor context-aware OSIS calls are currently failing to transmit the context selector to the server, resulting in "silent" failures where all contexts return the same (default) data.Proposed Fix
http_post_unixandpost_raw_json_with_headersincrates/openrpc/src/transport.rsto correctly attach headers to thehyper::Request.OsisClientincrates/openrpc_http_client_lib/src/lib.rsto default to the/rpcendpoint.This is a breaking change for services expecting the legacy path, but it is necessary for alignment with the
hero_contextspecification.@despiegk Can you check this? Is this something I should fix or just keep a local patch for hero_biz?
Correction based on Timur's clarification
After discussing with Timur, Layer 1 of this issue is incorrect — the per-domain socket paths are not legacy, they are intentional architecture.
What the per-domain paths actually are
OSIS is a single backend server that handles many distinct data domains (calendar, contacts, business, messaging, etc.). Because each domain has dozens of its own RPC methods, a single shared OpenRPC spec would easily reach 3000+ methods, making it unworkable for AI tooling and hard to navigate. Kristof specifically designed OSIS to bind one socket per domain (e.g.
hero_osis_business/rpc,hero_osis_calendar/rpc) so that:This is current, active architecture — not a legacy pattern to be removed.
What WAS legacy (and already fixed)
The actual legacy pattern was encoding context in the socket path, e.g.
hero_osis_business_threefold/rpc. That approach was abandoned because it required re-binding every service to a new socket for each context, which was architecturally unsound. The replacement — passing context via theX-Hero-ContextHTTP header — was already implemented in commited6e7eb3c0(feat(OsisClient): per-domain URL routing + X-Hero-Context header).I had confused domain-in-path (still correct) with context-in-path (was legacy, already removed).
What remains as a real bug
Layer 2 — Header Forwarding on UDS is the actual issue to investigate. The
X-Hero-Contextheader must survive the Unix Domain Socket transport hop. If the hyper-over-UDS transport is stripping custom headers before the request reaches the OSIS server, context selection will silently fail regardless of how the URL is constructed. Timur is currently checking this.Updated scope
This issue should be scoped to Layer 2 only: verify and fix that
X-Hero-Context(andX-Hero-Claims) are correctly forwarded through the UDS transport incrates/openrpc/src/transport.rs.bug/arch: OsisClient constructs wrong URL and transport drops headers on UDSto bug: OpenRPC UDS transport drops X-Hero-Context and X-Hero-Claims headersExact fix required (confirmed by reading the code)
Repo:
lhumina_code/hero_rpc— filecrates/openrpc/src/transport.rsThe bug
post_raw_json_with_headers(line 216) acceptsextra_headers: &[(&str, &str)]and correctly applies them when the transport is HTTP. But when the transport isUnixSocket, it callshttp_post_unixwithout passing the headers — they are silently dropped:http_post_unix(line 354) has no headers parameter and builds a hardcodedhyper::Requestwith onlyContent-TypeandHost.call_unix_http(line 331) also callshttp_post_unixdirectly with no headers.Exact changes needed
1. Add
extra_headersparameter tohttp_post_unix:2. Apply them in the
Request::builder()chain insidehttp_post_unix:3. Update the
UnixSocketbranch inpost_raw_json_with_headersto pass headers through:4. Update
call_unix_http(line 331) to pass empty headers:No other files need to change. The public API of
post_raw_json_with_headersstays the same — callers already pass headers there, they just never reached the socket.