# Explorer Access Edge Enforcement Runbook Operational runbook for enforcing explorer-issued API keys at the RPC edge for Chain 138 service lanes such as: - `alltra-rpc` on VMID `2102` - `thirdweb-rpc` on VMID `2103` - approval-gated `core-rpc` on VMID `2101` This complements the explorer access console and backend access APIs. The explorer can already issue, rotate, revoke, and validate keys; this runbook covers how to enforce those keys on nginx-facing RPC endpoints. ## Preconditions - Explorer config/API backend is running on VMID `5000` and reachable at `127.0.0.1:8081` - `ACCESS_INTERNAL_SECRET` is configured on the explorer API service - Users and subscriptions are already managed through `/access` - The target RPC lane is behind nginx or another proxy that can make a subrequest to the explorer API ## Canonical validator endpoint - Internal: `http://127.0.0.1:8081/api/v1/access/internal/validate-key` - Public-prefixed equivalent through explorer nginx: `https://explorer.d-bis.org/explorer-api/v1/access/internal/validate-key` ### Validator modes - `GET` for nginx `auth_request` - supply `X-API-Key` or `Authorization: Bearer ...` - supply `X-Access-Internal-Secret` - returns `200` on success or `401` on rejection - includes headers such as: - `X-Validated-Product` - `X-Validated-Tier` - `X-Validated-Scopes` - `X-Quota-Remaining` - `POST` for richer internal clients - JSON body with `api_key`, `method_name`, `request_count`, `last_ip` - returns JSON payload with validated key metadata ## Canonical nginx pattern Use [`common/nginx-rpc-api-key-gate.conf`](./common/nginx-rpc-api-key-gate.conf) as the starting template. For lane-specific rendered configs, use [`../scripts/render-rpc-access-gate-nginx.sh`](../scripts/render-rpc-access-gate-nginx.sh). The important behavior is: 1. nginx receives user traffic 2. nginx subrequests `/__access_validate_rpc` 3. that subrequest calls the explorer validator with: - the client API key - the shared internal secret - request method and source IP 4. only validated requests are proxied to the protected RPC upstream ## Render a product-specific config Instead of editing the template manually, render a concrete config for the target lane: ```bash bash explorer-monorepo/scripts/render-rpc-access-gate-nginx.sh \ --product thirdweb-rpc \ --server-name thirdweb-rpc.example.org \ --internal-secret "$ACCESS_INTERNAL_SECRET" \ --output /etc/nginx/conf.d/thirdweb-rpc-gated.conf ``` Example for `alltra-rpc`: ```bash bash explorer-monorepo/scripts/render-rpc-access-gate-nginx.sh \ --product alltra-rpc \ --server-name alltra-rpc.example.org \ --internal-secret "$ACCESS_INTERNAL_SECRET" \ --output /etc/nginx/conf.d/alltra-rpc-gated.conf ``` Example for `core-rpc` with an explicit upstream override: ```bash bash explorer-monorepo/scripts/render-rpc-access-gate-nginx.sh \ --product core-rpc \ --server-name rpc-http-prv.d-bis.org \ --internal-secret "$ACCESS_INTERNAL_SECRET" \ --upstream http://192.168.11.211:8545 \ --output /etc/nginx/conf.d/core-rpc-gated.conf ``` After rendering, verify syntax before reload: ```bash nginx -t systemctl reload nginx ``` ## Recommended product mapping | Product | Suggested public host | Upstream target | |---|---|---| | `core-rpc` | `rpc-http-prv.d-bis.org` | `http://192.168.11.211:8545` | | `alltra-rpc` | partner/internal hostname | `http://192.168.11.212:8545` | | `thirdweb-rpc` | managed SaaS/internal hostname | `http://192.168.11.217:8545` | For `core-rpc`, keep manual approval enabled and consider IP allowlists in addition to API keys. ## Safe remote install workflow For an operator-friendly rollout, use the dry-run-first installer: ```bash bash explorer-monorepo/scripts/install-rpc-access-gate-nginx-via-ssh.sh \ --product thirdweb-rpc \ --server-name thirdweb-rpc.example.org \ --ssh-host root@192.168.11.217 \ --internal-secret "$ACCESS_INTERNAL_SECRET" ``` That prints the rendered config and planned remote target without mutating anything. Apply only after review: ```bash bash explorer-monorepo/scripts/install-rpc-access-gate-nginx-via-ssh.sh \ --product thirdweb-rpc \ --server-name thirdweb-rpc.example.org \ --ssh-host root@192.168.11.217 \ --internal-secret "$ACCESS_INTERNAL_SECRET" \ --apply ``` By default the installer copies the config, runs `nginx -t`, and only then reloads nginx. ## Explorer API service env At minimum, set: ```dotenv ACCESS_ADMIN_EMAILS=ops@example.org,platform@example.org ACCESS_INTERNAL_SECRET=replace-with-long-random-secret ``` ## Verification Use the dedicated verifier: ```bash bash explorer-monorepo/scripts/verify-explorer-access-edge-hook.sh \ --base-url https://explorer.d-bis.org \ --internal-secret "$ACCESS_INTERNAL_SECRET" ``` To test a real key: ```bash bash explorer-monorepo/scripts/verify-explorer-access-edge-hook.sh \ --base-url https://explorer.d-bis.org \ --internal-secret "$ACCESS_INTERNAL_SECRET" \ --api-key "sk_live_example" ``` ## Rollout order 1. Deploy explorer config/API backend so the validator endpoint is live 2. Confirm `ACCESS_INTERNAL_SECRET` is loaded in the service env 3. Apply nginx config for one protected lane first, usually `thirdweb-rpc` 4. Verify validation responses and upstream reachability 5. Expand to `alltra-rpc` 6. Apply stricter controls for `core-rpc` only after admin approval flow is tested ## Honest limits - This repo now provides the validator hook, operator docs, and example edge config - Actual enforcement still depends on where the RPC traffic is terminated - Billing settlement, Stripe, or x402 monetization is a separate commercial layer