feat(license): distributed license enforcement across multi-node setups (#359)

* feat(license): distributed license enforcement across multi-node setups

The primary instance's license tier is now asserted to remote nodes on
every proxied HTTP and WebSocket request via trusted headers. Remote
nodes honor the assertion only when the request carries a valid
node_proxy JWT, preventing unauthorized elevation from browsers or API
tokens. Falls back to local license tier for direct access.

* fix(test): remove unused vi import in distributed-license tests
This commit is contained in:
Anso
2026-04-03 11:31:14 -04:00
committed by GitHub
parent 9e87e14d62
commit 6c26ae3f50
7 changed files with 324 additions and 9 deletions
+6
View File
@@ -55,6 +55,12 @@ Active licenses are re-validated every **72 hours** against the Lemon Squeezy AP
To manage your subscription (update payment method, view invoices, cancel, or switch plans), visit the [Lemon Squeezy customer portal](https://app.lemonsqueezy.com/my-orders) or use the link in your purchase confirmation email.
## Multi-node license enforcement
If you manage multiple servers through Sencho's [multi-node feature](/features/multi-node), you only need a license on your **primary instance**. All remote nodes automatically inherit the primary's license tier for proxied requests — no per-node activation required.
For details on how this works, see [License enforcement across nodes](/features/multi-node#license-enforcement-across-nodes).
## Deactivating a license
To transfer your license to a different instance:
+22
View File
@@ -90,6 +90,28 @@ Click the **calendar icon** on any node row to jump directly to the Schedules vi
When a node is deleted, all scheduled tasks and update status data associated with it are automatically cleaned up.
## License enforcement across nodes
When you have a paid license (Skipper or Admiral) on your primary instance, all remote nodes automatically inherit that license tier for proxied requests. You do not need to activate a license on each remote node separately.
### How it works
Your primary Sencho instance asserts its license tier to remote nodes on every proxied request. Remote nodes trust this assertion because it arrives alongside a valid node proxy token — the same token you configured when adding the node. No additional configuration is required.
This means:
- **Paid primary → remote nodes**: Pro and Admiral features work on all remote nodes, governed by the primary instance's license.
- **Community primary → remote nodes**: Pro-gated features are blocked on remote nodes, even if a remote node has its own paid license. The primary's tier is authoritative for proxied requests.
- **Direct access to a node**: If you access a remote Sencho instance directly (not through the primary), it uses its own local license tier as usual.
### Why this matters
Without this trust chain, remote nodes would default to the Community tier and block Pro/Admiral features — even though the primary instance has a valid paid license. Distributed license enforcement eliminates this gap so your fleet behaves consistently regardless of which node you're operating on.
<Note>
Remote nodes do not need their own license keys. A single license on the primary instance covers all nodes managed through it.
</Note>
## Editing and deleting nodes
Click the **pencil icon** on any remote node row to edit its name, URL, or token. Click the **trash icon** to remove it. The local node cannot be edited or deleted.
+13
View File
@@ -134,6 +134,19 @@ Click the **wifi icon** on the node row to re-test connectivity after making cha
---
## Pro features return 403 on remote nodes
**Symptom:** A Pro or Admiral feature works on the local node but returns "This feature requires Sencho Pro" (403) when you switch to a remote node.
**Checks in order:**
1. **Is your primary instance licensed?** Go to **Settings > License** on the primary instance and verify it shows an active Skipper or Admiral license. Remote nodes inherit the primary's tier — if the primary is on Community, all remote nodes will be Community too.
2. **Is the remote node's token valid?** An expired or revoked token prevents the license tier from being transmitted. Regenerate the token on the remote instance and update the node config on the primary.
3. **Is the remote node running an up-to-date version of Sencho?** Distributed license enforcement requires both the primary and remote instances to be on v0.34.0 or later. Update the remote node if it's on an older version.
4. **Are you accessing the remote node directly?** If you navigate directly to the remote Sencho instance's URL (bypassing the primary), it uses its own local license. License inheritance only works through the primary's proxy.
---
## Forgotten admin password
Sencho has no password recovery flow. To reset the password: