# Federation

Federation lets one hub (the **primary**) run capabilities on
another hub (a **satellite**) — for example to reach a GPU box or to
keep data inside a specific location. A flow step opts in with an
`on:` selector; everything else stays exactly like a local step.

This panel is the **primary** side: it shows the satellites currently
connected and lets you enrol new ones.

## Add a satellite

1. Press **Add satellite** and give it a name (e.g. `satellite-a`).
2. The hub issues a single-use **bootstrap token** and bundles its
   **CA certificate**. Copy the shown config into the satellite's
   `config.yaml` (one paste) and export the token as
   `CHAIN_BOOTSTRAP_TOKEN`.
3. Start the satellite. It dials the primary, the CA pin makes the
   first connect tamper-proof, and the primary signs it a short-lived
   certificate. It then appears in this list.

## How it stays secure

- The satellite **dials outbound** — no inbound firewall change.
- Every connection is **mTLS**. The first connect is verified against
  the bundled CA; later connects authenticate with the satellite's
  own certificate (no token needed).
- The satellite resolves and runs the capability in **its own
  sandbox** — only inputs cross the wire, never code.
- Each cross-hub call is recorded on both sides (`dispatched_to`), so
  the audit trail and replay determinism survive federation.

## Using a satellite in a flow

Add an `on:` selector to a step:

```yaml
- id: extract
  use: text.extract@^1
  on: region=berlin        # or pin=satellite-a, auto:healthiest, auto:lowest_rtt
  with:
    input: $inputs.doc
```
