NekoNest Cloud
NekoNest Cloud is the private commercial control plane and managed Relay for the open-source NekoNest data plane. Self-hosted NekoNest remains independent: it does not contact this repository, read subscriptions, or display Cloud concepts.
The managed architecture is deliberately not “one Docker Server per customer”:
Daemon / Cloud PWA
-> stable Connect origin
-> regional Cloud Relay
-> TenantEngineRegistry
-> one isolated relaycore.Engine per tenant
-> per-tenant SQLite and attachment root
Cloud control plane
-> account, entitlement, host slots, placement, authorization revisions
-> short-lived signed authorization snapshots for Relay nodes
One account maps to one tenant/Nest. A host slot is consumed by one non-revoked host identity, whether it is online or not. A copied device credential remains the same identity and the managed Relay rejects a second simultaneous daemon; software cannot prove that a fully copied private key resides on a different physical machine.
Current commercial policy
- Open-source self-hosting remains free.
- Cloud is a closed, free test while operational and legal gates remain open.
- No quote, order, payment, balance, automatic charge, or token resale path is enabled.
- The existing entitlement/capacity source is authoritative for host slots.
Registering the N+1 non-revoked identity returns
device_capacity_exceeded; revoking a host releases its slot. - Lowering capacity below the active host count is rejected until the user explicitly revokes hosts. Cloud never chooses a device to evict.
- Price, billing period, refund, subscription-expiry, and payment-provider policy remain outside this implementation.
See docs/commercial-contract.md and
docs/launch-gates.md.
Implemented control-plane contracts
- Account, beta entitlement, host-slot, pairing, claim, device credential, revocation, audit, feedback, retention, and account-exit domain state in D1.
- Atomic host claiming: an identity retry is idempotent and does not consume a second slot; a different N+1 identity is refused.
- Stable daemon registration.
POST /api/devices/registerreturns the existing device fields plusconnection_state: ready | provisioningand optionalretry_after_seconds; it never returns a tenant Relay URL. - Regions, Relay nodes, tenant placement, placement generation, authorization revision, opaque route handles, and single-use handoff tickets.
- Ed25519-signed canonical authorization snapshots with
kid, issue/expiry, tenant state, home region, target node, generation, revision, and active credential digests. - Relay-node-only internal APIs for live authorization, revision/delta polling, route resolution, and heartbeat. Node calls use scoped identity; clients cannot submit a raw tenant ID.
- A 60-second, origin-bound, single-use Dashboard-to-PWA handoff. D1 stores only
the ticket digest. Exchange creates an independent revocable
phone_id,phone_token, and non-authorizing opaque route handle. Completion first records a non-authorizing pending principal; only the first request proving possession of the exact token and route handle activates it and advances the tenant authorization revision. A lost exchange response therefore cannot leave an unused active phone identity. - Login or handoff never grants a phone access to a host. The phone must still complete NekoNest’s per-device E2E pairing and receive that device’s key package.
- Stable ingress resolves the current placement for every new connection and uses authenticated internal HTTPS/WSS forwarding when the home node is elsewhere; clients never receive a node URL or redirect.
- Fenced backup/restore and migration primitives keep one writable generation.
Application-layer tenant purge closes the Engine, deletes live data,
attachments and all tenant backups, then clears active credentials only
after node acknowledgement. Its completion audit is written only after all
D1 postconditions hold, and the purge job's
completedmarker is the final fenced mutation.
The Cloud PWA is built from an exact NekoNest revision. It points at the stable
Connect origin through NekoNest runtime endpoint configuration and refuses any
managed endpoint that is not sealed.
The manual cloud-pwa.yml workflow accepts
only a full 40-character NekoNest commit SHA, verifies the checkout, runs the
PWA tests/type-check/build, writes the deploy-time Connect config, records the
source SHA, and emits an immutable build artifact. It does not deploy by itself.
Removed legacy design
The unreleased activation poller, /api/devices/bootstrap, tenant
relay_url handoff, managed-device manifest, per-tenant Server container, and
single-VPS Node provisioner are intentionally removed. They are not a fallback
or a compatibility mode. A daemon with that old managed configuration must
re-register.
Local control-plane development
Requires Node.js 22.13 or newer:
npm ci
npm run dev
Production control-plane configuration includes:
- D1 binding
DBfrom.openai/hosting.json; NEKONEST_CLOUD_ADMIN_EMAILSfor the temporary closed-test admin boundary;NEKONEST_CLOUD_CREDENTIAL_SECRETwith at least 32 random characters for purpose-separated HMAC digests;- Relay snapshot signing keys and active
kid; - independent Relay-node mTLS identities and an exact origin allowlist for the Cloud PWA;
- the stable Connect and PWA origins used by registration and handoff.
Sites/ChatGPT identity and the development demo viewer are closed-test scaffolding, not the final public identity or account-recovery decision.
Daemon distribution
The download catalog is fail closed. It accepts only an exact stable NekoNest
tag, exact platform assets, checksums.txt, and configured SHA-256 digests; it
never follows latest. The compatible daemon must implement protocol 1.3,
stable server_url, ready | provisioning, and structured service errors.
Artifact hashes do not replace publisher/code signing.
See docs/daemon-distribution.md.
Relay deployment, internal forwarding, migration and purge configuration are
documented in docs/relay-operations.md.
The manual cloud-relay.yml workflow
rejects local replace directives, verifies the requested relaycore/vX.Y.Z
tag against go.mod, and runs tests, vet, race checks, and a provenance build
with GOWORK=off.
Database
Drizzle schema is in db/schema.ts, with append-only
migrations under drizzle/. Runtime migration tracking uses
cloud_schema_migrations.
npm run db:generate
Never rewrite a migration already applied to a D1 environment. Because this repository has not yet served production users, a disposable environment may be recreated; any non-disposable D1 database must be exported before migration.
Verification
npm run type-check
npm run lint
npm test
cd relay
go test -count=1 ./...
go vet ./...
The Go Relay has its own tests, race checks, and resource-leak checks. A local green build is not public-service acceptance. Paid/public launch stays blocked until exact-build deployment proves stable ingress, cross-tenant isolation, sealed message and attachment paths, 15-second revocation, five-minute snapshot expiry, backup/restore, deletion/purge, regional migration and rollback, monitoring/on-call, retention, identity, domain/filing, and payment policy.