> ## Documentation Index
> Fetch the complete documentation index at: https://docs.novacula.io/llms.txt
> Use this file to discover all available pages before exploring further.

# RPC exposure

> Control how a node's RPC endpoint is reachable — local, direct (with an IP allowlist), or public domain (managed gateway with TLS, rate limit, and RPC-key auth)

Every node serves RPC, but you decide **how reachable that endpoint is**. RPC exposure is a per-node setting with three modes — **Local**, **Direct**, and **Public domain** — and it applies the same way you describe it on both backends, with each backend using its native mechanism underneath.

This page is about the **RPC** endpoint, which has all three modes. The node's other ports are simpler: **P2P** is published **directly by default** so the node can peer (you can close it, but it can't be proxied), and **metrics** always stay internal to the host or cluster.

## Where to set it

* **At deploy** — the **Network** step of the [Deploy node](/docs/nodes/deploy-a-node) wizard, under **Network & Access**.
* **Any time after** — open the node, go to the **RPC** tab, and use its **Edit** action (dialog: **Edit RPC exposure**).

Exposure is desired state like everything else: change it and the executor reconciles to match on its next check-in. You don't need to redeploy.

## Modes

| Mode              | What it does                                                                                             | Reachable from                                                  |
| ----------------- | -------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- |
| **Local**         | RPC stays private — bound to localhost (Agent) or a `ClusterIP` Service (Operator).                      | Inside the host / cluster only.                                 |
| **Direct**        | Publishes the RPC port on the executor's own network, optionally restricted to an IP allowlist.          | Anyone who can reach the host/node IP and passes the allowlist. |
| **Public domain** | Serves RPC through a managed gateway behind a domain, with TLS, a rate limit, and optional RPC-key auth. | The public internet, at `https://<your-domain>`.                |

Pick the lightest mode that fits: **Local** for a node only other in-network workloads consume, **Direct** for a known set of source IPs, **Public domain** to publish a hardened public endpoint with a hostname and TLS.

A node that serves a [pool](/docs/nodes/pools) belongs in **Local** as well: the pool's gateway reaches it from inside the host or cluster, so nothing is lost by closing the port, and the pool domain stays the only way in.

## Direct

Direct publishes the RPC port so clients reach it on the executor's network. How that happens differs by backend:

* **Agent (bare-metal)** — binds RPC to `0.0.0.0` on the host. If Novacula manages the host firewall, your [IP allowlist](#ip-allowlist) is enforced with firewall rules; if the firewall is unmanaged, the node reports a warning that the allowlist is **not** enforced and it's on you to restrict access.
* **Operator (Kubernetes)** — publishes a Service whose type you choose:
  * **NodePort** *(default)* — opens a port on every cluster node. The allowlist is enforced with a Kubernetes `NetworkPolicy`, which requires a policy-enforcing CNI (Calico, Cilium, Canal). Reaching it from outside still depends on the node having a routable IP and the firewall allowing the node-port range.
  * **LoadBalancer** — provisions a cloud load balancer. The allowlist is enforced through the load balancer's `loadBalancerSourceRanges`, so your provider must support it.

### Advertised host

Optionally set an **advertised host** — the DNS name or IP your clients should actually use to reach the node. The platform advertises it verbatim in the node's endpoint. Leave it empty and the endpoint falls back to the observed address (the LoadBalancer external IP, or the node's external/internal IP for NodePort). Set it when the reachable address differs from what the cluster observes — for example behind NAT or a static DNS record you manage.

## IP allowlist

In **Direct** mode, the **Restrict access (CIDR)** field limits who can reach the RPC port to a list of CIDR ranges (`allowFrom`) — comma- or newline-separated, for example `203.0.113.0/24` or `134.119.214.27/32`. Leave it empty to allow **all** source addresses.

<Warning>
  Enforcement depends on your environment, and Novacula can't always verify it end to end. On Agent with an unmanaged firewall, and on Operator NodePort with a CNI that doesn't enforce `NetworkPolicy`, the allowlist may not actually take effect — the node surfaces a warning where it can detect this, but **confirm the restriction holds from an outside host** before relying on it.
</Warning>

## Public domain

**Public domain** serves the node's RPC through a managed gateway, so clients connect to a clean `https://<domain>` instead of a raw host:port. You provide:

* **RPC domain** *(required)* — the hostname clients will use, e.g. `rpc.example.com`. **Point its DNS at the executor's public address** — the Agent host's public IP, or the cluster's ingress external IP on Operator. The dialog shows the exact record to create once the executor reports its address. Novacula does not manage DNS zones.
* **TLS** — **Auto** (a certificate is issued and renewed for you via cert-manager; your cluster needs a configured issuer), **Manual** (you supply a TLS Secret), or **Off** (HTTP only, for private networks).
* **Rate limit** *(required)* — requests per second the gateway allows.
* **Auth** — **RPC key** (the gateway requires a valid [RPC key](#rpc-keys)) or **None** (the domain is open).

On the **Operator** backend this materializes as an Ingress (plus cert-manager wiring for Auto TLS); the operator chart must grant the ingress and cert-manager RBAC (shipped in the current chart — see [Provision on Kubernetes](/recipes/provision-on-kubernetes)). On **Agent**, the gateway runs as a managed service on the host. The node's **RPC** tab reports DNS and certificate status so you can see when the public endpoint is actually live.

### RPC keys

When a proxy endpoint uses **RPC-key auth**, access is gated by a per-node **RPC key** — the bearer credential your clients present to the proxied endpoint. There is one active key per node. You can issue it at deploy time (**Issue RPC key after deploy**) or from the node's **RPC** tab later (**Issue RPC key after save**).

The key's secret is **shown once**, at the moment the executor mints it — copy it then, because Novacula stores only a hash and can't show it again. The key itself is reusable for as many requests as you like; issuing a new key rotates the old one out (it's revoked on the next sync).

Present the key as a **bearer token** in the `Authorization` header of each request to the proxied endpoint:

```bash theme={null}
curl -X POST https://rpc.example.com \
  -H "Authorization: Bearer nvcl_your-rpc-key" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
```

## Reading the endpoint

The node's **RPC** tab shows the endpoint clients should actually use, resolved to a reachable address rather than an internal hostname:

* **Direct** — `protocol://host:port`, where host is your advertised host if set, otherwise the observed external IP. The tab marks whether the endpoint is externally reachable and offers copy / open actions.
* **Public domain** — `https://<domain>`, always external, with certificate status (`pending`, `ok`, or `failed`) and a DNS-record hint.

If a direct endpoint can't be resolved to an external address yet, the tab says so (for example a LoadBalancer still showing `<pending>`); give the executor a cycle to report, and check your cloud/firewall if it persists.

## Permissions

Changing a node's exposure is a configuration change, so it requires the **Owner** or **Admin** role — same as [editing a running node](/docs/nodes/edit-configuration). Members have read-only access. See [Roles and permissions](/docs/platform/roles-and-permissions).

## Related

* [Deploy a node](/docs/nodes/deploy-a-node) — set exposure at deploy time.
* [Pools](/docs/nodes/pools) — serve several nodes behind one domain and one TLS certificate.
* [Edit a running node](/docs/nodes/edit-configuration) — what else can change after deploy.
* [Provision on Kubernetes](/recipes/provision-on-kubernetes) — ingress, cert-manager, and the RBAC the proxy and metrics paths need.
