API key security
API keys work exactly as before until you configure a policy. Advanced security can require a customer-signed JWT and restrict a key by source IP, network, JSON-RPC method, and sustained RPC method rate.
How authentication works
Bearer authentication has two distinct uses. A standard API key can authenticate the clean endpoint with Authorization: Bearer YOUR_API_KEY. A customer-signed JWT also uses Authorization: Bearer YOUR_JWT, and SolidRPC verifies that token with public keys you upload in the dashboard.
When both credentials are required, use either POST /<api-key>/evm/<decimal-chain-id> plus a Bearer JWT, or POST /evm/<decimal-chain-id> with X-API-Key: YOUR_API_KEY plus the Bearer JWT. A Bearer API key cannot share the Authorization header with a JWT. Sending both X-API-Key and a Bearer API key is rejected as conflicting input.
Both routes require a positive decimal chain ID with no trailing slash, leading zero, or extra segment. Only POST is accepted. Omit Authorization when you are not sending the intended API key or JWT. Malformed and unrelated credentials are never ignored.
URL API key plus Bearer JWT
curl https://rpc.solidrpc.io/YOUR_API_KEY/evm/1 \
-X POST \
-H "Authorization: Bearer YOUR_JWT" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'X-API-Key plus Bearer JWT
curl https://rpc.solidrpc.io/evm/1 \
-X POST \
-H "X-API-Key: YOUR_API_KEY" \
-H "Authorization: Bearer YOUR_JWT" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'Create and rotate verification keys
Open API Keys, choose Configure, and add an SPKI PEM public key. RS256 uses a 2048–4096-bit RSA key with the standard 65537 exponent. ES256 uses the P-256 curve. These OpenSSL commands keep the private key local and export the public half:
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out private.pem
openssl pkey -in private.pem -pubout -out public.pemopenssl ecparam -name prime256v1 -genkey -noout -out private.pem
openssl pkey -in private.pem -pubout -out public.pemEach API key can store three verification keys. SolidRPC generates a UUID kid for each one. Put that exact value in the JWT header so the gateway chooses the intended public key.
- Add the new public key while the old key is still active.
- Start issuing tokens with the new
kidand private key. - Wait for every token signed by the old key to expire.
- Remove the old public key.
JWT contract
{
"alg": "RS256",
"typ": "JWT",
"kid": "SERVER_GENERATED_KEY_UUID"
}const iat = Math.floor(Date.now() / 1000);
const claims = {
"aud": "urn:solidrpc:api-key:YOUR_API_KEY_ID",
"iss": "https://auth.example.com",
"iat": iat,
"exp": iat + 3600,
"chains": [1, 8453],
"methods": ["eth_blockNumber", "eth_call"],
"ip_cidrs": ["203.0.113.10/32"],
"rps": 20
};| Field | Rule |
|---|---|
alg | Must match the stored key: RS256 or ES256 |
typ | Required and exactly JWT |
kid | Required server-generated verification-key UUID |
aud | Required fixed audience shown on the key settings page |
iss | Required only when the key policy configures an expected issuer |
iat, exp | Required numeric dates. Lifetime must be between 5 minutes and the configured maximum |
nbf | Optional numeric date. A 30-second clock skew is allowed |
Unknown application claims are ignored. Tokens using none, an HMAC algorithm, critical extensions, remote key URLs, or embedded public keys are rejected. A malformed Bearer token is rejected even when JWT is optional for that key.
Delegated scopes
Static settings define the key's maximum authority. Optional token claims can narrow that authority for one workload. They can never grant a network, method, source, or method-rate ceiling that the API key does not already have.
| Claim | Behavior |
|---|---|
chains | Array of decimal chain IDs permitted for this token |
methods | Array of exact, case-sensitive JSON-RPC method names |
ip_cidrs | Array of IPv4, IPv6, or CIDR sources contained by the static allowlist |
rps | Positive sustained RPC method calls/s cap no higher than the key and account ceilings |
Omitting a scope claim adds no token-specific restriction. Sending an empty array grants no access for that dimension. Every member of a JSON-RPC batch must satisfy the chain and method policy, otherwise the entire batch is rejected before quota or usage is charged.
Source IP allowlists
Source policies accept individual IPv4 or IPv6 addresses and CIDR ranges. The gateway trusts only the client address verified at SolidRPC's edge. Requests without that verified source proof fail closed whenever the key or token has an IP scope.
Rate ceilings
The account rate limit always remains the parent ceiling. A key can set a lower sustained RPC method rate, and a JWT can set a lower token rate. Applicable account, key, and token buckets are checked atomically, so extra keys or tokens cannot multiply account throughput.
A per-token bucket is identified by the API key ID plus the SHA-256 digest of the byte-exact JWS signing input: base64url(protected header).base64url(payload). This hashes the two encoded JWT segments, not decoded claims and not the full compact JWT. The signature is deliberately excluded so equivalent ES256 high-S and low-S signatures cannot create separate rate-limit buckets.
Key and token burst capacity is the smaller of the parent burst or five times the sustained method-call rate. Each method call in a JSON-RPC batch consumes one token. See the rate-limit guide for token accounting and 429 handling.
Failures and recovery
| Status | Meaning |
|---|---|
| 401 | Bearer token is missing, malformed, expired, or fails signature or claim validation |
| 403 | Verified source, chain, or method is outside the effective policy |
| 429 | Account, key, token, or JWT-verification abuse bucket is exhausted |
| 503 | A configured hard policy cannot be enforced safely while shared security state is unavailable |
Authentication and policy failures are not billed. For generic bodies, retry guidance, and JSON-RPC errors, see the error reference.