[Phase 2] Pass caller identity (RequestContext) through RPC dispatch pipeline #11
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#11
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
The current
rpc_handler()incrates/osis/src/rpc/server.rsdoes not extract or propagate caller identity from HTTP headers/request extensions. For auth enforcement at the OSIS level (ACL on contexts), handlers need to know WHO is making the request.Current State
rpc_handler()signature (server.rs:1667)No HTTP headers are extracted. No auth middleware exists in the Axum router built by
OServer.JsonRpcRequest(jsonrpc.rs)No auth/identity fields.
ACL module exists but is not wired
crates/osis/src/acl.rs(~820 lines) has:AclEntrywith circle/group resolutionRightsenum (Admin, Write, Read)check_access()logicProposed Changes
1. Add
RequestContextstruct2. Extract identity from request headers/extensions
In the
rpc_handler(), extract identity from:X-Proxy-User-Email,X-Proxy-Auth-MethodX-Public-Key,X-Signature,Authorization: Bearerrequest.extensions().get::<AuthContext>()3. Pass
RequestContextto CRUD handlersThe auto-generated CRUD method dispatch needs to receive
RequestContextso it can:before_create,before_update, etc.)4. Optional: Auth middleware layer
Add an optional auth middleware to the Axum router that validates signatures/tokens before the request reaches
rpc_handler(). This would complement (not replace) application-level auth like znzfreezone_backend'srpc_auth.rs.Design Considerations
RequestContextfields should beOptionso existing deployments without auth continue to workRelated
lhumina_code/hero_osis: ACL fields on Context type (separate issue)lhumina_code/hero_proxy: Identity header injection (separate issue)znzfreezone_code/znzfreezone_backendissue #29: Cross-context auth architectureznzfreezone_code/znzfreezone_backendrpc_auth.rs: Example of application-level RPC auth middlewareUpdate: Identity Comes from Proxy Headers
Following discussion on hero_proxy#8, authentication is moving to hero_proxy. The proxy verifies secp256k1 signatures at the edge and injects:
For the
RequestContextproposed in this issue, the primary extraction path becomes:The
rpc_handler()should extract these from HTTP headers (when behind hero_proxy) and pass them through to CRUD handlers and lifecycle hooks.API keys are being dropped in favor of keypair-only auth, so
RequestContextdoesn't need anapi_key_idfield.The trust model: hero_rpc trusts
X-Proxy-*headers because the connection from hero_proxy is via Unix socket. The proxy strips any externally-suppliedX-Proxy-*headers before injecting its own verified ones.Pass caller identity (RequestContext) through RPC dispatch pipelineto [Phase 2] Pass caller identity (RequestContext) through RPC dispatch pipelineImplementation: RequestContext through RPC dispatch pipeline
Implemented on the
developmentbranch. Here's a summary of the changes:New types (
crates/osis/src/rpc/request_context.rs)RequestContext— carries caller identity through the dispatch pipeline:caller_pubkey: Option<String>— fromX-Public-Keyor proxy headerscaller_email: Option<String>— fromX-Proxy-User-Emailbearer_token: Option<String>— fromAuthorization: Bearer <token>or JSON bodytokenfieldauth_method: AuthMethod— enum:None,Bearer,Signature,ProxyRequestContext::from_headers()— extracts identity from HTTP headersRequestContext::merge_from_json_params()— extractstokenfield from JSON-RPC body (WASM client path)All fields are
Option→ fully backwards compatibleChanges to dispatch pipeline
protocol.rsrequest_context: RequestContexttoRpcRequestserver.rs(HTTP handler)HeaderMap, buildsRequestContext, passes through dispatchdispatch.rsRequestContextunix_server.rsRequestContext::default()(anonymous) for raw UDSdomain_server.rsDispatchFntype,rpc_handler,domain_dispatchhandler.rshandle_request(&RpcRequest)gets context viaRpcRequestTrait extensions (backwards-compatible defaults)
OsisAppRpcHandler: Addedhandle_rpc_call_with_context()andhandle_service_call_with_context()— default implementations delegate to the existing methods, ignoring contextCustomMethodHandler::handle(): Addedrequest_context: &RequestContextparameterServerState::try_custom_method(): Now passesRequestContextthroughCode generator (
rust_osis.rs)Generated
RpcRequeststruct now includesrequest_context: hero_rpc_osis::rpc::RequestContext.All existing generated files updated.
Headers extracted
X-Public-Key/X-Proxy-User-Pubkeycaller_pubkeyX-Proxy-User-Emailcaller_emailAuthorization: Bearer <token>bearer_token+AuthMethod::BearerX-Proxy-Auth-MethodAuthMethod::ProxyX-SignatureAuthMethod::Signaturetokenfieldbearer_token(WASM client fallback)What's NOT in scope (as per the issue)
RequestContextfor auth (consumers opt in)Testing
cargo build --workspace✅cargo test --workspace --lib✅ (all 77 tests pass; 1 pre-existing failure in scaffold test)RequestContextunit tests pass (4 tests)Pushed as commit
d4d4b22on thedevelopmentbranch.