PortBay Pro
PortBay is free and open source under Apache-2.0. Pro is optional. It is a pay-what-you-want, perpetual way to support the project and unlock the hosted conveniences — a synced account across your machines, higher project limits, and a few power-user features. There is no subscription.
We're up front about this because the alternative — quietly bolting a paywall onto an "open, no-paywall" tool — would be a bait-and-switch. So here's exactly what's free, what Pro adds, and how the system works under the hood.
Tier model
PortBay uses three tiers. The tier is determined by whether you are signed in and whether your account holds a Pro entitlement.
| Anonymous | Free | Pro | |
|---|---|---|---|
| Auth | None — fresh install | Signed in (GitHub or email) | Signed in + Pro license |
| Project cap | 3 | 6 | Unlimited |
| Multi-device sync | — | — | End-to-end encrypted |
| Custom ports & CORS | Defaults | Defaults | Fully configurable |
| Mail server | Catch & view | Catch & view | Full SMTP access |
| Early access | — | — | Yes |
| Priority support | Community | Community | Priority |
Anonymous and Free share the same feature set — the only difference between them is the project cap (3 vs 6) and that a Free account is the prerequisite for ever upgrading to Pro and for sync.
The project cap counts registry records (projects), not hostnames. A project may expose more than one virtual host; only the number of projects matters.
How sign-in works
Sign-in supports two auth methods:
- GitHub OAuth — authorizes via GitHub and resolves to your GitHub account id. This is the stable identity key for donations, merged PRs, and license issuance.
- Email magic-link — passwordless. Enter an email address; PortBay Cloud sends a one-time link. The account is keyed on the verified email address.
github_idisnullfor email-auth accounts.
Sign in from Settings → Account or the user menu in the app. The CLI and GUI share one keychain session — signing in from either unlocks both.
portbay login # GitHub or email — opens a browser or prints a URL
portbay license # show tier, source, expiry/grace, and signed-in account
portbay logoutAnonymous → Free
When an anonymous user tries to add their 4th project, the cap prompt offers sign up / sign in. Completing sign-up issues a signed Free entitlement, raising the cap to 6.
Free → Pro
When a Free user tries to add their 7th project, the prompt offers the two Pro acquisition paths (see below). Pro activates on the next license refresh.
How to get Pro
Two paths — pay with money or with code. Either one issues a perpetual Pro license tied to your account.
Donate
Support the project financially and Pro unlocks automatically.
- Donate to PortBay.
- Sign in to PortBay with the account you want Pro on (Settings → Account, or the user menu).
- Pro activates on your next license refresh. Already donated and don't see it? Open the upgrade sheet and choose "Already done it? Refresh my license."
Contribute
Get Pro by improving PortBay. When a qualifying pull request you authored is merged, Pro is issued to your GitHub account automatically.
- Find an issue or improvement — see Contributing.
- Open a pull request; once it's merged, Pro unlocks on your next refresh.
The signed entitlement
Every signed-in user receives a signed JSON document from PortBay Cloud's /license endpoint. The client verifies the signature locally against an Ed25519 public key shipped in the binary, caches the document on disk, and trusts it offline. This is the shape both the backend and the Rust entitlement layer agree on:
{
"schema": 2,
"account": { "github_id": 12345, "login": "octocat" },
"tier": "pro", // "free" | "pro" (never "anonymous")
"source": "donate", // "signup" | "donate" | "contribute" | "manual" | null
"issued_at": "2026-05-24T00:00:00.000Z",
"recheck_after": "2026-06-23T00:00:00.000Z",
"grace_days": 21,
"revoked": false,
"entitlements": {
"max_projects": null, // null = unlimited (Pro); Free = 6; anon = 3
"sync": true,
"custom_port_cors":true,
"mail": "full", // "limited" | "full"
"early_access": true,
"priority_support":true
},
"sig": "<ed25519 over the canonical payload>"
}The signature covers a canonical form of the payload (keys recursively sorted, compact, top-level sig excluded) that the client reconstructs byte-for-byte before calling verify_strict. Tampering with any field invalidates the signature.
Anonymous is the client's built-in fallback — it is never fetched and never signed.
Offline grace
PortBay is a local tool. Pro access never drops because the license server is unreachable.
The client computes one effective state from the cached document and the clock:
| Cache | Age | Effective state | Cap | Pro features |
|---|---|---|---|---|
| None / no token | — | anonymous | 3 | off |
Signed free | Any | free | 6 | off |
Signed pro | ≤ recheck window (default 30 days) | pro | ∞ | on |
Signed pro | Recheck < age ≤ recheck + grace | pro-grace | ∞ | on |
Signed pro | Age > recheck + grace (offline) | free | 6 | off |
Signed pro, revoked | — | free | 6 | off |
Signed free, revoked | — | anonymous | 3 | off |
The recheck_after field in the signed document sets when the client should re-verify with the server. The default grace window is 21 days beyond recheck (the grace_days field in the signed document). While inside the grace window the entitlement state is pro-grace — Pro features remain active.
A lapsed or revoked Pro never drops to Anonymous. The signed-in floor is always Free (6). Only a revoked Free account (abuse) falls to Anonymous (3).
The unknown-offline state is reserved for a future refresh-failure surface and is not currently emitted.
Feature gates
Project cap
The cap is enforced identically by the GUI, the CLI, and every add_project backend path. The backend check is the backstop; the GUI gates it proactively before the wizard opens.
- Anonymous: 3 projects.
- Free: 6 projects.
- Pro: unlimited (
max_projects: null).
A lapsed or revoked Pro uses the Free cap (6), never the Anonymous cap. Existing projects above the cap are never deleted — only new adds are blocked.
Custom ports & CORS
The custom_port_cors entitlement gates custom cross-origin policies (CorsConfig.allowedOrigins). The basic listen port is never gated. The gate only fires when introducing or changing an active CORS policy — clearing origins back to empty is always allowed. An existing policy is preserved on downgrade; we only reject the act of changing it.
Mail server
The mail entitlement is either "limited" or "full".
Limited (Anonymous and Free):
- Catch and view local outbound mail.
- Single default mailbox.
- Rolling retention — last 100 messages, cleared on cleanup.
Full (Pro):
- Multiple mailboxes / per-project routing.
- Unlimited retention, search, and export.
- SMTP relay / forwarding to a real address.
Multi-device sync
The sync entitlement gates the sync client. Sync is end-to-end encrypted with a recovery key only you hold.
- Settings → Sync → Set up sync. PortBay generates a recovery key that encrypts your registry before it leaves your Mac.
- Save the recovery key somewhere safe (a password manager) — it is the only way to read your synced data or add another device.
- On a second machine: Settings → Sync → Add this device with a key, paste the recovery key, and your projects pull in.
Project records sync (host, command, port, env references). Machine-specific absolute paths and raw secrets do not. Manage and revoke devices from the same panel.
Early access
The early_access entitlement opts a Pro account into in-development features before they reach the stable channel. Features in the early-access stage are gated at both the Svelte and Rust layers; graduating a feature to stable flips its stage to ga with no call-site changes needed.
Current early-access features include Sandboxed Projects.
Priority support
The priority_support field is a process distinction, not a code gate — Pro accounts receive priority on bug reports and support requests.
Your data & your rights
See the Privacy Policy and Terms of Service. In short: the software stays Apache-2.0; the hosted Pro service has its own terms. You can export or delete your account data at any time. A lapsed or revoked license only blocks new gated actions — your existing projects are never touched.
PortBay is recompilable, and every Pro check is bypassable by rebuilding from source. We don't pretend otherwise. The real value in Pro is the hosted account and sync — the parts that genuinely need a server.
