npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@serve.zone/interfaces

v32.84.0

Published

Shared TypeScript interfaces and TypedRequest contracts for the serve.zone ecosystem.

Readme

@serve.zone/interfaces

@serve.zone/interfaces is the shared TypeScript contract package for the serve.zone ecosystem. It contains the public data shapes and TypedRequest interfaces used by Cloudly, Coreflow, Spark, Coretraffic, platform clients, SDKs, and external integrations to exchange infrastructure state without duplicating DTOs.

Issue Reporting and Security

For reporting bugs, issues, or security vulnerabilities, please visit community.foss.global/. This is the central community hub for all issue reporting. Developers who sign and comply with our contribution agreement and go through identification can also get a code.foss.global/ account to submit Pull Requests directly.

Install

pnpm add @serve.zone/interfaces

Public API

The root export exposes six namespaces:

import { appstore, data, platform, platformservice, protocol, requests } from '@serve.zone/interfaces';

| Namespace | Purpose | | --- | --- | | appstore | App Store catalog, manifest, service requirement, and upgrade contracts. | | data | Durable platform object shapes such as clusters, services, deployments, images, domains, DNS entries, secrets, users, status, settings, backups, registries, BaseOS metadata, and task executions. | | requests | TypedRequest contracts for Cloudly and serve.zone control-plane RPC methods. | | protocol | The handshake two peers exchange when a session opens: what each side speaks, the oldest peer it accepts, and the named refusal when they cannot serve one session. | | platform | Current platform-service contracts for email, SMS, push notifications, letters, AI, databases, object storage, logging, backups, and SIP. | | platformservice | Legacy platform-service namespace kept for older consumers that still depend on the previous layout. |

This package intentionally has no service implementation logic. It is a stable vocabulary for services that need to agree on payload shape, method names, and response types.

Identifier Vocabularies

Two vocabularies name things in these contracts, and which one a member uses is part of the contract.

| Vocabulary | Rule | Members | | --- | --- | --- | | Canonical identifier | ^[A-Za-z0-9][A-Za-z0-9:._-]{0,199}$ — first character alphanumeric, up to 200 characters | organizations, clusters, services, namespaces, sessions, assignments, attempts, authorities, pools, endpoints and every content id derived from them | | Node id | ^[A-Za-z0-9_-]{1,128}$ — the URL alphabet, a leading - or _ included, up to 128 characters | every member that names a node of a cluster |

A node may be named -abc or _abc: enrollment, the runtime session registration and the Spark wire admit a node id that begins with a separator, so every member that names the same node admits one too. data.isClusterNodeId(value) is that rule, and it is the rule at every node-bearing member: nodeId on a session binding, a registration, an enrollment, a Spark heartbeat, a relay block, an assignment, a workload lease, a handoff lease, a DNS-lease renewal run, a protection receipt, an egress authority, a cluster VPN node, an ingress registration, a traffic bucket, a Corestore inventory and an isolated-restore node control; id on a router incarnation and on a node retirement; cloudlyNodeId on a cluster runtime target and on a secret runtime target; and placement.nodeIds on a service runtime spec. A service that stores or forwards a node id should judge it with the same reader rather than with the canonical one, which would refuse a node these contracts themselves enrolled and registered.

A replica id is the one composed name: a producer names a replica slot <node id>.<index>, counted from zero. data.isRuntimeReplicaId(value) reads it by decomposition — the part before the last dot in the node vocabulary, the index on its own and never zero-padded — and reads a name that carries no such index, a zero-padded node-a.01 among them, as an opaque slot name in the canonical identifier vocabulary.

WorkloadInit release verifiers should use the dedicated Node-compatible subpath:

import {
  validateWorkloadInitReleaseAttestationStatement,
  validateWorkloadInitReleaseIdentity,
  workloadInitReleaseContract,
} from '@serve.zone/interfaces/runtime/workloadinit';

@serve.zone/interfaces/runtime/workloadinit exposes only the WorkloadInit release identity, attestation, approval, authority, digest, and validator contracts. Its runtime dependency graph is limited to the immutable-image digest validator; unlike @serve.zone/interfaces/runtime, it does not load the general runtime graph, plugins.js, SmartCrypto, TypedRequest, or Corestore runtime modules.

Directional Image Streams

Image transfer contracts use @api.global/typedrequest-interfaces 7.1.0 and the directional VirtualStream protocol used by TypedRequest 8 and TypedSocket 8. Directions in shared DTOs describe the requesting peer:

| Contract field | Requester endpoint | TypedHandler endpoint | | --- | --- | --- | | requests.image.IRequest_PushImageVersion.request.imageStream | TVirtualStream<'send'> | TVirtualStream<'receive'> | | requests.image.IRequest_PullImageVersion.response.imageStream | TVirtualStream<'receive'> | TVirtualStream<'send'> |

The method names remain pushImageVersion and pullImageVersion. Each stream carries ordered Uint8Array chunks. TypedRequest reverses stream directions for the handler automatically; do not reverse the shared declaration yourself.

Consumers must replace the removed undirected IVirtualStream API with explicit transport-created endpoints. Senders use send() or writable, then close; receivers use receive() or readable, then explicitly accept() after draining EOF and completing application storage or delivery. completion confirms the receiver's accepted receipt, while closed confirms transport cleanup. The upload response's allowed flag permits sending; it does not confirm storage. Receiver rejection, aborts and failed completion must reach the caller. Existing deployment log and shell push-message contracts retain their message shapes.

Human Credential Administration

requests.admin.getHumanCredential and mutateHumanCredential describe human credential inspection and mutation for recently authenticated administrators. Operations rotate a password, revoke password login, or revoke existing sessions. Each successful mutation advances the generation and invalidates older human UI/API and OCI registry sessions. Upstream OIDC identity bindings remain intact.

Send the expected generation and a stable mutation ID. After a lost response, authenticate again and repeat the same request. A replay returns the original metadata without applying the operation again; inspect current metadata separately. Requests containing passwords must never be logged. Responses contain no passwords or verifiers. Cloudly owns validation, atomic persistence, and session enforcement; these shared contracts alone do not implement an endpoint.

Node Credential Administration

requests.node defines getNodeCredential, rotateNodeCredential and revokeNodeCredential for verified platform-infrastructure administrators. getNodeConfig now also requires identity; callers using the previous unauthenticated request shape must update. Its response remains the public IClusterNode, never a persisted backend document.

data.INodeCredentialMetadata separates spark and pallet purposes and exposes lifecycle state, generation, rotation-required status and session epoch, but no bearer, hash, socket peer or controller process identity. Infrastructure credentials do not grant organization or workload permissions.

