update readme and portal.png

Kim committed Mar 5, 2026 at 11:25 UTC 88b0cdb26e809fd14a1f141e55ebc74bf49d25a2
2 files changed -50
README.md
-50
@@ -39,33 +39,6 @@ and routes incoming traffic while preserving end-to-end TLS.
39
40 For details, see [docs/glossary.md](docs/glossary.md).
41
42 -## Protocol Scope
43 -
44 -- Raw TCP reverse-connect is the only supported relay/tunnel transport.
45 -- Websocket transport is unsupported for relay/tunnel traffic.
46 -
47 -## Connection Model
48 -
49 -- Conn #1 (`browser -> app`) is the data plane and keeps existing tenant-facing TLS behavior.
50 -- Conn #2 (`relay -> tunnel`) is the control plane and requires lease-bound client mTLS identity on `/sdk/register`, `/sdk/connect`, `/sdk/renew`, and `/sdk/unregister`.
51 -
52 -## Runtime Contracts
53 -
54 -- Lease IDs in admin and SDK payloads are plain string IDs.
55 -- Base64URL lease-ID encoding is used only for admin action route path segments (`/admin/leases/{encodedLeaseID}/{action}`).
56 -- Control-plane admission order is strict: `IP -> Lease -> CertBind -> Token`.
57 -- Tunnel installer scripts always fetch `${BIN_URL}.sha256` and fail closed on missing, malformed, or mismatched checksum.
58 -
59 -## Control-Plane Upgrade Requirement
60 -
61 -- This release wave is a hard-break for control-plane identity.
62 -- Clients without valid lease-bound mTLS identity fail deterministically at control-plane admission.
63 -- There is no token-only fallback mode after cutover.
64 -
65 -### Routing Notes
66 -
67 -- SNI routing preserves an exact-match fallback for the portal root host. Requests that target the exact `PORTAL_URL` host (for example, `portal.example.com`) are handled by the admin/API listener via the no-route path.
68 -
42 ## Quick Start
43
44 ### Run Portal Relay
@@ -76,10 +49,6 @@ cd portal
49 docker compose up
50 ```
51
79 -Set `PORTAL_URL` to your public domain. If `ADMIN_SECRET_KEY` is not set, one is auto-generated and logged at startup. Set `CLOUDFLARE_TOKEN` to enable automatic ACME DNS-01 certificate provisioning (required only when using Cloudflare for DNS).
80 -
81 -The compose file exposes port 443 (SNI routing) and 4017 (admin/API). The SNI port requires a wildcard DNS record (`*.<base-domain>`) pointing to the relay host.
82 -
52 For deployment to a public domain, see [docs/deployment.md](docs/deployment.md).
53
54 ### Expose Local Service via Tunnel
@@ -93,25 +62,6 @@ For deployment to a public domain, see [docs/deployment.md](docs/deployment.md).
62
63 See [portal-toys](https://github.com/gosuda/portal-toys) for more examples.
64
96 -## Relay Server Configuration
97 -
98 -| Flag | Env Var | Default | Description |
99 -| --- | --- | --- | --- |
100 -| `--adminport` | — | `4017` | Admin/API HTTP(S) port |
101 -| `--admin-secret-key` | `ADMIN_SECRET_KEY` | auto-generated | Admin auth secret (auto-generated and logged if not set) |
102 -| `--portal-url` | `PORTAL_URL` | `https://localhost:4017` | Portal base URL |
103 -| `--bootstraps` | `BOOTSTRAP_URIS` | derived from `PORTAL_URL` | Comma-separated relay API URLs |
104 -| `--sni-port` | `SNI_PORT` | `443` | SNI TCP listener port |
105 -| `--keyless-dir` | `KEYLESS_DIR` | `/etc/portal/keyless` | TLS cert and keyless materials directory |
106 -| `--cloudflare-token` | `CLOUDFLARE_TOKEN` | `""` | Cloudflare DNS API token (Zone:Read + DNS:Edit) |
107 -| `--lease-bps` | — | `0` (unlimited) | Per-lease bandwidth cap (bytes/sec) |
108 -| `--trust-proxy-headers` | `TRUST_PROXY_HEADERS` | `false` | Trust X-Forwarded-For / X-Real-IP headers |
109 -| `--trusted-proxy-cidrs` | `TRUSTED_PROXY_CIDRS` | `""` | CIDR allowlist for trusted proxies |
110 -
111 -### Deployment Notes
112 -
113 -- `admin_settings.json` persists runtime state (ban lists, BPS limits, approval mode) in the process working directory. Mount CWD as a volume to preserve state across container restarts.
114 -
65 ## Architecture
66
67 See [docs/architecture.md](docs/architecture.md).
portal.png
Binary files a/portal.png and b/portal.png differ