Skip to content

Latest commit

 

History

History
95 lines (72 loc) · 3.92 KB

File metadata and controls

95 lines (72 loc) · 3.92 KB

Deploying octoport centrally

Personal mode is npx octoport up --open on a laptop. This document covers the organization shape: one octoport for a team, behind TLS, with SSO.

Topology

employees' MCP clients ──▶ https://mcp.company.internal  (TLS proxy)
                                     │
                              octoport container
                                     │─ /data volume (config, tokens, OAuth grants, call log)
                                     └─▶ downstream MCP servers

octoport never terminates TLS. Put Caddy (deploy/Caddyfile), nginx, or your load balancer in front, and run the container bound to loopback-published ports only (127.0.0.1:6286:6286 as in deploy/docker-compose.yml).

Quick start

cd deploy
# edit docker-compose.yml: replace mcp.company.internal with your hostname
docker compose up -d
docker compose exec octoport node dist/cli.js token   # initial admin token + dashboard URL

Flags that matter for a central deployment:

Flag Why
--host 0.0.0.0 containers must bind all interfaces
--allow-host <hostname> the exact Host employees use — DNS-rebinding guard
--behind-proxy acknowledgement that TLS terminates upstream
--public-url https://… snippets, dashboard display, and OAuth callbacks use the external URL

Health, metrics, logs

  • GET /healthz — token-exempt liveness/readiness (wire it to your proxy or orchestrator).
  • GET /metrics — Prometheus text format; scrape with an admin-scope bearer token.
  • Call log: SQLite at /data/calls.sqlite; retention via logRetentionDays in config; octoport logs --jsonl or the dashboard export for SIEM ingestion.
  • Payloads: set "logPayloads": false globally (or per server) to keep the audit metadata-only.

Secrets

Keep credentials out of config.json: any env/header/oauth value that is exactly a reference resolves at connect time —

"env": { "GITHUB_TOKEN": "file:///run/secrets/github-token" }
"headers": { "Authorization": "vault://secret/mcp/jira#token" }

file:// pairs with Docker/Kubernetes secrets mounts; vault:// reads HashiCorp KV v2 using $VAULT_ADDR + $VAULT_TOKEN (the standard Vault agent/sidecar contract), cached for 5 minutes. ${VAR} expansion still works.

Identity

  • OIDC: see idp.md. Employees authenticate with company access tokens; profiles map IdP groups to servers/tools. Non-admin identities opening the hub in a browser land on the /my portal (their per-user server authorizations); the admin dashboard and API stay admin-scope.
  • Local tokens remain for CI/service accounts and break-glass. In org mode create them hashed (hashed: true) with an expiry (expiresDays) and the mcp scope only; keep exactly one full-admin token in a password manager.

Backup, upgrade, rollback

Everything durable lives in the /data volume:

  • config.json — servers, tokens (hashes + any plaintext ones), profiles, OIDC settings
  • oauth/*.json — downstream OAuth grants (shared and per-user)
  • calls.sqlite — the audit log

Backup = snapshot the volume (the config write path is atomic; SQLite is WAL — prefer stopping the container or using sqlite3 .backup for consistency). Treat backups as secret material.

Upgrade: pull/build the new image, docker compose up -d. Schema changes migrate forward automatically (additive ALTER TABLEs). Rollback: run the previous image against the same volume — older versions ignore newer optional config fields, and the call-log schema is additive, so this is safe within one minor-version step. Take a volume snapshot before major upgrades.

Scaling notes

One octoport process serves a small-to-mid team comfortably (calls are I/O-bound relays). It is intentionally single-node: SQLite + in-process state. If you outgrow it, that is the Postgres/HA milestone on the roadmap — tell us before you need it.