Mutations require the exact generation and session epoch plus a stable mutation ID. Rotation takes the SHA-256 hash of a node-generated CSPRNG credential that the node has already durably retained with that mutation ID. Lost-response retries repeat the complete request and receive the original metadata, never newly minted plaintext. A replay result is historical and cannot authorize a current session. Treat rotation request hashes as sensitive in transport hooks and logs.

These types do not implement authentication, storage, enrollment or endpoints. Cloudly must verify current administrator authority, validate complete inputs, atomically persist the credential transition and immutable actor-bound receipt, and fence subsequent control effects against current durable credential/session authority. Node identity storage and transport integration must be qualified before enabling rotation or Pallet enrollment.

Spark Host Reporting

data.sparkNodeHeartbeatContract defines the HTTPS POST endpoint /spark/nodes/heartbeat, transport byte limits and protocolRefusalStatus, the status a refused offer is answered with. Its exact request snapshot contains a Spark-purpose bearer, the sender's protocol offer and ISparkNodeReport: fractional host CPU, memory and disk observations, Linux host facts, and the verified bundle version, source commit and manifest digest. It has no Docker or container-count fields. Local runtime readiness remains distinct from unverified workload readiness.

The route reads the bounded body, reads the offer with protocol.readProtocolOffer, negotiates it against its own sparkNode offer and answers a refusal with protocolRefusalStatus and an IProtocolRefusal body — all before the node is authenticated, so a peer of another major is refused by name instead of by a credential verdict it cannot act on. The receipt carries the controller's own offer, so an accepted node judges the session it just reported into.

The Swarm-era Spark runtime keeps its own four routes in data.sparkSwarmNodeContracts, each stating the same three facts as the route above — heartbeat (/spark/swarm-nodes/heartbeat), metricsSample, actionResult and swarmObservation, every one of them an { endpoint, maxRequestBytes, maxResponseBytes } — so one bounded read serves every Spark route. The bounds differ because the bodies do: a heartbeat states the node's whole runtime description, a metrics-sample answer carries every action queued for that node, and one observation carries up to 1024 observed Swarm nodes. That is a second runtime, not an older version of this one: a worker in coreflow-node mode posts those bodies and a pallet node posts this one, and the family retires with coreflow rather than with this release. ISparkSwarmNodeHeartbeatRequest is now owned here, so Cloudly and Spark no longer carry private copies of it, and every Swarm-era body — request and answer alike — carries protocol and is judged in the same order. For fleet cutover, that same observation may carry a bounded local Docker snapshot from the reporting node and, only when control is available, a manager-visible service/task snapshot. The existing node-token, reporter-session, sequence, digest and accepted-receipt rules authenticate both; no separate fleet-report route exists.

Each of the four routes has its validator here, so a server never writes its own member checks: data.validateSparkSwarmNodeHeartbeatRequest, data.validateSparkMetricsSampleRequest, data.validateSparkActionResultRequest and data.validateSparkSwarmObservationRequest. All four answer the same way — one string per refused member, naming the member, and an empty list for an admissible body — so a route table can hold them side by side. They read the envelope first (exact key set, the sender's offer, then the reporter's identity), then the payload: a heartbeat's metrics and full runtime description including each described serve.zone service, a sample's four observations and optional network rates, and an action result whose status is one a node can actually report, never pending. Bodies are judged member by member rather than as canonical bytes, because only the observation is digested and the others carry fractional CPU, memory and rate observations; every level is copied away from the caller's object first, so an accessor is refused instead of run. None of them authenticates a node or acts on the body.

Cloudly must authenticate the bearer against current Spark authority and fence credential generation and session epoch transactionally before recording host liveness. ISparkNodeHeartbeatReceipt contains only server-derived acceptance evidence; the sender must match its node ID and credential generation to its exact active identity. Neither a receipt nor the sender's observation time grants current authority or workload readiness. Persist only the report and receipt in IClusterNode.data.sparkNodeReport, never the bearer. Keep legacy reporting separate. This endpoint does not deliver or acknowledge operator actions.

data.sparkNodeHostContract defines the node's desired-host route, /spark/nodes/host, with 1024-byte request and response bounds, authenticated and judged in the same order as the heartbeat. ISparkNodeHostRequest carries the Spark bearer and the sender's offer; ISparkNodeDesiredHost answers with the whole desired value of IClusterNode.data.hostnameIntent — the hostname and its generation — never a change, and hostname: null with generation 0 states that Cloudly holds no intent, so Spark leaves the host's hostname as it is. Spark applies the latest generation and states the outcome of its last attempt as the optional ISparkNodeReport.hostApply (applied, or failed with a bounded reason) on its next heartbeat; the node has converged when runtime.hostname states the intent's hostname. A Spark that sends hostApply raises its minimumPeerVersion so it reaches only a Cloudly that reads it.

Node Actions

A node action (INodeAction: reboot, serve.zone service update, system upgrade) that a node runtime executes carries lifecycle (INodeActionLifecycle): the administrator's confirmation (INodeActionConfirmation: the typed hostname, the digest of the impact preview they read, when the impact names a Corestore on the node the consent to restart it, and for an update the fleet Spark target revision the preview showed, refused target-changed once the target moved), the impact (INodeActionImpact), the fleet Spark target an update moves the node to, a revision, the current deadline, the claim, a failure with its remedy and a timeline. A Swarm-era record carries none of it and travels only in the Swarm-era metrics-sample answer. TNodeActionStatus keeps the four shipped values (pending is the requested state) and adds claimed, executing, draining, rebooting, verifying, expired, cancelled and unverified; data.nodeActionStatusKinds states which are open.

data.sparkNodeActionContracts defines the node runtime's two action routes, authenticated and judged in the heartbeat's order: offer (/spark/nodes/action) answers the node's one open action (ISparkNodeActionAssignment) or null, and transition (/spark/nodes/action/transition) takes one step at the revision the assignment states — claim with the host's boot id, a forward phase (sparkNodeActionPhaseOrder), complete (a host upgrade without a reboot) or fail with one of sparkNodeActionFailureCodes — and answers applied, replayed (the same step again at the same revision) or a named refusal. data.admitsSparkNodeActionTransition states which step an action admits. Cloudly verifies every action from what the node reports (data.nodeActionVerification): a new boot.id, the target bundle version, or a completed host upgrade; a heartbeat stating boot.rebootRequired after a host upgrade fails it reboot-required rather than rebooting. A deadline (data.nodeActionCompletionBudgetMs, nodeActionContract) that passes ends an action unverified.

