# Self-host

{/* // RUNNING THE GATE YOURSELF */}

Postern is built to run as a small set of co-located services behind a reverse proxy. This page is the
architectural map of a self-hosted deployment — what the pieces are, where they sit, and what's in V1
scope.
**V1 is hosted-first:** V1 ships as a hosted service on `mszazu.com` subdomains. The components below are the same ones a
  self-host runs; the API surface, SDK, and MCP server are identical whether you point them at the
  hosted base URL or your own. Wire-up seams to the live backend are marked `// TODO(wire-api)` in the
  SDK and MCP sources.

## Components

| Component | What it is | Stack |
|---|---|---|
| **Agent + admin API** | The `/v1` REST surface; token/agent/mailbox orchestration | Go (`cmd/postern-api`) |
| **Authoritative DNS** | Serves per-tenant A/MX/SPF/DKIM/DMARC for delegated subdomains | Go + `miekg/dns` (`cmd/postern-dns`), DB-backed |
| **MCP server** | The agent tool surface incl. `wait_for_email` | TypeScript (`postern/mcp`), stdio + HTTP |
| **Console** | Human management UI (agents, keys, domains, inboxes) | Next.js |
| **Send backend** | Authenticated sending | Azure Communication Services |
| **Receive backend** | Full IMAP mailbox store | WildDuck |

The Go API reuses the existing provisioning core (`internal/provisioning`, `internal/mailserver`,
`internal/store`, `internal/auth`), which is why it lives in the shared Go module.

## Deployment shape

V1 deploys to nested `mszazu.com` subdomains, co-located on one host behind the reverse proxy:

| Host | Serves |
|---|---|
| `agents.mszazu.com` | Marketing website |
| `app.agents.mszazu.com` | Console |
| `api.agents.mszazu.com` | API + MCP |
| `ns1.mszazu.com` / `ns2.mszazu.com` | Authoritative DNS (UDP/TCP 53) |
| `docs.agents.mszazu.com` | This documentation |

Mailboxes live on `*.mszazu.com` nested labels. Images are prebuilt and deployed with the Uncloud
`--no-build` flow. co-located in V1, isolate later

## Configuration

The whole client and server stack is driven by `POSTERN_API_BASE_URL` (and a key). Point everything at
your own host and it works the same way:

```bash frame="terminal"
export POSTERN_API_BASE_URL="https://api.postern.internal"
export POSTERN_API_KEY="pk_agent_…"
```

| Variable | Used by | Purpose |
|---|---|---|
| `POSTERN_API_BASE_URL` | SDK, MCP, your clients | Base URL of the API (`mock` for offline). |
| `POSTERN_API_KEY` | SDK, MCP | Scoped agent or enrollment key. |
| `POSTERN_MOCK` | MCP | `1` to force offline fixtures. |
| `SITE_URL` | docs/website build | Public host for canonical URLs. |

## Security model to preserve

If you self-host, carry the same discipline the hosted service enforces:

- Every API call is **tenant-scoped by `customer_id` derived from the key**, never from client input.
- Agent keys are **scoped, revocable, and audited**; no org-wide key reaches an MCP host.
- Inbound webhooks are **HMAC-signed and timestamped**.
- Credential/download links are **signed, short-TTL**, and (soon) single-use.

See [Enrollment tokens & scopes](https://docs.agents.mszazu.com/concepts/enrollment-tokens/) and [Errors](https://docs.agents.mszazu.com/api/errors/) for how
these show up at the API.

## V1 scope & what's deferred

| In V1 | Deferred |
|---|---|
| One-call inbox on `mszazu.com` subdomains (mandatory ACS sender) | Real-money / mainnet x402, production billing |
| Send + receive + threaded reply | Self-serve domain purchase (ops-assisted first) |
| Scoped enrollment + agent keys (issue/scope/expire/revoke/audit) | `spring*` isolation as a self-serve toggle, BYO-domain |
| Hosted MCP with `wait_for_email` | Semantic search / auto-labeling |
| HMAC-signed inbound webhooks | Dedicated IPs + warmup engine + cold-outreach tooling |
| Console + x402 test mode | SOC2 / SAML / EU residency |
| Go SDK + REST/OpenAPI, NS-delegation DNS | Biscuit offline attenuation, AP2 mandates |

## Next

- [Domains & onboarding](https://docs.agents.mszazu.com/concepts/domains-and-onboarding/) — the DNS server in context.
- [API reference](https://docs.agents.mszazu.com/api/overview/) — the surface you'd run.
- [Rate limits & quotas](https://docs.agents.mszazu.com/operating/limits/) — limits to configure.