feat: authenticate cast RPC calls with x-internal-service-secret header - #377
Merged
Conversation
Adds an optional RPC_HEADER_SECRET env var to the multichain deploy scripts, sent as the x-internal-service-secret header on cast preflight calls so they can be authenticated against internal RPC providers. forge script (simulation/broadcast) can't carry the header — Foundry builds its fork/ broadcast RPC provider directly from the URL with no header support. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
forge test's vm.createSelectFork builds its RPC provider straight from the URL with no way to attach custom headers, so the integration suite started 401ing once the RPC gateway began requiring x-internal-service-secret on every request (cast's native --rpc-headers doesn't help here since forking never goes through cast). Adds scripts/rpc-header-proxy.py, a small local HTTP proxy that injects the header before forwarding to the real endpoint, and scripts/with-rpc-header-proxy.sh, which starts it and points FOUNDRY_RPC_URL at 127.0.0.1 for the wrapped command. test-integration.yml now runs forge test through the wrapper. Verified end-to-end against a mock gateway that 401s without the header: `forge test` passes through the proxy, fails without it. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
alanhwu
approved these changes
Aug 19, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
RPC_HEADER_SECRETenv var toscripts/deploy-v3-multichain.shandscripts/deploy-quoter-multichain.sh, sent as thex-internal-service-secretheader on everycastRPC preflight call (chain-id,code,call,balance) viacast's native--rpc-headersflag. Omitted when unset, so public-RPC / local-dev usage is unchanged. Mirrors Uniswap/uniswapx-parameterization-api#442, adapted to this repo's Foundry tooling..github/workflows/test-integration.yml, which started failing with401 Unauthorized: Missing required header x-internal-service-secretonce the RPC gateway began enforcing the header on every request.forge test's forking (vm.createSelectFork) builds its RPC provider straight from the URL string with no way to attach custom headers — confirmed by reading the Foundry source (crates/evm/core/src/fork/multi.rs) — socast's native--rpc-headersdoesn't help here; forking never goes throughcast.The fix: a local header-injecting proxy
scripts/rpc-header-proxy.py— a small stdlib-only local HTTP proxy that addsx-internal-service-secretto every forwarded JSON-RPC request.scripts/with-rpc-header-proxy.sh— starts the proxy and pointsFOUNDRY_RPC_URLat127.0.0.1for a wrapped command, so it works regardless of which Foundry code path makes the request. No-ops (runs the command againstUPSTREAM_RPC_URLdirectly) whenRPC_HEADER_SECRETis unset.test-integration.ymlnow runsscripts/with-rpc-header-proxy.sh forge test -vvvwithUPSTREAM_RPC_URL: secrets.RPC_URLandRPC_HEADER_SECRET: secrets.RPC_HEADER_SECRET.forge scriptbroadcasts, which don't need the header, so they're left ascast-only; their comments point atwith-rpc-header-proxy.shfor anyone who does need it there.Testing
bash -non all four scripts.RPC_HEADERS_ARGSarray expansion underset -u.cast chain-idand a realforge testwithvm.createSelectForkboth fail with a 401 when hitting the mock directly, and both succeed when routed throughwith-rpc-header-proxy.sh.🤖 Generated with Claude Code