A Spark that executes actions states ISparkNodeReport.boot (the kernel boot id and whether the host waits for a reboot) and actionExecutors, the canonical list of action names it executes; Cloudly admits an action only for a node that states its executor. Both are optional members an earlier reader refuses, so a Spark sends them only to a Cloudly that reads them, like hostApply.

data.ISparkFleetTarget is the one fleet Spark target: a version and the SHA-256 its release's SHA256SUMS.txt states for install.sh, with a revision, who set it and when, an append-only history (ISparkFleetTargetChange) and per-node holds (ISparkNodeTargetHold). data.readSparkNodeTargetStanding places a node at, behind or ahead of it, held, unreported or untargeted. The admin requests (getNodeActionPreview, createNodeAction with confirmation, cancelNodeAction, getSparkFleetTarget, setSparkFleetTarget, setSparkNodeTargetHold) answer refusals by name from data.nodeActionRefusals and data.sparkFleetTargetRefusals.

The snapshot functions reject unknown keys, accessors, malformed identities and nonfinite/out-of-range numbers, then return detached frozen records. Transports own byte limits, timeouts and cancellation. These contracts do not implement a listener, credentials, persistence, freshness or shutdown.

Independent Node Enrollment

requests.node defines getNodeEnrollmentState for current Spark-authenticated adoption preconditions and enrollNode for atomic Spark/Pallet enrollment. These contracts do not implement endpoints, authentication, a database or a daemon.

The enrollment proposal binds the canonical HTTPS Cloudly origin, hostname, enrollment identity, original bootstrap proof hash and an exact ordered pair of independently prepared Spark/Pallet credential hashes and CAS counters. Fresh Jump starts both at zero; existing-node adoption rotates current Spark and requires Pallet authority to be absent. snapshotNodeEnrollment returns a detached, frozen snapshot; computeNodeEnrollmentDigest hashes strict canonical JSON under nodeEnrollmentContract.digestDomain, serve.zone/node-enrollment. Neither helper generates or persists credential material.

Transport proof is excluded from the digest to permit exact lost-response recovery. Bootstrap proof must hash to the original proof hash and is allowed only before a receipt exists. Pending-Spark proof must hash to the prepared Spark hash and is allowed only for an existing exact receipt. verifyNodeEnrollmentProof checks this binding and mode only: Cloudly must derive receipt state itself and fence live bootstrap/credential authority in the same owned transaction. Current Jump codes are 12 random bytes encoded as 16 canonical base64url characters.

bindNodeEnrollmentAcknowledgement checks the complete digest, both owners, exact next generations and unchanged adopted node ID, returning a detached frozen acknowledgement. Authenticate Cloudly before accepting it. The acknowledgement is immutable commit evidence, not ongoing authority or workload readiness. Server replay must still verify both active credential generations and hashes; reporter reconnect alone does not invalidate the credential. Spark and Pallet commit their local activation independently and converge after restart; there is no shared plaintext vault or cross-local-database ACID claim. Never log proof/request bodies or hashes, put them in URLs, or expose them through transport hooks.

requests.pallet defines the node-local preparePalletNodeEnrollment, bindPalletNodeEnrollment and activatePalletNodeEnrollment methods. They belong only on the protected root-owned Unix control socket, never a network router. Preparation requests initial Pallet authority (zero generation and session epoch) and returns only its independently retained credential hash. snapshotPalletNodeEnrollmentPreparation and bindPalletNodeEnrollmentPreparation validate that exact exchange.

Local confirmations explicitly distinguish a durable pending binding from the exact current active Pallet identity. bindPalletNodeEnrollmentBound verifies the whole enrollment digest and its pre-assignment node ID (null for fresh Jump). snapshotPalletNodeEnrollmentActivation captures the exact activation request, rejecting extra wrapper fields as well as malformed nested data. bindPalletNodeEnrollmentActive takes that complete activation request and verifies the full Cloudly acknowledgement, including both owners and the assigned node ID. Both confirmation binders return detached frozen snapshots captured before hashing. These are pure content checks: authenticate the local transport separately, and have Pallet prove its current owned state before issuing a confirmation. A historical receipt is insufficient, and Pallet activation does not imply Spark activation or workload readiness.

palletNodeEnrollmentContract specifies one four-byte unsigned big-endian length-prefixed UTF-8 JSON frame per direction, followed by write-half-close, at most 32768 request bytes and 16384 response bytes excluding the prefix. Implement the listener with half-open response support, strict EOF/trailing-byte rejection, bounded time/concurrency, root-only directory/socket permissions and drained cleanup. The package supplies no listener, permission checks or persistent state. No bearer, generic rotation operation or database access is part of this IPC API.

Node Runtime Routing Binding

requests.node.getNodeRuntimeBinding { nodeId, nodeToken } is a current Spark-node-authenticated read. Cloudly derives data.INodeRuntimeBindingRead from its current credential, node, cluster, durable runtime-controller, relay and cluster-runtime records. The answer contains the exact routing identity { cloudlyOrigin, nodeId, clusterId, controller, runtimeNamespace, relay }, the current { id, phase, generation } runtime reference and the Spark credential generation and session epoch that authenticated the read. snapshotNodeRuntimeBindingRead requires the runtime id to equal the routing cluster, and bindNodeRuntimeBindingRead binds the answer to Spark's exact immutable Cloudly origin, node and credential generation. Neither helper authenticates the server.

requests.pallet.bindPalletNodeRuntimeBinding and readPalletNodeRuntimeBinding belong on the existing root-owned Pallet enrollment control socket. Bind is absent-to-present only: the current active Pallet enrollment must name the same canonical Cloudly origin and node, an exact replay is idempotent and every different origin, node, cluster, controller, namespace or relay conflicts. Read requires the requested origin and node to equal both the active enrollment and the stored binding; an absent binding rejects. Spark applies and reads back the binding before starting runtime-serve. On an offline reboot it may read the exact persisted routing identity to select the relay, but that record grants no workload permission and no right to advance or run a cluster phase. Fresh authenticated runtime-session state remains the only workload authority.

The local operations carry no bearer, signing key, generic configuration field, phase mutation or caller-authored permission. nodeRuntimeBindingContract states the immutable local mutation and routing-only persistence rules.

