Skip to content
ARP / SPEC
VERSION v0.1 — DRAFT

Install — Self-host gateway

This is Mode B from the install overview. You run your own gateway, your own database, and point your bridges at it. We ship the same code we run in production at gateway.arp.run; you deploy it on infra you control.

When to pick this: privacy-strict orgs, regulated industries, or anyone who wants connection metadata + audit chains to stay on infrastructure they control. The managed cloud doesn't see encrypted message bodies, but it does see who-talks-to-whom — Mode B keeps that on your side too.

What you're deploying

┌─ Your infrastructure ───────────────────────────────────┐
│                                                         │
│   apps/cloud-gateway          (stateless Node service)  │
│        │                                                │
│        ├── Postgres            (your DB)                │
│        ├── scope-catalog       (HTTP service)           │
│        └── audit storage       (in same Postgres)       │
│                                                         │
│   gateway.<your-domain>        (TLS termination)        │
│                                                         │
└─────────────────────────────────────────────────────────┘
              ▲                                ▲
              │ outbound WS                    │ HTTPS
              │                                │
        bridges (arpc)                  owner dashboard
                                        (you also self-host
                                         apps/cloud-app)

The two services you operate:

  • apps/cloud-gateway — DIDComm fanout, PDP integration, audit chain. Stateless, scales horizontally, talks to Postgres.
  • apps/cloud-app — Next.js owner dashboard (sign-in, pairing UX, connection management). Also stateless.

Plus Postgres (any Postgres works; we use Neon at the managed cloud).

Prerequisites

  • A Linux host or container platform (Railway, Fly, Render, your own VPS / Kubernetes)
  • A Postgres database (≥14)
  • A domain you control with TLS (e.g., gateway.example.com and app.example.com)
  • Node.js 24+ on the deploy target
  • The ARP monorepo cloned locally

Steps

1. Clone and build

git clone https://github.com/KybernesisAI/arp
cd arp
pnpm install
pnpm --filter @kybernesis/arp-cloud-gateway build
pnpm --filter @kybernesis/arp-cloud-app build

2. Provision Postgres + run migrations

export DATABASE_URL=postgres://…
pnpm --filter @kybernesis/arp-cloud-db migrate

Schema includes connections, audit chain rows, pairing state, scope catalog cache.

3. Deploy the gateway

Minimum env vars:

DATABASE_URL=postgres://…
GATEWAY_WS_URL=wss://gateway.example.com
SCOPE_CATALOG_URL=https://gateway.example.com/scope-catalog
SIGNING_KEY=<base58 ed25519 secret>   # gateway's own signing identity
PORT=8080

Deploy apps/cloud-gateway as a long-running Node service. The container or platform should give it a persistent WebSocket-friendly endpoint with TLS termination in front of it.

4. Deploy the dashboard

GATEWAY_API_URL=https://gateway.example.com
DATABASE_URL=postgres://…
NEXTAUTH_SECRET=…
PORT=3000

Deploy apps/cloud-app as a Next.js app. Owners sign in here, pair agents, manage connections, view audit.

5. Point bridges at your gateway

On any agent host running arpc, edit the agent folder's arp.json to override the gateway URL:

{
  "gateway_ws_url": "wss://gateway.example.com",
  "scope_catalog_url": "https://gateway.example.com/scope-catalog"
}

Restart the bridge:

arpc service restart
arpc host status   # confirms it's connected to your gateway

Differences from the managed cloud

Managed (gateway.arp.run)Self-host (this guide)
You operateBridge onlyGateway, Postgres, dashboard, bridge
TLS / certsWe handleYou handle (Let's Encrypt, your CA)
PostgresMulti-tenant Neon, oursYours
Audit storageOur DBYour DB
Dashboard URLcloud.arp.runapp.example.com
Connection metadata visibilityWe see itOnly you
UpdatesAutoYou pull + redeploy

Operating notes

  • Stateless gateway. Run multiple instances behind a load balancer; they coordinate via Postgres + signed envelopes. No sticky sessions required for HTTP, but WebSocket connections from bridges should be sticky to the same gateway pod (most platforms handle this by default).
  • Postgres backups. Audit chains are append-only and signed, so corruption is detectable — but a dropped DB still loses recent state. Daily backups are the floor.
  • Scope catalog. Bridges fetch templates from scope_catalog_url. The gateway serves the same JSON the managed cloud does, compiled from packages/arp-scope-catalog/scopes/*.yaml. Pin a version in your deploys so policy compilation stays deterministic.
  • Migration to/from managed cloud. The handoff bundle is portable. Switching is a gateway_ws_url change in arp.json and a service restart. Existing connections keep working because they bind to the agent's DID, not the gateway URL.

Hardening checklist

  • Postgres on a private network, not public
  • Gateway behind a real TLS terminator (Caddy, Nginx, your platform's edge)
  • SIGNING_KEY stored in a secret manager, not env file in repo
  • Audit chain export job (e.g., daily snapshot to S3) for forensic preservation
  • Monitoring: gateway WS connection count, Postgres connection pool, audit-write latency
  • Rate-limiting on the public WS endpoint (the bridge protocol allows reasonable abuse without it)
  • Install overview — picking a deployment mode
  • Local (Mac) — Mode A install on macOS
  • VPS — Mode A install on a Linux VPS
  • SDKs — package reference, including apps/cloud-gateway