# Federation

> How one NYXDB instance reads another's tables — application access on the host, sources and external relations on the consumer, forward mode.

Federation lets one instance, the **consumer**, read tables that live on another
instance, the **host**, without copying them. The consumer sees each host table
as a read-only **external relation** and forwards every read of it to the host.
Reads are forwarded live, and a source can also mirror a host table locally.

Link: wss://

**consumer**

- credential (the minted token)
- source → external relations
- read-only, forwarded

**host**

- application access
- minted secret
- table grants with a row predicate

## On the host: application access

- An **application access** names one remote instance allowed to connect.
- `ALTER APPLICATION ACCESS … MINT SECRET` returns its secret, a token starting
  with `nyxa1_`, exactly once. The host stores only a digest of it.
- Minting again rotates the secret: sessions opened with the old secret end.
- `DISABLE` and `DROP` end the access's sessions; on the consumer the source
  then reports `unavailable` until the access is enabled or re-created.
- What the access may read is granted per table, and every table grant carries
  a row predicate (`WHERE col = literal` or `WHERE col IN (…)`). The actions are
  `read` and `subscribe`.
- `max_session_ms` bounds each session's lifetime (default 24 hours, at most
  30 days), and `max_live_sessions` bounds concurrent sessions.

## On the consumer: credential and source

- `CREATE CREDENTIAL <uuid> SECRET '…'` stores the minted token as a file with
  mode 0600 under the node's federation credentials directory
  (`gateway.federation.credentials_directory`). The secret is never echoed and
  is redacted from query history.
- `CREATE SOURCE … KIND nyxdb_instance` connects to the host endpoint with that
  credential and registers the exposed host tables as external relations under
  local names. The host schema is probed when the source is declared and checked
  again on reconnect.
- External relation names share one namespace with tables, views and
  transformations, so each name is unique.
- `ALTER SOURCE` pauses, resumes, detaches one relation or exposes more;
  `DROP SOURCE` removes the source and its relations.

## Reads and streams

- A `SELECT` on an external relation is authorized locally and forwarded whole
  to the host, with only the relation name rewritten.
- External relations are read-only: writes go to the host. They join with local
  tables and read `AS OF COMMIT` like local relations.
- A `STREAM SELECT` on an external relation becomes one subscription on the
  host. Local subscribers of the same statement share it.
- A forwarded stream does not resume: after a disconnect, open a new
  `STREAM SELECT`.
- When the host is unreachable, reads fail with `unavailable` and a reason
  naming the source, while the consumer reconnects with backoff. Recovery is
  automatic.

## Network rules

- The endpoint host must match a suffix in
  `gateway.federation.allowed_endpoint_suffixes`; an empty list turns
  federation off.
- `wss://` is required for any endpoint other than loopback.
- Federation statements run on WebSocket sessions, and federated reads run over
  both HTTP and WebSocket.

## Permissions

Source statements need `relation_ddl` or `source_manage`. Application-access
and credential statements need `credential_manage` or `source_manage`, and
application-access grants need `data_grant_manage` or `source_manage`. See
[Governance](/docs/operations/governance).

## Observe

| Relation | Side | Shows |
| --- | --- | --- |
| `system.application_accesses` | host | Each access, its status, secret generation and grants. |
| `system.sources` | consumer | Each source, its endpoint, lifecycle (ready, paused, unavailable) and last status. |
| `system.external_relations` | consumer | Each external relation, its host binding, mode and state. |

The statements are listed with examples in
[SQL: federation](/docs/sql/federation).

---

Source: https://nyxdb.io/docs/concepts/federation/