A node can instead be driven by a controller on its own host, such as Onebox. data.INodeRuntimeLocalRoutingBinding is { nodeId, clusterId, controller, runtimeNamespace, registryHosts } with a controller of kind onebox; it names no Cloudly origin and no relay. nodeRuntimeLocalControllerContract fixes the transport: the controller is the TypedSocket client on Pallet's root-only Unix socket /run/serve.zone/pallet/controller.sock (mode 0600, server URL http://localhost), whose file permissions authenticate the peer. A node carries a Cloudly binding or a local one, never both, and the local binding, like the Cloudly one, grants no workload permission by itself.

The first request on a local connection is bindPalletLocalRuntimeController (see Authenticated Runtime Sessions). It is first bind or exact replay. Pallet answers data.INodeRuntimeLocalBindingConfirmation: the exact persisted binding plus the generation and SHA-256 hash of a bearer that Pallet generates and keeps. bindNodeRuntimeLocalBindingConfirmation binds that answer to the binding sent and to the credential the controller pinned in its own durable state at the first bind (null for that first bind). A different credential for the same binding rejects rather than being adopted, because it means the node lost the state the controller enrolled.

registryHosts lists, strictly ordered, the canonical host[:port] registries (isCanonicalRegistryHost) whose pull credential the local controller issues. isNodeRuntimeLocalRegistryWorkload is the local registry rule: a workload's registryHost, and its pullEndpoint when one is stated, must both be listed.

Service Machine Credentials

requests.admin.getServiceMachineCredential inspects redacted metadata; mutateServiceMachineCredential creates, rotates or revokes authority for one exact existing service and organization. ensure requires absent authority and a null expected generation. Rotation and revocation require the exact current generation. Retain the mutation ID and complete input for retry; a receipt replay returns historical metadata without restoring authority.

IServiceMachineGrant currently grants only platform:session. This is separate from deployment grants, human membership and infrastructure permissions. The backend must authenticate each JWT against the current active credential generation, expiry and exact service ownership. Structural snapshot helpers do not perform these checks. Credential changes, encrypted service SecretSet delivery and the replay receipt must commit in the same authorized transaction. The response contains only the immutable secret/version reference; no bearer or hash is returned. Revocation removes current delivery from the metadata.

Private Networks

requests.network defines organization-scoped network create/update/retire and service attachment operations. Mutations require a retained idempotency ID and an exact expected revision; null means no prior document. Cloudly must authorize each request against live canonical membership and policy, reserve aliases transactionally, reject cross-organization attachments, and retain historical receipts. These contracts do not implement the backend or node enforcement.

data.buildPrivateNetworkFqdn produces <alias>.n-<26 lowercase base32 characters>.o-<26 lowercase base32 characters>.internal. from server-owned immutable DNS keys. Aliases are lowercase ASCII labels unique per network. Display-name edits do not rename DNS. A sole attachment selects its search suffix; several attachments require an explicit default or no search suffix. Fully qualified names remain unambiguous across networks. Network policy permits member-to-member connectivity and explicitly configures or denies external DNS forwarding. Creating an alias does not publish public DNS, ingress or ports.

data.composeServicePrivateNetworkDnsPolicy(membership, networks, resolvers) derives the service's network suffixes, the single selected search suffix, and the intersection of external forwarding permissions. resolvers is the complete resolver list of the protected authority the service is projected under. A service attached to no private network forwards any public name to the first four of those resolvers in address and port order; when the authority declares no resolver it has no external resolution (externalDns: null, so its node answers REFUSED for every name). An attached service is decided by its networks alone: a network denying external DNS keeps denying its members whatever the authority declares. Supply every attached network exactly once, with active state and matching canonical organization/DNS keys. Missing, extra, inactive or inconsistent network definitions are rejected. Forwarding requires every attachment to permit both the queried public name and the same exact upstream IP/port; a denied or empty intersection returns externalDns: null. The default network changes only short-name search. Nested suffix unions are intersected at DNS label boundaries and canonicalized without dropping permitted branches; the composed list can contain up to 1,024 suffixes across 16 networks. This pure helper returns detached policy metadata. Its caller must authenticate and fence the included membership/network revisions before issuing node authority.

The snapshot helpers validate and detach content; they do not authenticate it, reserve names, prove membership, or report applied state. Packet authority remains until an applied denial or independent fence. DNS snapshots have a separate maximum 15-minute validity, with positive TTLs capped at five seconds and negative TTLs at one second. DNS expiry does not prove packet revocation or permit identity reuse. Retirement and attachment responses describe desired or historical metadata; consumers must separately track outstanding node revocations and readiness.

IRuntimeNetworkProtectedAuthority declares the complete controller-owned IPv4 protection set, disjoint private workload/transit pools, protected resolver and platform endpoints, and every affected egress authority, including offline nodes. Its snapshot and digest helpers bind the exact predecessor and all declaration content. They cannot prove that an operator's inventory is complete. Install the union of old and new protection on every affected egress owner, or independently fence that owner, before exposing a newly allocatable pool. Removing an entry from the declaration is not a revocation acknowledgement. Prefix arrays are sorted lexically and nonoverlapping; pools and endpoints are sorted by ID; egress owners are ordered by canonical JSON of [nodeId, runtimeNamespace].

continuesRuntimeNetworkProtection(previous, next) states which successor of a protected authority only adds. It answers true when next is previous itself, or exactly the next step of its chain (the same id and controller, next.previous naming previous) in which every egress owner, pool, resolver and platform endpoint of previous is still present with the same content and the prefixes still cover every address previous protected, however they are split. A cluster topology change is such a step: a node joins the egress, or a cluster's hub joins the platform endpoints. The step keeps its barrier: every egress owner still reports a receipt for next before an allocation binds to it. Any removal or change, a jump over a step, another chain or another controller answers false. Both authorities and their digests are validated, and either that does not validate is rejected.

IRuntimeNetworkProtectionReceipt reports a worker's durable, joined native protection journal separately from projection admission. It binds a complete protected-authority reference, node/controller scope, authenticated reporter, boot identity and exact native journal reference to a monotonic receipt chain. A null nativeBarrier explicitly removes allocation eligibility. A node sends one only in answer to the retirement request of a signed projection (see Projection Retirement Requests): its egress ownership is being retired with the withdrawn disposition, and it mints no positive receipt for the chain afterwards (runtimeNetworkProtectionContract.withdrawal). Nothing else withdraws. The node's allocation-pool guard is retained in the kernel when the node process ends, and its boot unit restores it before networking starts, so a clean stop, a crash, a reboot or being offline leaves the last receipt current. A reconnect binds a new reporter session, which the old receipt no longer matches, and the node's first positive receipt under that session restores eligibility. A boot or protection change requires new native journal evidence. These portable values do not inspect a kernel or authenticate their own producer.

