# Sovereign inference — your hardware, your region

# Sovereign inference — your hardware, your region

For regulated and public-sector workloads you can guarantee that inference runs
**only on machines you own** and **only in the region you choose**. The policy is
enforced at routing time, not merely promised: if no compliant node can serve, the
request **fails** — it never falls back to hardware or a region you didn't allow.

This builds on [Regions & data sovereignty](/docs/regions) and [Run a node](/docs/running-a-node).

## What you get

- **Own hardware only** — requests route exclusively to nodes you operate.
- **Your jurisdiction** — pinned to the EU (or a region you set).
- **Fail-closed** — no compliant node → a clean `503`, never a silent leak.
- **Managed for you** — on-demand model loading, scheduling, routing and uptime.
  Your team ships against one OpenAI-compatible API without operating ML infra.

## 1. Bring your hardware online

On each of your machines (run them in the EU for an EU-sovereign setup):

```bash
curl -fsSL https://porten.ai/install.sh | sh
```

It installs the node, you approve it in your account from the browser, and it
registers as **yours**. See [Run a node](/docs/running-a-node). A node carries the
region it's onboarded in — make sure yours are tagged for your jurisdiction.

## 2. Lock the key down

In **Build → API keys**, on the key your application uses:

- **Fleet → "My nodes only"** — routing is restricted to nodes you own.
- **Region → EU** (the region picker) — routing is restricted to EU nodes.

Both constraints are stored on the key and applied **together** at routing time.
Operators can also set them per key via the admin API.

## 3. Point your app at the API

```bash
curl https://porten.ai/v1/chat/completions \
  -H "Authorization: Bearer $PORTEN_API_KEY" \
  -d '{"model":"…","messages":[{"role":"user","content":"…"}]}'
```

Every request from this key now runs only on your hardware, in your region.

## 4. Verify it's enforced (fail-closed)

Stop your nodes (or take them off the network) and send a request. You get:

```json
503 {"error":{"code":"no_available_node","type":"service_unavailable", ... }}
```

— rather than the request routing somewhere else. That's the guarantee: **no
compliant node, no inference.** It can't silently spill to a machine or region you
didn't allow.

## Total control: self-host the platform

For an air-gapped or fully in-house deployment, run the **entire** platform — the
Hub included — on your own infrastructure. It's a single Go binary plus Postgres
and Redis (a Docker Compose stack), so nothing, including the control plane, leaves
your network. A self-host bundle is available on request.

## What about the control plane?

With the **hosted** platform, a request transits the Hub (European-owned) on its
way to your node and back — inference still happens only on your hardware, but the
prompt passes through the Hub in transit. With a **self-hosted** Hub it never leaves
your network at all. Hardware-enforced privacy on *shared* infrastructure
(confidential compute via TEE + remote attestation) is on the roadmap.
