APIZ guide
Ethereum JSON-RPC Adapter
Use the Ethereum Adapter for bounded JSON-RPC calls that require Scripted Policy inspection, especially already-signed transaction submission. It is a proxy and transaction inspector, not a wallet or remote signer.
What This Adapter Supports
- HTTP POST JSON-RPC forwarding.
- Provider authentication through none, bearer, custom header, or a complete write-only provider URL whose path/query contains the provider key.
- APIZ bearer or API-key-shaped Temporary Credentials.
- A bounded
decodeTransactionPolicy helper for signed EIP-2718 transactions. - An
eth_chainIdconnection test.
Credential Boundary
Three different credentials/signatures may exist:
| Material | Purpose | Agent receives it? |
|---|---|---|
| Upstream provider credential or secret provider URL | APIZ authenticates to the RPC provider | No |
| APIZ Temporary Credential | Agent authenticates to the APIZ endpoint | Yes |
| Ethereum transaction signature | Authenticates the on-chain sender | Already part of the signed transaction |
APIZ strips the Client Access Credential and injects provider authentication only after Policy approval. It never replaces or creates the Ethereum transaction signature and never stores an Ethereum private key.
Prepare The Upstream Credential
Obtain an HTTPS JSON-RPC endpoint. Prefer a provider key that can be sent in a
header. If the provider requires the key inside its URL, use provider_url
authentication so the complete URL is stored as write-only credential material
instead of visible API Instance configuration.
Choose a deterministic development chain or provider project for testing. Do not use production signing keys or submit repository fixtures to a live chain.
Web Console
- Open API Instances → Create API Instance → Ethereum JSON-RPC.
- Enter the non-secret JSON-RPC URL.
- Choose no authentication, bearer, custom header, or provider URL.
- Enter provider material only under Provider authentication.
- Attach a tested Scripted Policy before exposing state-changing RPC methods.
- Save and run the
eth_chainIdconnection test.
The built-in Deny Ethereum RPC by default template deliberately denies every call until an explicit transaction-aware Policy is ready.
CLI
Inspect the descriptor and helper surface:
apiz adapter explain ethereum
apiz api explain --adapter ethereum
Create a bearer-authenticated provider connection:
read -rsp "Ethereum provider token: " ETH_RPC_TOKEN && printf '\n'
printf '%s' "$ETH_RPC_TOKEN" | jq -Rs '{credential: .}' |
apiz -o json api create \
--adapter ethereum \
--name ethereum-mainnet \
--config-json '{"http":{"base_url":"https://rpc.example.invalid"},"auth_mode":"bearer"}' \
--credential-stdin
unset ETH_RPC_TOKEN
apiz api test <api-instance-id>
For provider_url, set auth_mode to provider_url and send
{"provider_url":"https://provider.example.invalid/<key>"} as credential
JSON. The complete value is encrypted and never returned.
Give An Agent Access
apiz -o json client create --name transaction-agent
apiz client bind <client-id> --api-instance <api-instance-id> --alias ethereum
apiz client credentials create <client-id> --binding ethereum --ttl 1h --format curl
When a client accepts only a provider URL and no separate auth setting, choose the managed-domain secret URL setup item. That URL is itself a credential and must not enter logs, tickets, or source control. Prefer a separate bearer credential when the client supports it.
Use It From The Agent
Verify the denied path first:
curl -fsS \
-H "Authorization: Bearer $APIZ_TEMPORARY_CREDENTIAL" \
-H 'Content-Type: application/json' \
--data '{"jsonrpc":"2.0","id":1,"method":"eth_chainId","params":[]}' \
"$APIZ_ETHEREUM_ENDPOINT"
For an allowed signed transaction on a deterministic test chain:
curl -fsS \
-H "Authorization: Bearer $APIZ_TEMPORARY_CREDENTIAL" \
-H 'Content-Type: application/json' \
--data "$(jq -cn --arg raw "$SIGNED_RAW_TX" \
'{jsonrpc:"2.0",id:1,method:"eth_sendRawTransaction",params:[$raw]}')" \
"$APIZ_ETHEREUM_ENDPOINT"
The upstream JSON-RPC response is returned unchanged.
Policy Actions And Resources
Every accepted HTTP request normalizes to resource ethereum_rpc, action
ethereum:rpc:call, and dangerous risk. Method-level authorization therefore
requires Scripted Policy body inspection.
The adapter helper:
const decoded = adapter.ethereum.decodeTransaction({ raw_tx: signedRawTx })
returns bounded fields including transaction type, hash, chain ID, recovered sender, recipient/contract creation, nonce, value, gas fields, calldata size and selector, access-list counts, blob hashes, and authorization count where applicable. Helper errors deny through normal fail-closed Policy behavior.
Build and run the repository transaction-guard fixtures before publishing:
apiz policy build \
examples/scripted-policies/ethereum-transaction-guard/policy.ts \
--outdir examples/scripted-policies/ethereum-transaction-guard/dist
for fixture in examples/scripted-policies/ethereum-transaction-guard/fixtures/*.json; do
apiz policy test \
--source examples/scripted-policies/ethereum-transaction-guard/dist/policy.js \
--fixture "$fixture" --explain
done
Review allow and deny cases for chain, sender, recipient, transaction type, value, selector, malformed input, and unsupported JSON-RPC methods.
Connection Tests
The adapter sends one bounded eth_chainId request. Success requires a 2xx
JSON-RPC response containing a valid hexadecimal chain ID and no JSON-RPC
error. It never submits a transaction.
Evidence And Troubleshooting
ethereum_connection_unauthorized: verify provider authentication mode and rotate the stored credential.ethereum_connection_invalid_response: the endpoint did not return a valideth_chainId; confirm URL, chain service, and response format.- Every call denied: the default template is deny-only; publish and attach the tested Scripted Policy.
- Transaction helper error: inspect the safe reason for malformed hex, oversized bytes, unsupported envelope, or invalid signature.
- Upstream rejected transaction: APIZ allowed the request and reached the RPC provider; investigate nonce, funds, gas, chain, and provider response.
Use request evidence to inspect the ordered timeline without exposing provider credentials or full private payloads.
Current Limitations
- Only POST is accepted and every request has the same coarse adapter action.
- Request bodies are bounded and buffered for atomic Policy inspection; responses are streamed and not exposed to Policy scripts.
- APIZ does not provide Clef, remote signing, transaction re-signing, sign-and-submit, nonce management, or wallet account virtualization.
- Signed transaction submission should be tested against a deterministic local chain or mock before any production RPC provider.