reportRuntimeNetworkProtection uses the current authenticated physical peer. Its request binder accepts a historical outbox only against receiver-owned reporter history and identifies that use as historical. The response must match the exact sent receipt. bindRuntimeNetworkAllocationProtection requires the current persisted protection receipt and durable session for every declared egress owner, in canonical owner order. Missing, unavailable, stale-protection and superseded-session evidence reject. An offline owner cannot be omitted. The controller must fence all those records together with lease insertion, before reserving any handoff or workload address. There is no generic independent-fence flag, quorum or expiry: the one way an owner leaves is Egress Owner Retirement. Protection receipts neither prove workload readiness nor release packet/address/name quarantine.

IRuntimeNetworkHandoffLease binds an immutable node/router incarnation to its protected-authority reference, transit subnet and peers, protocol-qualified source ports, nonzero conntrack zone and 128-bit label. The label is exactly 32 lowercase hex characters. Port ranges are inclusive, sorted by protocol then first port, and disjoint within each protocol. bindRuntimeNetworkHandoffLease verifies both digests, scope and transit-pool containment and returns detached values. It does not authenticate a projection or attest to an actual namespace/interface.

snapshotRuntimeNetworkHandoffLedger verifies at most 256 retained leases for one node/controller epoch, including quarantined allocations. It rejects host handoff-port collisions even across router/runtime namespace changes, and zone or label reuse within one router incarnation. The caller must transactionally supply the complete retained set, serialize allocation and fence controller-epoch changes. These are collision checks, not an IPAM allocator or a native capability. No expiry, empty conntrack dump, process exit or table removal establishes flow drainage or permits handoff identity reuse. Signed complete projections, live interface proofs and the separate router/host apply journal remain responsibilities of Cloudly and Pallet; neither packet admission nor readiness follows from these helpers.

IRuntimeNetworkWorkloadLease is the immutable material referenced by assignment.workload.network. It binds one execution attempt and router incarnation to a workload pool, dedicated unbridged linkSubnet, workload address, exact /32 sourcePrefix, and router-side gateway. The gateway also supplies dnsServer on port 53, because CRI DNS settings cannot encode a port. Canonical private point-to-point subnets through /31 are accepted; the owning CNI implementation must qualify its chosen layout. The source prefix, link subnet, VPN control prefix and host/router transit subnet have different roles. bindRuntimeNetworkWorkloadLeaseToAssignment verifies immutable assignment identity without a circular assignment digest. Membership, aliases, readiness and projection revisions never change this address material.

IRuntimeNetworkProjection contains complete relevant network definitions, service memberships and endpoint leases, including remote ready endpoints and declared services with no replicas. It carries the current protected authority, exact historical allocation authorities, local handoff, a maximum 15-minute DNS window and explicit packet/lease/handoff withdrawals. All arrays use the documented canonical ordering: networks and endpoints by ID, memberships by canonical [organizationId, serviceId], references by canonical complete reference, and withdrawals by canonical complete grant. Projections are bounded to 896 KiB, 128 networks, 256 memberships/endpoints, 16 historical authorities and 4,096 carried withdrawals. These transport bounds do not assert native capacity; the node must preflight the actual SmartVPN, Smartnftables and DNS limits before effectful application.

The packet grants a node projection derives are bounded too, and that bound is a protocol limit, not a transport bound: grants are never carried in the projection, and validateRuntimeNetworkProjection refuses a projection whose grants exceed runtimeNetworkProjectionContract.maximumGrants, 4,096 directed grants per node projection. The count covers every workload grant (each ordered pair of distinct members of a private mesh with at least one end on the node) together with every local public-egress and platform grant. One private network whose members are all on the node therefore holds at most 64 of them (64 × 63 = 4,032 workload grants; 65 × 64 = 4,160 is refused), and fewer once remote members, other networks' pairs or egress and platform grants share the node's 4,096. The bound also keeps each successor's explicit withdrawals, which carry every grant it omits and are capped at 4,096, representable. Cloudly and Pallet both apply it through this package's validation, so lifting the ceiling is a protocol change across all three, never a different value here alone.

validateRuntimeNetworkProjection checks complete digest and scope bindings, pool containment, disjoint link subnets, network/organization keys, aliases, resolver authorization and ready-replica uniqueness. It does not authenticate controller inventory, prove observation provenance or authorize allocation reuse. Cloudly must derive readiness from the current authenticated assignment report, retain all affected offline authorities and complete its allocation/barrier transactions before issuance.

An endpoint may publish node ports through the optional IRuntimeNetworkEndpoint.publishedPorts. Each IRuntimeNetworkPublishedPort binds one hostPort (1..65535, unique per node and protocol across the projection) to the workload's targetPort, optionally on an explicit uplink hostIp (never the wildcard or loopback; binding it to the node's uplink is Pallet's enforcement, because the projection carries no uplink fact), and carries the Cloudly authorization reference that permitted it: a published port without that reference cannot exist, and the projection signature covers every byte of it. An endpoint that publishes nothing omits the member entirely and keeps its exact canonical bytes and digest; a present member is never an empty list, so "publishes nothing" has exactly one encoding.

Operators author that authorization through getServicePublishedPorts and setServicePublishedPorts, modelled on the private-network membership pair. IServicePublishedPorts returns the current authorized list with its policy revision, or null when a service never had a policy document. ISetServicePublishedPorts returns the accepted IServicePublishedPorts document with its new revision and a replayed flag, and carries expectedRevision (null for the first document), a retained mutationId for replay, and IRuntimeNetworkPublishedPortRequest entries of protocol, hostPort and targetPort, optionally hostPortEnd and symmetric: the request accepts no hostIp (an omitted address means the node uplink). An empty list is a valid policy meaning the service publishes nothing. Callers never supply an authorization reference: Cloudly derives each projection entry's reference from the accepted policy revision and digest, and node-level host-port placement stays Cloudly's decision.

Who authors a service's published ports follows the service. A service of an idp.global organization is that organization's: only a federated sign-in holding its freshly introspected owner role reads and writes them, and an infrastructure administrator does not substitute for it. A platform-owned service (data.IServicePlatformOwnership: organizationId, serviceId, the designating administrator's actorId, designatedAt) belongs to no idp.global organization, such as the cluster ingress or a platform call router; only a verified administrator reads and writes its published ports, as only an administrator writes its egress. An administrator designates such a service with designatePlatformOwnedService, withdraws it with undesignatePlatformOwnedService and reads it with getServicePlatformOwnership (requests.network.IReq_Admin_Cloudly_DesignatePlatformOwnedService, IReq_Admin_Cloudly_UndesignatePlatformOwnedService, IReq_Admin_Cloudly_GetServicePlatformOwnership). Only a platform organization's service is designated: data.isPlatformOrganizationId is true exactly for a canonical identifier that carries : (legacy:Service:<id>, Organization:<id>), and false for an idp.global nanoid, whichever character it starts with, and for any value that is not a canonical identifier, such as an empty or whitespace id. Cloudly refuses every other id as organization-not-platform, and further designation refusals are service-unknown, service-deleting and conflict (data.servicePlatformOwnershipRefusals). The designation grants no port, egress or placement by itself. Withdrawing it leaves the service's published ports as they are with no writer, because a platform organization has no idp.global owner, until an administrator designates the service again. A published-port write staged while the designation changes is refused as the policy write's conflict.

A published entry with hostPortEnd publishes every port from hostPort to hostPortEnd inclusive, each to the same port inside the workload, so its targetPort equals hostPort and a one-port range is written without the member. symmetric: true makes outbound flows the workload originates from a published target port leave the node from the matching host port, so a peer sees one address and port in both directions (SIP, RTP); it grants no egress of its own, and a projection endpoint carries a symmetric entry only while its publicEgress is true. Both members are stated only when present, so an entry without them keeps its bytes. A symmetric entry owns its inside ports: no other entry of the list and protocol, symmetric or not, publishes to its target port or any port of its range (findRuntimeNetworkPublishedPortInsideOverlap), which Cloudly refuses as published-port-symmetric-inside-overlap and the snapshots refuse outright. The entries of one list are sorted, never overlap within a protocol, number at most runtimeNetworkPublishedPortContract.maximumEntries (64) and cover at most its maximumPortsPerService (1024) ports; on one node, no two entries of a protocol share a port. The port space is split once for Cloudly and Pallet: handoff leases translate outbound flows to runtimeNetworkHandoffSnatPortRange (49152-65535), and Cloudly publishes only runtimeNetworkPublishedPortContract.publishablePorts (1-49151), refusing any other policy as published-port-reserved (isRuntimeNetworkPublishedPortReserved) and a symmetric entry without public egress as published-port-symmetric-without-egress. The snapshots do not enforce the band, so leases and policies written before it stay readable.

A node reads a projection as a whole, so one built against an interfaces release before these members refuses any projection that carries them, including entries of endpoints on other nodes. The session offer (IProtocolOffer.interfacesVersion) is the only statement a node makes about the contract it reads; there is no separate capability list, so a controller must not issue a ranged or symmetric entry into a projection for a node whose offer names an earlier release.

Every endpoint's publicEgress and platformEndpointIds come from the same service policy document. A verified administrator authors them through getServiceNetworkEgress and setServiceNetworkEgress (requests.network.IReq_Admin_Cloudly_GetServiceNetworkEgress / IReq_Admin_Cloudly_SetServiceNetworkEgress): platform endpoints are platform authority, and only an administrator writes the runtime spec whose attached network has to state the same values. IServiceNetworkEgress returns publicEgress and the selected platformEndpointIds (sorted, unique, at most runtimeNetworkAuthorityContract.maximumPlatformEndpoints) with the document's revision, or null when a service never had a policy document. ISetServiceNetworkEgress carries expectedRevision (null for the first document), a retained mutationId for replay and the exact desired values, and returns the accepted IServiceNetworkEgress with a replayed flag; Cloudly carries the published ports forward unchanged, and refuses an id that names no current platform endpoint. Published ports and egress are two halves of one document with one revision, so expectedRevision of either request is the revision the caller read from either answer, and an accepted write of either advances it.

One document per service holds its published ports and its egress under one revision. The first accepted write of either (expectedRevision: null) creates it: setServicePublishedPorts with egress publicEgress: false and platformEndpointIds: [], setServiceNetworkEgress with no published ports. From then on both reads return it, never null. It is an explicit policy: an attached spec stating publicEgress: false and platformEndpointIds: [] matches it and reaches no public address and no platform endpoint; network-policy-missing means the service has no document at all.

snapshotServiceNetworkEgress and snapshotSetServiceNetworkEgress check the shapes. An attached runtime spec is admitted only while it states the document's values (network-policy-mismatch), and nothing else grants a workload egress: a Corestore endpoint on the node's own host is delivered locally, but only to a workload that selects it.

getRuntimeNetworkProjectionPacketGrants derives directed member connectivity and explicit local public/platform egress independently of DNS readiness.

getRuntimeNetworkProjectionPrivateMeshes validates the complete projection and returns its private meshes (IRuntimeNetworkPrivateMesh): one per (organizationId, networkId) that some endpoint's service membership attaches, with the lease references of every such endpoint, local or remote, sorted by lease id. Meshes are sorted by organization and then network id; a network no endpoint attaches has no mesh, and an endpoint whose membership attaches no network is in none. This grouping is the one definition of who may reach whom: the workload grants of getRuntimeNetworkProjectionPacketGrants are exactly the ordered pairs of distinct members of each mesh with at least one end on the projection's node, each pair once however many networks its ends share. A receiver realizes a mesh from it without deriving membership again. Whether a member is local is its lease's node scope (the projection's nodeId, runtimeNamespace and controller), and which local members are attached, or whether remote members are reachable through a tunnel, is the receiver's own fact; the mesh grants nothing beyond the pairs above. A projection names each network id once and only for the organization that owns it, so the key's organization never separates two meshes of one validated projection; it is kept so that the grouping holds without that rule.

composeRuntimeNetworkProjectionDnsViews builds one union view per local workload source address, with every authorized FQDN and complete ready-replica A set. An empty array declares NODATA; absent/unauthorized names remain NXDOMAIN, and IPv4-only service names have AAAA NODATA. The view carries the existing forwarding intersection and zero or one search suffix. Pallet must prove the actual sandbox/veth/source binding, block private/bare-name forwarding, clip TTLs and convert the effective window from getRuntimeNetworkEffectiveDnsWindow (see DNS Lease Renewals) using its qualified boot/time authority. These helpers neither cache queries nor renew a lease.

The DNS composer accepts an optional second argument of exact local workload lease references. Selection happens before view expansion while the complete validated projection still supplies every eligible local or remote target and declared empty name. Omit it for all local views or pass [] for none. Unknown, remote, stale and duplicate references reject. Selection is captured before asynchronous validation and output retains projection order. This lets Pallet compose only its currently attached sources without duplicating membership rules; the references themselves do not prove native attachments or DNS authority.

composeRuntimeNetworkProjectionDnsRecordSets answers the same DNS material with each network's records defined once (IRuntimeNetworkDnsRecordSets). It returns one record set (IRuntimeNetworkDnsRecordSet: networkId, dnsSuffix and records sorted by name) per private network that a selected local source attaches, and no other, sorted by network id. Per selected source, in projection order, it returns that source's union view without records (IRuntimeNetworkDnsSetView: source, sourceAddress, dnsServer, policy) and networkIds, the sets it serves in policy.networkSuffixes order. The union of a source's sets is exactly the records of its composeRuntimeNetworkProjectionDnsViews view, and no name is in two of them, because a validated projection names every alias FQDN once. The union views repeat every shared name in every view; the sets hold it once, so the material grows with sources plus names instead of their product. The composer takes the same optional selection, validates the same way and refuses the same inputs. Its answer is a pure function of the validated projection and the selection, in a stable order; it reads no attachment journal. It names no consumer's identifiers: a consumer that installs the sets (Pallet, as smartdns recordSets referenced by recordSetIds) derives its own set ids, for example from the network's DNS keys.

Both composers read each membership's ready addresses once per projection, so composing one source's view costs work linear in memberships plus endpoints, not their product.

The optional IRuntimeNetworkProjection.router member carries explicit router-origin egress selections and withdrawals. A projection that omits it retains its exact canonical bytes, digest and signature and grants no router-origin flows. New issuers can select resolverIds and platformEndpointIds from the current protected inventory; an empty selection denies all router egress. DNS forwarding policy, workload egress and inventory presence alone supply no router grant. The whole member is signed with the projection; it is not an unsigned runtime option.

getRuntimeNetworkProjectionRouterPacketGrants validates the complete projection and returns up to 96 detached exact grants. Each binds the current local handoff reference and its router transit source address to a selected destination ID, IPv4 address, protocol and port. Resolver selection explicitly authorizes both TCP and UDP at the declared resolver port. Platform selection authorizes only its declared transport tuple, for example a VPN relay endpoint. Every selected protocol must have a source-port allocation in that handoff. No public wildcard, workload source or alternate source address can be supplied in this selection.

Router withdrawals retain these complete grant bodies, including the old handoff and source address. Removing a selection, changing an inventory endpoint or retiring the handoff must explicitly withdraw the old grants. Unknown denials and denials overlapping current grants reject. Up to 4,096 retained withdrawals carry forward until the caller supplies its exact joined application of the preceding projection, with the same receipt boundary as workload withdrawals. These values do not prove packet drainage, native enforcement or allocation reuse. Consumers must compose workload, router and host grants and their separate withdrawals; they must also fence the actual native source, routing and process lifetimes. DNS expiry or readiness changes do not revoke packet authority.

A projection whose controller kind is onebox names a controller that runs on the node itself, so it has no other node: it refuses every endpoint whose lease is not placed on the projection's own node and runtime namespace. Projections of a cloudly controller keep their remote endpoints.

The optional IRuntimeNetworkProjection.host member exists only on onebox projections; any other controller kind carrying it rejects. It lets the node's own host namespace, for example Onebox's reverse proxy, dial exact local workload ports directly, with no loopback publication, no loopback DNAT and no change to martian filtering. A projection that omits it retains its exact canonical bytes, digest and signature and grants no host-origin flows. Each ingress entry names the exact lease reference of a local endpoint of the same projection, a protocol, the workload's own port and an authorization reference. The authorization is signed with the projection but is not part of the grant identity, so re-authorizing an unchanged port neither creates nor withdraws a grant. Entries are unique and strictly ordered; at most 1,024 are allowed (runtimeNetworkHostContract).

getRuntimeNetworkProjectionHostPacketGrants validates the complete projection and returns detached exact grants. Each binds the current handoff reference and its transit host address as the source to the lease reference, lease IPv4 address, protocol and exact port as the destination. Unlike router grants, host grants need no per-protocol source-port allocation in the handoff. Host withdrawals follow the router rules: removing a selection or retiring the handoff or lease must explicitly withdraw the old complete grants, unknown denials and denials overlapping current grants reject, and up to 4,096 retained withdrawals carry forward until the caller supplies its exact joined application of the preceding projection.

The optional IRuntimeNetworkProjection.workloadIngress member exists only on cloudly projections; any other controller kind carrying it rejects. It is how the cluster ingress workload reaches the workloads it routes to without a published host port: each grants entry names the exact lease reference of the ingress workload (source), the exact lease reference of the target workload (destination), a protocol, the target's own listening port and an authorization reference. Unlike the full-mesh workload grants, it needs neither the same organization nor a shared private network, it opens exactly one port, and it is one-way: nothing flows back except the replies of a connection the ingress opened. Both leases must be endpoints of the projection, they must differ, and at least one of them must be placed on the projection's own node. Entries are unique and strictly ordered by [source.id, destination.id, protocol, port]; at most 1,024 are allowed (runtimeNetworkWorkloadIngressContract). The authorization is signed content, not grant identity. A projection that omits the member retains its exact canonical bytes, digest and signature. getRuntimeNetworkProjectionWorkloadIngressPacketGrants validates the complete projection and returns detached IRuntimeNetworkWorkloadIngressPacketGrants ({ source, destination: { lease, protocol, port } }). Their withdrawals follow the host rules: an omitted grant needs its exact withdrawal, unknown or current denials reject, and up to 4,096 retained withdrawals carry forward until the exact joined application of the preceding projection is supplied (Projection Application Receipts).

A signed grant is not yet a delivered flow. The receiving node enforces a grant only between two workloads attached behind its own router: the packet engine has no one-way grant across the inter-node tunnel, so a grant whose ingress lease and target lease run on different nodes is signed into both nodes' projections and admitted by both, yet neither builds a packet path for it and the flow stays denied. Until cross-node one-way grants exist, a controller may route a cluster ingress route to the target lease address and port only when the grant exists and both leases are placed on the same node.

The optional IRuntimeNetworkProjection.hostPlatformEndpointIds lists the ids of the protected authority's platform endpoints whose address the projection's node's own host carries, such as a relay listener or a Corestore beside the node on one machine. A node delivers workload flows to those endpoints locally instead of forwarding them. The list is sorted, unique, never empty when present, and every id must be a current platform endpoint; omitting it keeps the canonical bytes and states that no endpoint is local. It grants nothing: a workload still reaches only the endpoints it selects. The platform endpoint contract itself ({ id, address, protocol, port }) names no node, which is why this statement is per projection.

Projection Retirement Requests

The optional IRuntimeNetworkProjection.retirement (IRuntimeNetworkProjectionRetirement { disposition: 'withdrawn', protectedAuthority }) is Cloudly's request that a running node withdraw its allocation protection, because its egress ownership is being retired with the withdrawn disposition. It travels in the projection because that is the one authenticated, monotonic channel the node already admits, journals and reads on every pass, and whose acknowledged head Cloudly already tracks: the controller's signature covers it, so a node cannot invent it; the projection chain is bound to the controller epoch, node and runtime namespace, so it cannot be carried elsewhere; and a node's acknowledged head proves the node admitted it. A retired node never returns (runtimeNetworkEgressRetirementContract.reentry), so no later chain of the same node can meet a stale request.

protectedAuthority is the authority current when Cloudly first signed the request; its id names the receipt chain's authority chain. validateRuntimeNetworkProjection accepts it only on a cloudly projection and only naming the projection's own authority chain at a generation the projection has reached (the current authority itself at the same generation). admitRuntimeNetworkProjection latches it: it may first appear on any projection, including the first, and that first appearance names exactly the projection's current protectedAuthority (an older generation is refused, because the node's positive receipt under the current authority would then be newer than the request and the withdrawal could never complete). Afterwards every successor carries it unchanged, never dropped and never rewritten, so it stays fixed while the authority chain moves on. Omitted, it keeps the canonical bytes and asks for nothing; it grants and withdraws no packet flow. Consumers on interfaces earlier than 32.44.0 read projections with exact keys and refuse one that carries retirement, so Cloudly sends the request only to nodes that report a compatible interfaces version. snapshotRuntimeNetworkProjectionRetirement is the exact-key reader and runtimeNetworkProjectionRetirementContract states the rules.

The node answers with the null-barrier successor of its protection receipt chain and mints no positive receipt for that chain again. Its allocation-pool guard stays enforced: the answer withdraws eligibility, not protection.

bindRuntimeNetworkProtectionReceiptRetirement(receipt, previous, retirement) is the receiver's gate for every report from a node whose projections carry the request, beside admitRuntimeNetworkProtectionReceipt with the same previous (the receiver's current receipt for the node, or null). The receipt must belong to the retiring authority chain and previous, when given, must be the same chain's exact predecessor or the receipt itself. The null answer always passes. A positive receipt passes only while it can predate the node's admission of the request, so a receipt the node minted before it saw the request still drains from its outbox and the withdrawal behind it is never wedged: it names no authority newer than the request's (a newer one could only come from a projection already carrying the request), and its predecessor is not a null withdrawal (once the receiver holds the answer, no positive receipt follows). A positive receipt minted after the request against the same authority cannot be told apart from one minted before; the node's obligation is never to mint one.

admitRuntimeNetworkProjection checks exact predecessor/replay identity and rejects changed same-generation content, regressed membership/readiness evidence, changed immutable address/DNS keys, and omitted packet grants without explicit withdrawal. Pending withdrawals/tombstones must carry forward until the caller supplies the exact previous projection reference from its own durable joined application receipt (Projection Application Receipts). That reference is never taken from an incoming ACK. Keep the accepted history and apply journal until native effects and DNS/allocation quarantine are settled; a complete new snapshot does not erase that history.

IRuntimeNetworkSigningAuthority is separate from human JWT signing. Install its current revision through the existing authenticated physical connection and commit it with a durable CAS fence. Newly enrolled nodes may bootstrap the controller's current key generation; existing trust cannot be reset to do so. Exact successor revisions rotate the Ed25519 public key; publicKey: null revokes it. Rotation/revocation stops acceptance under the previous key, and requires newly signed authority for DNS. It does not deny outstanding packets or permit allocation reuse.

The Node-only @serve.zone/interfaces/runtime export supplies createRuntimeNetworkSigningKey, signRuntimeNetworkProjection and verifyRuntimeNetworkProjection. Signing produces ISignedRuntimeNetworkProjection { authority, projection, signature }, and the signature covers the canonical envelope { domain, authority, projection } under the dedicated serve.zone/runtime-network-projection-signature domain, so it binds the complete projection and the exact signing-authority revision. Verification requires receiver-owned trusted authority and node scope; an envelope contains no key to trust. Private KeyObjects stay process-local; Cloudly persists their exported material only through its encrypted internal secret store. The dedicated requests.runtimesession key/projection push contracts bind the current physical peer. Their response acknowledges durable admission only, never application, readiness, independent fencing or pool activation.

The getRuntimeManagedVpnCredential method contract in requests.runtimesession uses IGetRuntimeManagedVpnCredentialRequest and IGetRuntimeManagedVpnCredentialResponse. Its request carries the exact current session and signed projection reference. The secret response repeats those bindings and supplies the hub tuple the node dials, the transport it dials it over (quic, the one transport a managed hub serves), the managed authority ID, the Noise server public key, the client keypair and the expiry in Unix milliseconds. The response states no TLS name: QUIC is dialled on the address alone. The hub is the node's own cluster's relay (see Cluster VPN Hub And Network). Keep the response process-local; never persist, hash, log or embed it in a signed projection.

snapshotGetRuntimeManagedVpnCredentialRequest and its response counterpart capture closed detached JSON shapes and canonical 32-byte key encodings. bindGetRuntimeManagedVpnCredentialRequest(request, projection, trustedSession) validates the complete projection digest and binds node, controller, namespace, physical-session identity and projection reference. The response binder takes (response, request, projection, trustedSession, now, renewal = null) and additionally requires the hub's exact tuple to be selected in router.platformEndpointIds, carrying the protocol of the credential's transport — udp for quic, as runtimeNetworkAddressPlanContract.hubTransports states. A relay therefore cannot name itself: the endpoint has to be one the node's signed projection already selected. Expiry must be after the caller-qualified time and no later than the referenced projection's effective DNS window (see DNS Lease Renewals); acceptance before that window starts rejects.

A credential names one projection, but its key pair belongs to the node's managed VPN membership, which outlives it. Every workload add, removal, readiness change or policy change signs a new projection generation; none of them changes who the member is. continuesRuntimeManagedVpnMembership(previous, next) is that rule: next continues the membership when it is the same projection lineage (id), under a protected authority that continues the previous one (continuesRuntimeNetworkProtection: the same authority or its next step that only adds), with the same handoff lease (which names the node scope and carries the router incarnation), and is previous itself or a later generation. A node joining the egress