@camstack/system 1.2.419 → 1.2.421
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
- package/dist/builtins/alerts/alerts.addon.js +1 -1
- package/dist/builtins/alerts/alerts.addon.mjs +1 -1
- package/dist/builtins/autotrack/index.js +1 -1
- package/dist/builtins/autotrack/index.mjs +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +2 -2
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +2 -2
- package/dist/builtins/calendars/calendars.addon.js +1 -1
- package/dist/builtins/calendars/calendars.addon.mjs +1 -1
- package/dist/builtins/camera-grid/index.js +1 -1
- package/dist/builtins/camera-grid/index.mjs +1 -1
- package/dist/builtins/composer/composer.addon.js +2 -2
- package/dist/builtins/composer/composer.addon.mjs +2 -2
- package/dist/builtins/console-logging/index.js +1 -1
- package/dist/builtins/console-logging/index.mjs +1 -1
- package/dist/builtins/core-blocks/core-blocks.addon.js +2 -2
- package/dist/builtins/core-blocks/core-blocks.addon.mjs +2 -2
- package/dist/builtins/device-manager/contribution-cache.d.ts +18 -1
- package/dist/builtins/device-manager/device-aggregation.d.ts +7 -1
- package/dist/builtins/device-manager/device-manager.addon.js +53 -8
- package/dist/builtins/device-manager/device-manager.addon.mjs +53 -8
- package/dist/builtins/hub-forwarder/index.js +1 -1
- package/dist/builtins/hub-forwarder/index.mjs +1 -1
- package/dist/builtins/keychain/index.js +3 -3
- package/dist/builtins/keychain/index.mjs +3 -3
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
- package/dist/builtins/local-auth/local-auth.addon.js +2 -2
- package/dist/builtins/local-auth/local-auth.addon.mjs +2 -2
- package/dist/builtins/local-network/local-network.addon.js +1 -1
- package/dist/builtins/local-network/local-network.addon.mjs +1 -1
- package/dist/builtins/loki-logging/index.js +1 -1
- package/dist/builtins/loki-logging/index.mjs +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
- package/dist/builtins/platform-probe/index.js +1 -1
- package/dist/builtins/platform-probe/index.mjs +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
- package/dist/builtins/snapshot/index.js +1 -1
- package/dist/builtins/snapshot/index.mjs +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +0 -0
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +0 -0
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +1 -1
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +1 -1
- package/dist/builtins/system-config/system-config.addon.js +138 -18
- package/dist/builtins/system-config/system-config.addon.mjs +138 -19
- package/dist/builtins/winston-logging/index.js +1 -1
- package/dist/builtins/winston-logging/index.mjs +1 -1
- package/dist/{composition-sources-562ib2dL.mjs → composition-sources-DoYpCPtl.mjs} +1 -1
- package/dist/{composition-sources-OaDYklhR.js → composition-sources-DxlTUSI1.js} +1 -1
- package/dist/{constants-BeQWXybC.mjs → constants-CtxNK2QJ.mjs} +1 -1
- package/dist/{constants-ik5xtasS.js → constants-GXZQRcjB.js} +1 -1
- package/dist/{dist-C0wYvAHC.mjs → dist-0OD9ue39.mjs} +106 -2
- package/dist/{dist-DLHPmdoV.js → dist-Df7s77se.js} +106 -2
- package/dist/index.js +187 -19
- package/dist/index.mjs +183 -21
- package/dist/{jwt-signing-key-CWmNKLQi.js → jwt-signing-key-BmyvxlDJ.js} +1 -1
- package/dist/{jwt-signing-key-dkTVfsLI.mjs → jwt-signing-key-W-WFzAoK.mjs} +1 -1
- package/dist/kernel/index.d.ts +5 -1
- package/dist/kernel/moleculer/agent-event-scope.d.ts +49 -0
- package/dist/kernel/moleculer/agent-mesh-authenticator.d.ts +15 -3
- package/dist/kernel/moleculer/broker-factory.d.ts +6 -0
- package/dist/kernel/moleculer/mesh-access-middleware.d.ts +8 -4
- package/dist/kernel/moleculer/mesh-join-hold.d.ts +85 -0
- package/dist/kernel/moleculer/mesh-mtls/index.d.ts +1 -1
- package/dist/kernel/moleculer/mesh-mtls/tls-tcp-transporter.d.ts +65 -4
- package/dist/{restore-archive-gGHgAZsz.mjs → restore-archive-BUMSox6L.mjs} +1 -1
- package/dist/{restore-archive-DZeFVS2l.js → restore-archive-W1Cg5y6C.js} +1 -1
- package/dist/{retired-settings-keys-DibNtLmU.js → retired-settings-keys-D-Xv1Zyv.js} +1 -1
- package/dist/{retired-settings-keys-BHlKEYNL.mjs → retired-settings-keys-Wz92bcuK.mjs} +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { i as __require } from "./chunk-CNf5ZN-e.mjs";
|
|
2
|
-
import { At as extractNestedAddonId, Bt as isObjectInput, Cn as resolveMethodAuth, Dn as scopesAllowDeviceCap, Dr as emitDownForOwnedCaps, En as scopesAllowAddon, G as addonSettingsCapability, Gr as resolveCapMount, Hr as parseJsonUnknown, Ht as kebabToCamel$1, It as isArrayOutputSchema, Lt as isCollectionArrayMethod, O as LOG_LEVEL_RANK, Qt as looseSchema, Rn as supportedRuntimes, Vr as parseJsonObject, Vt as isVoidInput, Wr as readinessKey, Zt as logLevelAtMost, br as asString$1, cn as objectInputDeclaresRequiredDeviceId, dr as DEVICE_STATUS_METHOD, ei as EventCategory$1, hr as ReadinessTimeoutError, j as METHOD_ACCESS_MAP, kr as expandCapMethods, lr as DATAPLANE_SECRET_HEADER$1, mr as ReadinessRegistry, pn as procedureAuthKey, pr as RUNTIME_DEFAULTS, qr as scopeKey, qt as lifecycleJobSchema, sn as objectInputDeclaresAddonId, sr as errMsg$1, t as ALL_CAPABILITY_DEFINITIONS, ur as DEVICE_SETTINGS_CONTRIBUTION_METHODS, vr as asJsonObject$1, wr as createEvent$1, yr as asNumber } from "./dist-
|
|
3
|
-
import { c as staticJwtSigningKey, i as getProcessJwtSigningKeyState, n as JwtSigningKeyUnavailableError, o as processJwtSigningKey, r as SYSTEM_SECRET_OWNER, t as JWT_SIGNING_KEY_REF } from "./jwt-signing-key-
|
|
2
|
+
import { At as extractNestedAddonId, Bt as isObjectInput, Cn as resolveMethodAuth, Dn as scopesAllowDeviceCap, Dr as emitDownForOwnedCaps, En as scopesAllowAddon, G as addonSettingsCapability, Gr as resolveCapMount, Hr as parseJsonUnknown, Ht as kebabToCamel$1, It as isArrayOutputSchema, Lt as isCollectionArrayMethod, O as LOG_LEVEL_RANK, Qt as looseSchema, Rn as supportedRuntimes, Vr as parseJsonObject, Vt as isVoidInput, Wr as readinessKey, Zt as logLevelAtMost, br as asString$1, cn as objectInputDeclaresRequiredDeviceId, dr as DEVICE_STATUS_METHOD, ei as EventCategory$1, hr as ReadinessTimeoutError, j as METHOD_ACCESS_MAP, kr as expandCapMethods, lr as DATAPLANE_SECRET_HEADER$1, mr as ReadinessRegistry, pn as procedureAuthKey, pr as RUNTIME_DEFAULTS, qr as scopeKey, qt as lifecycleJobSchema, sn as objectInputDeclaresAddonId, sr as errMsg$1, t as ALL_CAPABILITY_DEFINITIONS, ur as DEVICE_SETTINGS_CONTRIBUTION_METHODS, vr as asJsonObject$1, wr as createEvent$1, yr as asNumber } from "./dist-0OD9ue39.mjs";
|
|
3
|
+
import { c as staticJwtSigningKey, i as getProcessJwtSigningKeyState, n as JwtSigningKeyUnavailableError, o as processJwtSigningKey, r as SYSTEM_SECRET_OWNER, t as JWT_SIGNING_KEY_REF } from "./jwt-signing-key-W-WFzAoK.mjs";
|
|
4
4
|
import { AlertCenterAddon } from "./builtins/alerts/alerts.addon.mjs";
|
|
5
5
|
import "./builtins/alerts/index.mjs";
|
|
6
6
|
import { CalendarsAddon } from "./builtins/calendars/calendars.addon.mjs";
|
|
@@ -25,15 +25,15 @@ import { SqliteSettingsAddon, o as SqliteSettingsBackend, s as prefixRange } fro
|
|
|
25
25
|
import { ConfigStore, DeviceStore } from "./builtins/sqlite-storage/index.mjs";
|
|
26
26
|
import { StorageOrchestratorAddon, a as stripForwardedCaller, i as createHubCapForwardService, n as HUB_CAP_FWD_ACTION, o as buildStorageLocationRegistry, r as HUB_CAP_FWD_SERVICE, t as StorageOrchestratorService } from "./builtins/storage-orchestrator/storage-orchestrator.addon.mjs";
|
|
27
27
|
import "./builtins/storage-orchestrator/index.mjs";
|
|
28
|
-
import { _ as getProcessClusterSecretGate, a as MESH_CA_KEY_REF, b as setProcessClusterSecretGate, d as CLUSTER_SECRET_REF, f as CLUSTER_SECRET_REJECTED_EXIT_CODE, g as clusterSecretMatches, h as checkClusterSecret, i as MESH_CA_FIELD, m as CLUSTER_SECRET_UNAVAILABLE_TYPE, n as DEFAULT_HUB_TLS_TCP_PORT, o as MESH_CA_SETTINGS_KEY, p as CLUSTER_SECRET_SETTINGS_KEY, u as CLUSTER_SECRET_MISMATCH_TYPE, v as hashClusterSecret, y as isClusterSecretMismatchError } from "./constants-
|
|
29
|
-
import { A as
|
|
28
|
+
import { _ as getProcessClusterSecretGate, a as MESH_CA_KEY_REF, b as setProcessClusterSecretGate, d as CLUSTER_SECRET_REF, f as CLUSTER_SECRET_REJECTED_EXIT_CODE, g as clusterSecretMatches, h as checkClusterSecret, i as MESH_CA_FIELD, m as CLUSTER_SECRET_UNAVAILABLE_TYPE, n as DEFAULT_HUB_TLS_TCP_PORT, o as MESH_CA_SETTINGS_KEY, p as CLUSTER_SECRET_SETTINGS_KEY, u as CLUSTER_SECRET_MISMATCH_TYPE, v as hashClusterSecret, y as isClusterSecretMismatchError } from "./constants-CtxNK2QJ.mjs";
|
|
29
|
+
import { A as AGENT_UI_UNLOCK_TTL_MS, B as isMeshAuthMode, C as generateMeshCa, D as loadMeshCa, E as issueMeshLeafFromCsr, F as parseAgentDashboardOrigins, G as setProcessMeshEnforcer, H as requestProcessMeshEnforcement, I as verifyAgentUiUnlockTicket, J as parseCidrList, K as createCidrMatcher, L as MESH_AUTH_MODE_FIELD, M as UnlockTicketJtiStore, N as isAllowedAgentDashboardReturnTo, O as AGENT_DASHBOARD_ORIGINS_FIELD, P as mintAgentUiUnlockTicket, R as getProcessMeshAuthMode, S as exportMeshPrivateKeyPem, SystemConfigAddon, T as issueMeshLeafForNode, U as setProcessMeshAuthMode, V as parseMeshAuthMode, W as setProcessMeshAuthStatusSource, Y as readCidrSetting, _ as getProcessMeshCaState, a as ServiceBroker, b as caFingerprintCompact, c as JoinTokenJtiStore, d as verifyMeshJoinToken, f as getProcessNodeMeshTransport, g as MeshCaKeeper, h as processMeshCrl, i as Errors, j as AGENT_UI_UNLOCK_VERSION, k as AGENT_UI_UNLOCK_DOMAIN, l as mintMeshJoinToken, m as MeshCrl, n as MESH_TLS_PORT_HELLO_FIELD, o as setProcessMeshTlsEnabler, p as setProcessMeshPeerTransportLookup, q as normalizeIp, r as TlsTcpTransporter, s as enrollMeshNode, u as processJoinTokenJtiStore, v as requireProcessMeshCa, w as generateMeshKeyPair, x as createMeshCsrPem, y as caFingerprint, z as getProcessMeshAuthStatus } from "./builtins/system-config/system-config.addon.mjs";
|
|
30
30
|
import "./builtins/system-config/index.mjs";
|
|
31
31
|
import { WinstonDestination, WinstonLoggingAddon } from "./builtins/winston-logging/index.mjs";
|
|
32
32
|
import { C as isModelDownloaded, T as revisionWeightUrl, _ as downloadFile, a as startEventLoopStallMonitor, b as fetchJson, c as createAuthenticatedFileServer, d as resolveFilePath, f as ModelDownloadService, g as deleteModelFromDisk, h as collectModelFiles, i as attributeStall, l as parseRangeHeader, m as adoptModelRevisions, n as STALL_REPORT_MS, o as createFileDataPlaneHandler, r as STALL_TICK_MS, s as contentTypeFor, t as CustomActionRegistry, u as parseTokenizedUrl, v as downloadModel, w as resolveFormatRevision, x as getModelFilePath, y as ensureModel } from "./custom-action-registry-BQnbN0DP.mjs";
|
|
33
33
|
import { A as allFamiliesListenHost, C as collectCertIdentity, D as SERVER_AUTH_OID, E as MAX_LEAF_VALIDITY_DAYS, F as registerLanHttpHandler, M as bindPendingLanHttp, N as closeLanHttp, O as evaluateExistingCert, P as readLanHttpState, S as CA_COMMON_NAME, T as LEAF_RENEWAL_WINDOW_DAYS, _ as writeExtraSans, a as validateUploadedTls, b as loadTlsCert, c as registerHttpsListener, d as prepareBootTls, f as UPLOADED_CA_FILE, g as splitPemCertificates, h as readTlsMode, i as storeUploadedCertificate, j as applyLanHttp, k as DEFAULT_LAN_HTTP_PORT, l as reloadHttpsListener, m as readTlsAccessStatus, n as regenerateCertificate, o as clearHttpsListener, p as readExtraSans, r as revertToGeneratedCertificate, s as leafFingerprintOf, t as applyCertificateToListener, u as servedHttpsLeafFingerprint, v as writeTlsMode, w as CA_VALIDITY_DAYS, x as reissueTlsLeaf, y as ensureTlsCert } from "./tls-CaOLZ09W.mjs";
|
|
34
34
|
import { n as getPlatformKeychainKey, r as setPlatformKeychainKey, t as clearPlatformKeychainKey } from "./platform-key-source-BWlq0jjn.mjs";
|
|
35
35
|
import { n as getSinglePidStats, t as getPidStats } from "./resource-monitor-Di9daRwI.mjs";
|
|
36
|
-
import { c as BackupKeyFormatError, d as generateBackupKeyPair, l as BackupKeyMismatchError, m as readBackupEncryptionHeader, o as SystemBackupService, r as prepareRestoreArchive, s as BackupDecryptError, t as BackupKeyRequiredError } from "./restore-archive-
|
|
36
|
+
import { c as BackupKeyFormatError, d as generateBackupKeyPair, l as BackupKeyMismatchError, m as readBackupEncryptionHeader, o as SystemBackupService, r as prepareRestoreArchive, s as BackupDecryptError, t as BackupKeyRequiredError } from "./restore-archive-BUMSox6L.mjs";
|
|
37
37
|
import { z } from "zod";
|
|
38
38
|
import * as crypto$1 from "node:crypto";
|
|
39
39
|
import { createHash, createHmac, randomBytes, randomUUID, timingSafeEqual } from "node:crypto";
|
|
@@ -15106,6 +15106,9 @@ function createBroker(config) {
|
|
|
15106
15106
|
serializer: "MsgPack",
|
|
15107
15107
|
transporter: new TlsTcpTransporter({
|
|
15108
15108
|
port: agentListenPort,
|
|
15109
|
+
tlsPort: config.agentTlsListenPort ?? 6443,
|
|
15110
|
+
peerTlsPort: hubDialPort,
|
|
15111
|
+
hubOnlyPeers: true,
|
|
15109
15112
|
maxPacketSize: 10 * 1024 * 1024,
|
|
15110
15113
|
useHostname,
|
|
15111
15114
|
debug: false,
|
|
@@ -24108,6 +24111,10 @@ function createMeshAccessMiddleware(options) {
|
|
|
24108
24111
|
const sender = senderOf(ctx);
|
|
24109
24112
|
if (sender === null || sender === ownNodeId) return next.call(this, ctx);
|
|
24110
24113
|
const verdict = authenticator.admitCall(sender, name);
|
|
24114
|
+
if (verdict.verdict === "hold") return verdict.settled.then((settled) => runAdmitted.call(this, ctx, sender, settled));
|
|
24115
|
+
return runAdmitted.call(this, ctx, sender, verdict);
|
|
24116
|
+
};
|
|
24117
|
+
function runAdmitted(ctx, sender, verdict) {
|
|
24111
24118
|
if (verdict.verdict === "deny") {
|
|
24112
24119
|
logger?.warn("mesh call refused", {
|
|
24113
24120
|
sender,
|
|
@@ -24119,23 +24126,119 @@ function createMeshAccessMiddleware(options) {
|
|
|
24119
24126
|
if (name === "$hub.unregisterNode" && paramNodeId(ctx.params) !== sender) return Promise.reject(new Errors.MoleculerClientError(`node "${sender}" may unregister only itself`, 403, MESH_ACTION_FORBIDDEN_TYPE));
|
|
24120
24127
|
ctx.params = stripForgedIdentity(name, ctx.params);
|
|
24121
24128
|
return next.call(this, ctx);
|
|
24122
|
-
}
|
|
24129
|
+
}
|
|
24123
24130
|
},
|
|
24124
24131
|
localEvent(next, event) {
|
|
24125
24132
|
const name = event.name ?? "";
|
|
24126
24133
|
return function meshGatedEvent(ctx) {
|
|
24127
24134
|
const sender = senderOf(ctx);
|
|
24128
24135
|
if (sender === null || sender === ownNodeId) return Promise.resolve(next.call(this, ctx));
|
|
24129
|
-
|
|
24130
|
-
|
|
24131
|
-
|
|
24132
|
-
|
|
24133
|
-
|
|
24136
|
+
const verdict = authenticator.admitEvent(sender, name);
|
|
24137
|
+
const deliver = (settled) => {
|
|
24138
|
+
if (settled.verdict === "deny") {
|
|
24139
|
+
noteDroppedEvent(sender, name);
|
|
24140
|
+
return Promise.resolve();
|
|
24141
|
+
}
|
|
24142
|
+
return Promise.resolve(next.call(this, ctx));
|
|
24143
|
+
};
|
|
24144
|
+
return verdict.verdict === "hold" ? verdict.settled.then(deliver) : deliver(verdict);
|
|
24134
24145
|
};
|
|
24135
24146
|
}
|
|
24136
24147
|
};
|
|
24137
24148
|
}
|
|
24138
24149
|
//#endregion
|
|
24150
|
+
//#region src/kernel/moleculer/mesh-join-hold.ts
|
|
24151
|
+
var DEFAULT_MESH_JOIN_MAX_HELD = 1e3;
|
|
24152
|
+
var DEFAULT_MESH_JOIN_MAX_HOLD_MS = 15e3;
|
|
24153
|
+
var MeshJoinHold = class {
|
|
24154
|
+
opts;
|
|
24155
|
+
waiters = [];
|
|
24156
|
+
firstHeldAt = null;
|
|
24157
|
+
overflow = 0;
|
|
24158
|
+
timer = null;
|
|
24159
|
+
/** Holding is open while a join is in flight; closed after a decision or the bound. */
|
|
24160
|
+
open = true;
|
|
24161
|
+
now;
|
|
24162
|
+
constructor(opts) {
|
|
24163
|
+
this.opts = opts;
|
|
24164
|
+
this.now = opts.now ?? Date.now;
|
|
24165
|
+
}
|
|
24166
|
+
/** Whether a request arriving now would be held (a join is in flight). */
|
|
24167
|
+
get holding() {
|
|
24168
|
+
return this.open;
|
|
24169
|
+
}
|
|
24170
|
+
/** How many requests wait right now. */
|
|
24171
|
+
get size() {
|
|
24172
|
+
return this.waiters.length;
|
|
24173
|
+
}
|
|
24174
|
+
/** A join started: hold again. */
|
|
24175
|
+
reopen() {
|
|
24176
|
+
this.open = true;
|
|
24177
|
+
}
|
|
24178
|
+
/** Hold one request; `null` when holding is closed (the caller refuses it). */
|
|
24179
|
+
hold(kind) {
|
|
24180
|
+
if (!this.open) return null;
|
|
24181
|
+
if (this.waiters.length >= (this.opts.maxHeld ?? 1e3)) {
|
|
24182
|
+
this.overflow++;
|
|
24183
|
+
return {
|
|
24184
|
+
verdict: "hold",
|
|
24185
|
+
settled: Promise.resolve(this.refusal("the hold before the mesh join is full"))
|
|
24186
|
+
};
|
|
24187
|
+
}
|
|
24188
|
+
if (this.firstHeldAt === null) {
|
|
24189
|
+
this.firstHeldAt = this.now();
|
|
24190
|
+
this.timer = setTimeout(() => this.refuse("bound"), this.opts.maxHoldMs ?? 15e3);
|
|
24191
|
+
this.timer.unref?.();
|
|
24192
|
+
}
|
|
24193
|
+
return {
|
|
24194
|
+
verdict: "hold",
|
|
24195
|
+
settled: new Promise((resolve) => {
|
|
24196
|
+
this.waiters.push({
|
|
24197
|
+
kind,
|
|
24198
|
+
resolve
|
|
24199
|
+
});
|
|
24200
|
+
})
|
|
24201
|
+
};
|
|
24202
|
+
}
|
|
24203
|
+
/** The join proved the hub: deliver everything held, in order. */
|
|
24204
|
+
release() {
|
|
24205
|
+
this.open = false;
|
|
24206
|
+
this.settle({ verdict: "allow" }, "delivered", "authenticated");
|
|
24207
|
+
}
|
|
24208
|
+
/** The join failed, or the bound ran out: refuse everything held. */
|
|
24209
|
+
refuse(reason) {
|
|
24210
|
+
this.open = false;
|
|
24211
|
+
this.settle(this.refusal(`the join ended "${reason}"`), "refused", reason);
|
|
24212
|
+
}
|
|
24213
|
+
refusal(why) {
|
|
24214
|
+
return {
|
|
24215
|
+
verdict: "deny",
|
|
24216
|
+
errorType: MESH_NODE_UNAUTHENTICATED_TYPE,
|
|
24217
|
+
message: `"${this.opts.hubNodeId}" sent this before the mesh join settled, and ${why}`
|
|
24218
|
+
};
|
|
24219
|
+
}
|
|
24220
|
+
settle(verdict, outcome, reason) {
|
|
24221
|
+
if (this.timer !== null) clearTimeout(this.timer);
|
|
24222
|
+
this.timer = null;
|
|
24223
|
+
const waiters = this.waiters;
|
|
24224
|
+
const overflow = this.overflow;
|
|
24225
|
+
const firstHeldAt = this.firstHeldAt;
|
|
24226
|
+
this.waiters = [];
|
|
24227
|
+
this.overflow = 0;
|
|
24228
|
+
this.firstHeldAt = null;
|
|
24229
|
+
if (waiters.length === 0 && overflow === 0) return;
|
|
24230
|
+
for (const w of waiters) w.resolve(verdict);
|
|
24231
|
+
this.opts.onReport?.({
|
|
24232
|
+
outcome,
|
|
24233
|
+
reason,
|
|
24234
|
+
events: waiters.filter((w) => w.kind === "event").length,
|
|
24235
|
+
calls: waiters.filter((w) => w.kind === "call").length,
|
|
24236
|
+
overflow,
|
|
24237
|
+
heldForMs: firstHeldAt === null ? 0 : this.now() - firstHeldAt
|
|
24238
|
+
});
|
|
24239
|
+
}
|
|
24240
|
+
};
|
|
24241
|
+
//#endregion
|
|
24139
24242
|
//#region src/kernel/moleculer/agent-mesh-authenticator.ts
|
|
24140
24243
|
/** The child's register action on its parent agent. */
|
|
24141
24244
|
var AGENT_REGISTER_NODE_ACTION = "$agent.registerNode";
|
|
@@ -24155,10 +24258,22 @@ var AgentMeshAuthenticator = class {
|
|
|
24155
24258
|
nodes = /* @__PURE__ */ new Map();
|
|
24156
24259
|
hubNodeId;
|
|
24157
24260
|
now;
|
|
24261
|
+
hold;
|
|
24158
24262
|
constructor(deps) {
|
|
24159
24263
|
this.deps = deps;
|
|
24160
24264
|
this.hubNodeId = deps.hubNodeId ?? DEFAULT_HUB_NODE_ID;
|
|
24161
24265
|
this.now = deps.now ?? Date.now;
|
|
24266
|
+
this.hold = new MeshJoinHold({
|
|
24267
|
+
hubNodeId: this.hubNodeId,
|
|
24268
|
+
now: this.now,
|
|
24269
|
+
...deps.maxHeld !== void 0 ? { maxHeld: deps.maxHeld } : {},
|
|
24270
|
+
...deps.maxHoldMs !== void 0 ? { maxHoldMs: deps.maxHoldMs } : {},
|
|
24271
|
+
...deps.onHoldReport !== void 0 ? { onReport: deps.onHoldReport } : {}
|
|
24272
|
+
});
|
|
24273
|
+
}
|
|
24274
|
+
/** How many of the hub's requests wait for the join right now. */
|
|
24275
|
+
heldCount() {
|
|
24276
|
+
return this.hold.size;
|
|
24162
24277
|
}
|
|
24163
24278
|
/** Current mode: secret configured → enforce; else tolerate (upgrade path). */
|
|
24164
24279
|
mode() {
|
|
@@ -24172,9 +24287,16 @@ var AgentMeshAuthenticator = class {
|
|
|
24172
24287
|
noteHubJoinState(state) {
|
|
24173
24288
|
if (state === "authenticated") {
|
|
24174
24289
|
this.record(this.hubNodeId, "authenticated");
|
|
24290
|
+
this.hold.release();
|
|
24291
|
+
return;
|
|
24292
|
+
}
|
|
24293
|
+
if (state === "pending") {
|
|
24294
|
+
this.forget(this.hubNodeId);
|
|
24295
|
+
this.hold.reopen();
|
|
24175
24296
|
return;
|
|
24176
24297
|
}
|
|
24177
|
-
if (state === "secret-mismatch" || state === "hub-unverified"
|
|
24298
|
+
if (state === "secret-mismatch" || state === "hub-unverified") this.forget(this.hubNodeId);
|
|
24299
|
+
this.hold.refuse(state);
|
|
24178
24300
|
}
|
|
24179
24301
|
/** A child's `$agent.registerNode` was accepted (secret hash matched or none required). */
|
|
24180
24302
|
noteChildRegistered(sender, proof = "authenticated") {
|
|
@@ -24193,11 +24315,11 @@ var AgentMeshAuthenticator = class {
|
|
|
24193
24315
|
message: `"${action}" is not callable from another node (caller "${sender}")`
|
|
24194
24316
|
};
|
|
24195
24317
|
if (action === "$agent.registerNode" && isOwnChildNodeId(this.deps.ownNodeId, sender)) return { verdict: "allow" };
|
|
24196
|
-
return this.admitSender(sender, action);
|
|
24318
|
+
return this.admitSender(sender, action, "call");
|
|
24197
24319
|
}
|
|
24198
24320
|
admitEvent(sender, eventName) {
|
|
24199
24321
|
if (sender === this.deps.ownNodeId) return { verdict: "allow" };
|
|
24200
|
-
return this.admitSender(sender, `event:${eventName}
|
|
24322
|
+
return this.admitSender(sender, `event:${eventName}`, "event");
|
|
24201
24323
|
}
|
|
24202
24324
|
stateOf(nodeId) {
|
|
24203
24325
|
return this.nodes.get(nodeId)?.state ?? "unauthenticated";
|
|
@@ -24205,14 +24327,20 @@ var AgentMeshAuthenticator = class {
|
|
|
24205
24327
|
authenticatedNodeIds() {
|
|
24206
24328
|
return [...this.nodes].filter(([, r]) => r.state === "authenticated").map(([id]) => id);
|
|
24207
24329
|
}
|
|
24208
|
-
admitSender(sender, what) {
|
|
24330
|
+
admitSender(sender, what, kind) {
|
|
24209
24331
|
const state = this.stateOf(sender);
|
|
24210
24332
|
if (state === "authenticated" || state === "legacy") return { verdict: "allow" };
|
|
24211
|
-
if (this.mode() === "enforced")
|
|
24212
|
-
|
|
24213
|
-
|
|
24214
|
-
|
|
24215
|
-
|
|
24333
|
+
if (this.mode() === "enforced") {
|
|
24334
|
+
if (sender === this.hubNodeId) {
|
|
24335
|
+
const held = this.hold.hold(kind);
|
|
24336
|
+
if (held !== null) return held;
|
|
24337
|
+
}
|
|
24338
|
+
return {
|
|
24339
|
+
verdict: "deny",
|
|
24340
|
+
errorType: MESH_NODE_UNAUTHENTICATED_TYPE,
|
|
24341
|
+
message: `node "${sender}" has not authenticated to this agent — only the hub (after mutual mesh join) and this agent's own children may call it`
|
|
24342
|
+
};
|
|
24343
|
+
}
|
|
24216
24344
|
if (!this.nodes.has(sender)) {
|
|
24217
24345
|
this.record(sender, "unauthenticated");
|
|
24218
24346
|
this.deps.onTolerated?.(sender, what);
|
|
@@ -24232,6 +24360,40 @@ var AgentMeshAuthenticator = class {
|
|
|
24232
24360
|
}
|
|
24233
24361
|
};
|
|
24234
24362
|
//#endregion
|
|
24363
|
+
//#region src/kernel/moleculer/agent-event-scope.ts
|
|
24364
|
+
/** Moleculer's EVENT packet type (`packets.PACKET_EVENT`). */
|
|
24365
|
+
var PACKET_EVENT = "EVENT";
|
|
24366
|
+
/** Is this an event packet addressed to a node other than the hub? */
|
|
24367
|
+
function isPeerEventPacket(packet, hubNodeId) {
|
|
24368
|
+
return packet.type === PACKET_EVENT && packet.target !== null && packet.target !== hubNodeId;
|
|
24369
|
+
}
|
|
24370
|
+
function createAgentEventScope(opts) {
|
|
24371
|
+
let toHub = 0;
|
|
24372
|
+
const withheld = /* @__PURE__ */ new Map();
|
|
24373
|
+
const gate = (next) => function agentEventScoped(packet) {
|
|
24374
|
+
if (packet.type !== PACKET_EVENT) return next(packet);
|
|
24375
|
+
if (!isPeerEventPacket(packet, opts.hubNodeId)) {
|
|
24376
|
+
if (packet.target === opts.hubNodeId) toHub++;
|
|
24377
|
+
return next(packet);
|
|
24378
|
+
}
|
|
24379
|
+
const peer = packet.target ?? "";
|
|
24380
|
+
const prev = withheld.get(peer) ?? 0;
|
|
24381
|
+
withheld.set(peer, prev + 1);
|
|
24382
|
+
if (prev === 0) opts.log?.(`mesh events: not sending events to node "${peer}" — an agent's events go to the hub only (D848)`);
|
|
24383
|
+
return Promise.resolve();
|
|
24384
|
+
};
|
|
24385
|
+
return {
|
|
24386
|
+
middleware: {
|
|
24387
|
+
name: "CamstackAgentEventScope",
|
|
24388
|
+
transitPublish: gate
|
|
24389
|
+
},
|
|
24390
|
+
stats: () => ({
|
|
24391
|
+
toHub,
|
|
24392
|
+
withheld: Object.fromEntries(withheld)
|
|
24393
|
+
})
|
|
24394
|
+
};
|
|
24395
|
+
}
|
|
24396
|
+
//#endregion
|
|
24235
24397
|
//#region src/kernel/moleculer/mesh-join-client.ts
|
|
24236
24398
|
/** States in which a call to the hub is refused locally. */
|
|
24237
24399
|
var BLOCKING = new Set(["secret-mismatch", "hub-unverified"]);
|
|
@@ -26647,4 +26809,4 @@ var LifecycleJobEngine = class {
|
|
|
26647
26809
|
*/
|
|
26648
26810
|
var CAP_METHOD_NOT_IMPLEMENTED = "CAP_METHOD_NOT_IMPLEMENTED";
|
|
26649
26811
|
//#endregion
|
|
26650
|
-
export { ADMIN_TOKEN_MAX_LIFETIME_MS, ADMIN_TOKEN_PREFIX, AGENT_CAP_FWD_ACTION, AGENT_CAP_FWD_SERVICE, AGENT_DASHBOARD_ORIGINS_FIELD, AGENT_READINESS_SERVICE_NAME, AGENT_REGISTER_NODE_ACTION, AGENT_UI_UNLOCK_DOMAIN, AGENT_UI_UNLOCK_TTL_MS, AGENT_UI_UNLOCK_VERSION, ALL_CAPABILITY_DEFINITIONS, ARRAY_BUFFER_CENSUS_COOLDOWN_MS, ARRAY_BUFFER_CENSUS_SUSTAIN_MS, ARRAY_BUFFER_CENSUS_THRESHOLD_MB, ARRAY_BUFFER_RELEASE_MIN_DROP_RATIO, AddonApiFactory, AddonDepsManager, AddonEngineManager, AddonHealthMonitor, AddonInstaller, AddonLoader, AddonManifest, AddonRouteRegistry, AdminTokenManager, AgentMeshAuthenticator, AlertCenterAddon, ApiKeyManager, AuthAuditLog, AuthManager, BackupDecryptError, BackupKeyFormatError, BackupKeyMismatchError, BackupKeyRequiredError, CAP_ACTION_OVERFLOW_LABEL, CAP_ACTION_UNLABELLED, CAP_METHOD_NOT_IMPLEMENTED, CA_COMMON_NAME, CA_VALIDITY_DAYS, CLUSTER_SECRET_MISMATCH_TYPE, CLUSTER_SECRET_REF, CLUSTER_SECRET_REJECTED_EXIT_CODE, CLUSTER_SECRET_SETTINGS_KEY, CLUSTER_SECRET_UNAVAILABLE_TYPE, CORE_CAP_SERVICE_NAME, CalendarsAddon, CapRouteError, CapRouteResolver, CapUsageRegistry, CapabilityHandle, CapabilityRegistry, CapabilityUnavailableError, ComposerAddon, ConfigManager, ConfigStore, ConsoleDestination, ConsoleLoggingAddon, CoreBlocksAddon, CustomActionRegistry, DECISIVE_HEAP_SPACES, DEFAULT_DATA_PATH, DEFAULT_HUB_TLS_TCP_PORT, DEFAULT_LAN_HTTP_PORT, DEFAULT_LOG_LEVEL, DEVICE_SETTINGS_CONTRIBUTION_METHODS, DEVICE_STATUS_METHOD, DataPlaneRegistry, DeviceManagerAddon, DeviceRegistry, DeviceStore, EMPTY_CAP_ACTION_READING, EMPTY_SOCKET_DIRECTION, EMPTY_SOCKET_PLANE_BASELINE, EVENT_PLANE_TOP_N, EVENT_TOPIC_PREFIX, EngineManagerResolver, EventBus, FIRST_BOOT_ADMIN_PASSWORD, FIRST_BOOT_ADMIN_USERNAME, FeatureManager, FilesystemStorageAddon, FilesystemStorageProvider, FrameDecoder, FsStorageBackend, GET_STATUS_METHOD, HEALTH_MONITOR_GRACE_PERIOD_MS, HEALTH_MONITOR_RETRY_INTERVALS_MS, HEALTH_MONITOR_TICK_MS, HEAP_RECLAIM_MIN_INTERVAL_MS, HEAP_RECLAIM_STEADY_STATE_INTERVAL_MS, HEAP_RECLAIM_TRIGGER_MB, HEAP_SPACE_REPORT_MIN_MB, HEAP_WATCH_INTERVAL_MS, HEAP_WATCH_WARN_RATIO, HUB_CAP_FWD_ACTION, HUB_CAP_FWD_SERVICE, HUB_MAIN_HEAP_WATCH_LABEL, HUB_MAIN_RSS_BUDGET_MB, HUB_RSS_BUDGET_ENV, HubForwarderAddon, HubForwarderDestination, HubLogForwarder, HubNodeRegistry, INFRA_CAPABILITIES, IntegrationRegistry, JWT_SIGNING_KEY_REF, JobJournal, JoinTokenJtiStore, JwtSigningKeyUnavailableError, LEAF_RENEWAL_WINDOW_DAYS, LifecycleJobEngine, LifecycleStateMachine, LivenessMonitorAddon, LocalAuthAddon, LocalChildClient, LocalChildRegistry, LogManager, LogRingBuffer, LoggingGate, LoginSessionManager, LokiDestination, LokiLoggingAddon, MAX_CAP_ACTIONS_PER_PEER, MAX_LEAF_VALIDITY_DAYS, MESH_ACTION_FORBIDDEN_TYPE, MESH_AUTH_MODE_FIELD, MESH_AUTO_ENFORCE_GRACE_MS, MESH_CA_FIELD, MESH_CA_KEY_REF, MESH_CA_SETTINGS_KEY, MESH_JOIN_AUTHENTICATE_ACTION, MESH_JOIN_CHALLENGE_ACTION, MESH_JOIN_CHALLENGE_INVALID_TYPE, MESH_JOIN_CHALLENGE_TTL_MS, MESH_JOIN_PROTOCOL, MESH_NODE_UNAUTHENTICATED_TYPE, MESH_QUEUE_TOP_N, METHOD_ACCESS_MAP, MeshAuthenticator, MeshCaKeeper, MeshCrl, MeshJoinClient, ModelDownloadService, NATIVE_PROVIDER_SERVICE_INFIX, NATIVE_SCAN_DEPTH, NativeMetricsAddon, NativeMetricsProvider, NetworkQualityTracker, NotificationService, OUTBOUND_QUEUE_COOLDOWN_MS, OUTBOUND_QUEUE_SUSTAIN_MS, OUTBOUND_QUEUE_THRESHOLD_BYTES, PARENT_ROUTED_PROVIDER_ADDON_ID, PYTHON_VERSION, PeerAnsweredError, PipelineRunner, PipelineValidator, PythonEnvManager, QUARANTINE_DIRNAME, REFRESH_TOKEN_PREFIX, RESTART_MARKER_FILE, RSS_BUDGET_REANNOUNCE_MIN_MS, RSS_BUDGET_RELEASE_RATIO, RUNNER_HEAP_WATCH_INTERVAL_MS, RUNNER_RSS_BUDGET_ENV, RUNTIME_DEFAULTS, ReadinessRegistry, ReadinessTimeoutError, ReplEngine, RingBuffer, SERVER_AUTH_OID, SOCKET_PLANE_TOP_N, SOCKET_QUEUE_TOP_N, STALL_REPORT_MS, STALL_TICK_MS, STORE_READABLE_BOOTSTRAP_KEYS, SYSTEM_SECRET_OWNER, ScopedLogger, ScopedTokenManager, SettingsReadUnavailableError, SocketChannel, SqliteSettingsAddon, SqliteSettingsBackend, StagingArea, StorageLocationManager, StorageManager, StorageOrchestratorAddon, StorageOrchestratorService, SystemBackupService, SystemConfigAddon, SystemEventBus, TRADITIONAL_NATIVE_PACKAGES, TlsTcpTransporter, ToastService, UDS_NO_ROUTE_PREFIX, UNCLAIMED, UPLOADED_CA_FILE, USER_MANAGEMENT_INTERNAL, UdsLocalTransportClient, UdsLocalTransportServer, UnlockTicketJtiStore, UserManager, WinstonDestination, WinstonLoggingAddon, ZERO_LOOP_DELAY, __resetCapUsageRegistryForTests, __resetLoggingGateForTests, adaptBrokerToCluster, addonSettingsCapability, adoptModelRevisions, afterWorkerOnlineAnnounce, allFamiliesListenHost, answerClaimedGetStatus, applyCertificateToListener, applyLanHttp, attachUserManagementInternal, attributeStall, bindPendingLanHttp, bootstrapSchema, brokerCallForCap, brokerTransportLink, buildBinaryPath, buildCapRouters, buildHeapSample, buildLinkChain, buildNativeCapProxy, buildNodeManifest, buildNpmChildEnv, buildStorageLocationRegistry, builderMountedCapNames, caFingerprint, caFingerprintCompact, callRegisterNodeWithRetry, callWithServiceDiscovery, canServeDataPlane, capActionLabel, capActionName, capActionSuffix, capBareAction, capServiceName, checkClusterSecret, classifyAddonDir, classifyCapRoute, clearHttpsListener, clearPendingRestart, clearPlatformKeychainKey, closeLanHttp, clusterEventTopic, clusterSecretMatches, collectCertIdentity, collectModelFiles, computeHubJoinProof, computeNodeJoinProof, contentTypeFor, copyDirRecursive, copyExtraFileDirs, createAddonContext, createAddonDataPlaneFacility, createAddonPeerBytesFacility, createAddonService, createArrayBufferCensusGate, createAuthenticatedFileServer, createBroker, createBrokerDeviceManagerApi, createCapActionCensus, createCidrMatcher, createCoreCapService, createDeferredHeapWatchSink, createDoorSettingsView, createEventPlaneMeter, createEventPlaneReader, createFileDataPlaneHandler, createHubCapForwardService, createHubService, createInspectorArrayBufferCensus, createKernelHwAccel, createKernelInferenceEngine, createLocalTransport, createLoopDelayMeter, createMeshAccessMiddleware, createMeshCsrPem, createMeshQueueReader, createOutboundQueueGate, createParentUnownedCallHandler, createProcessService, createReadinessService, createReadinessServiceForRegistry, createScopedProcessManager, createSocketDirectionCounters, createSocketPlaneMeter, createSocketPlaneReader, createStreamProbeBrokerService, createUdsAddonContext, createUdsEventBridge, createUdsEventBus, createUdsLogger, createUdsLoggerWithControl, createV8Reclaimer, decideMeshAutoEnforce, deleteModelFromDisk, deriveAgentListenPort, describeProviderKindDrift, describeRss, detectWorkspacePackagesDir, deviceCapResolverLink, deviceOfGetStatus, diffCapActionCensus, diffEventPlane, diffSocketPlane, downloadBinary, downloadFile, downloadModel, emitDownForOwnedCaps, emitHeapDiagnosticReport, encodeFrame, enrollMeshNode, ensureAddonNativePrebuilds, ensureBinary, ensureDir, ensureFfmpeg, ensureLibraryBuilt, ensureModel, ensureNativePrebuilds, ensurePython, ensureTlsCert, evaluateExistingCert, expandCapMethods, exportMeshPrivateKeyPem, fetchJson, findInPath, formatArrayBufferCensus, formatEventPlane, formatHeapSpaces, formatLogLine, formatMeshQueue, formatOutboundQueueVerdict, formatSocketPlane, generateBackupKeyPair, generateMeshCa, generateMeshKeyPair, getBrokerEventBus, getBrokerTlsTransporter, getCapUsageRegistry, getFfmpegDownloadUrl, getLoggingGate, getModelFilePath, getMoleculerEventStats, getOrInitReadinessRegistry, getOrInitReadinessRegistryForClient, getPidStats, getPlatformInfo, getPlatformKeychainKey, getProcessClusterSecretGate, getProcessJwtSigningKeyState, getProcessMeshAuthMode, getProcessMeshAuthStatus, getProcessMeshCaState, getProcessNodeMeshTransport, getPythonDownloadUrl, getRestartMarkerPath, getSinglePidStats, getUserManagementInternal, getWorkerDeviceRegistry, hasDotNode, hashClusterSecret, heapSpaceField, hostNodeIdOf, hubMainRssBudget, installManifestNativeDeps, installManifestPythonDeps, installManifestSystemDeps, installPackageFromNpm, installPythonPackages, installPythonRequirements, ipcParentLink, isAddonDeploySource, isAllowedAgentDashboardReturnTo, isArrayBufferCensusReport, isArrayOutputSchema, isClusterSecretMismatchError, isCollectionArrayMethod, isCredentialKeyName, isInfraCapability, isMeshAuthMode, isModelDownloaded, isOwnChildNodeId, isRemoteForbiddenAction, isRemoteForbiddenOnAgent, isSettingsReadUnavailable, isSourceNewer, isolatedBuiltinPhase, issueMeshLeafForNode, issueMeshLeafFromCsr, leafFingerprintOf, loadMeshCa, loadTlsCert, localEndpointPath, localProviderLink, localSupportedPythonRuntimes, mapSignalsToInferenceHardware, meshErrorType, mintAgentUiUnlockTicket, mintMeshJoinToken, mountNativeCapService, nextRssBudgetState, normalizeIp, overlayGetStatus, parseAgentDashboardOrigins, parseCapAction, parseCidrList, parseMeshAuthMode, parseRangeHeader, parseRssBudgetMb, parseTokenExpiry, parseTokenizedUrl, partitionIsolatedBuiltinIds, prepareBootTls, prepareRestoreArchive, probePlatform, processJoinTokenJtiStore, processJwtSigningKey, processMeshCrl, proxyToUpstream, quarantineAddonResidue, readBackupEncryptionHeader, readCidrSetting, readExtraSans, readHeapSpaces, readLanHttpState, readPendingRestart, readSocketQueues, readTlsAccessStatus, readTlsMode, readinessKey, reclaimIntervalMs, recordSocketFrame, redactLogEntry, redactLogMeta, redactLogText, regenerateCertificate, registerEventBusService, registerHttpsListener, registerLanHttpHandler, reissueTlsLeaf, reloadHttpsListener, requestProcessMeshEnforcement, requireProcessMeshCa, resolveFilePath, resolveFormatRevision, resolveHwAccel, resolveNpmInvocation, revertToGeneratedCertificate, revisionWeightUrl, runHubAddonBoot, runNpm, sampleSocketDirection, scheduleSelfRestart, scopeKey, scopesAllowAddon, scopesAllowDeviceCap, selectAddonResidue, selectReportedSpaces, serializeTypedArrays, servedHttpsLeafFingerprint, setHubConnected, setNodeEventInterest, setPlatformKeychainKey, setProcessClusterSecretGate, setProcessMeshAuthMode, setProcessMeshAuthStatusSource, setProcessMeshEnforcer, setProcessMeshPeerTransportLookup, setProcessMeshTlsEnabler, setWrapperActive, shouldReclaim, signalAllRunnerGroups, socketDirectionBytes, socketDirectionMessages, splitPemCertificates, stampCallerAddonId, startEventLoopStallMonitor, startHeapWatch, startRunnerHeapWatch, staticJwtSigningKey, storeMayAnswer, storeUploadedCertificate, strandedMb, stripCamstackDeps, stripForgedIdentity, stripForwardedCaller, subscribePassthrough, udsChildLogToWorkerEntry, validateProviderRegistrations, validateUploadedTls, verifyAgentUiUnlockTicket, verifyMeshJoinToken, waitUntilReady, writeExtraSans, writePendingRestart, writeTlsMode };
|
|
26812
|
+
export { ADMIN_TOKEN_MAX_LIFETIME_MS, ADMIN_TOKEN_PREFIX, AGENT_CAP_FWD_ACTION, AGENT_CAP_FWD_SERVICE, AGENT_DASHBOARD_ORIGINS_FIELD, AGENT_READINESS_SERVICE_NAME, AGENT_REGISTER_NODE_ACTION, AGENT_UI_UNLOCK_DOMAIN, AGENT_UI_UNLOCK_TTL_MS, AGENT_UI_UNLOCK_VERSION, ALL_CAPABILITY_DEFINITIONS, ARRAY_BUFFER_CENSUS_COOLDOWN_MS, ARRAY_BUFFER_CENSUS_SUSTAIN_MS, ARRAY_BUFFER_CENSUS_THRESHOLD_MB, ARRAY_BUFFER_RELEASE_MIN_DROP_RATIO, AddonApiFactory, AddonDepsManager, AddonEngineManager, AddonHealthMonitor, AddonInstaller, AddonLoader, AddonManifest, AddonRouteRegistry, AdminTokenManager, AgentMeshAuthenticator, AlertCenterAddon, ApiKeyManager, AuthAuditLog, AuthManager, BackupDecryptError, BackupKeyFormatError, BackupKeyMismatchError, BackupKeyRequiredError, CAP_ACTION_OVERFLOW_LABEL, CAP_ACTION_UNLABELLED, CAP_METHOD_NOT_IMPLEMENTED, CA_COMMON_NAME, CA_VALIDITY_DAYS, CLUSTER_SECRET_MISMATCH_TYPE, CLUSTER_SECRET_REF, CLUSTER_SECRET_REJECTED_EXIT_CODE, CLUSTER_SECRET_SETTINGS_KEY, CLUSTER_SECRET_UNAVAILABLE_TYPE, CORE_CAP_SERVICE_NAME, CalendarsAddon, CapRouteError, CapRouteResolver, CapUsageRegistry, CapabilityHandle, CapabilityRegistry, CapabilityUnavailableError, ComposerAddon, ConfigManager, ConfigStore, ConsoleDestination, ConsoleLoggingAddon, CoreBlocksAddon, CustomActionRegistry, DECISIVE_HEAP_SPACES, DEFAULT_DATA_PATH, DEFAULT_HUB_TLS_TCP_PORT, DEFAULT_LAN_HTTP_PORT, DEFAULT_LOG_LEVEL, DEFAULT_MESH_JOIN_MAX_HELD, DEFAULT_MESH_JOIN_MAX_HOLD_MS, DEVICE_SETTINGS_CONTRIBUTION_METHODS, DEVICE_STATUS_METHOD, DataPlaneRegistry, DeviceManagerAddon, DeviceRegistry, DeviceStore, EMPTY_CAP_ACTION_READING, EMPTY_SOCKET_DIRECTION, EMPTY_SOCKET_PLANE_BASELINE, EVENT_PLANE_TOP_N, EVENT_TOPIC_PREFIX, EngineManagerResolver, EventBus, FIRST_BOOT_ADMIN_PASSWORD, FIRST_BOOT_ADMIN_USERNAME, FeatureManager, FilesystemStorageAddon, FilesystemStorageProvider, FrameDecoder, FsStorageBackend, GET_STATUS_METHOD, HEALTH_MONITOR_GRACE_PERIOD_MS, HEALTH_MONITOR_RETRY_INTERVALS_MS, HEALTH_MONITOR_TICK_MS, HEAP_RECLAIM_MIN_INTERVAL_MS, HEAP_RECLAIM_STEADY_STATE_INTERVAL_MS, HEAP_RECLAIM_TRIGGER_MB, HEAP_SPACE_REPORT_MIN_MB, HEAP_WATCH_INTERVAL_MS, HEAP_WATCH_WARN_RATIO, HUB_CAP_FWD_ACTION, HUB_CAP_FWD_SERVICE, HUB_MAIN_HEAP_WATCH_LABEL, HUB_MAIN_RSS_BUDGET_MB, HUB_RSS_BUDGET_ENV, HubForwarderAddon, HubForwarderDestination, HubLogForwarder, HubNodeRegistry, INFRA_CAPABILITIES, IntegrationRegistry, JWT_SIGNING_KEY_REF, JobJournal, JoinTokenJtiStore, JwtSigningKeyUnavailableError, LEAF_RENEWAL_WINDOW_DAYS, LifecycleJobEngine, LifecycleStateMachine, LivenessMonitorAddon, LocalAuthAddon, LocalChildClient, LocalChildRegistry, LogManager, LogRingBuffer, LoggingGate, LoginSessionManager, LokiDestination, LokiLoggingAddon, MAX_CAP_ACTIONS_PER_PEER, MAX_LEAF_VALIDITY_DAYS, MESH_ACTION_FORBIDDEN_TYPE, MESH_AUTH_MODE_FIELD, MESH_AUTO_ENFORCE_GRACE_MS, MESH_CA_FIELD, MESH_CA_KEY_REF, MESH_CA_SETTINGS_KEY, MESH_JOIN_AUTHENTICATE_ACTION, MESH_JOIN_CHALLENGE_ACTION, MESH_JOIN_CHALLENGE_INVALID_TYPE, MESH_JOIN_CHALLENGE_TTL_MS, MESH_JOIN_PROTOCOL, MESH_NODE_UNAUTHENTICATED_TYPE, MESH_QUEUE_TOP_N, MESH_TLS_PORT_HELLO_FIELD, METHOD_ACCESS_MAP, MeshAuthenticator, MeshCaKeeper, MeshCrl, MeshJoinClient, MeshJoinHold, ModelDownloadService, NATIVE_PROVIDER_SERVICE_INFIX, NATIVE_SCAN_DEPTH, NativeMetricsAddon, NativeMetricsProvider, NetworkQualityTracker, NotificationService, OUTBOUND_QUEUE_COOLDOWN_MS, OUTBOUND_QUEUE_SUSTAIN_MS, OUTBOUND_QUEUE_THRESHOLD_BYTES, PARENT_ROUTED_PROVIDER_ADDON_ID, PYTHON_VERSION, PeerAnsweredError, PipelineRunner, PipelineValidator, PythonEnvManager, QUARANTINE_DIRNAME, REFRESH_TOKEN_PREFIX, RESTART_MARKER_FILE, RSS_BUDGET_REANNOUNCE_MIN_MS, RSS_BUDGET_RELEASE_RATIO, RUNNER_HEAP_WATCH_INTERVAL_MS, RUNNER_RSS_BUDGET_ENV, RUNTIME_DEFAULTS, ReadinessRegistry, ReadinessTimeoutError, ReplEngine, RingBuffer, SERVER_AUTH_OID, SOCKET_PLANE_TOP_N, SOCKET_QUEUE_TOP_N, STALL_REPORT_MS, STALL_TICK_MS, STORE_READABLE_BOOTSTRAP_KEYS, SYSTEM_SECRET_OWNER, ScopedLogger, ScopedTokenManager, SettingsReadUnavailableError, SocketChannel, SqliteSettingsAddon, SqliteSettingsBackend, StagingArea, StorageLocationManager, StorageManager, StorageOrchestratorAddon, StorageOrchestratorService, SystemBackupService, SystemConfigAddon, SystemEventBus, TRADITIONAL_NATIVE_PACKAGES, TlsTcpTransporter, ToastService, UDS_NO_ROUTE_PREFIX, UNCLAIMED, UPLOADED_CA_FILE, USER_MANAGEMENT_INTERNAL, UdsLocalTransportClient, UdsLocalTransportServer, UnlockTicketJtiStore, UserManager, WinstonDestination, WinstonLoggingAddon, ZERO_LOOP_DELAY, __resetCapUsageRegistryForTests, __resetLoggingGateForTests, adaptBrokerToCluster, addonSettingsCapability, adoptModelRevisions, afterWorkerOnlineAnnounce, allFamiliesListenHost, answerClaimedGetStatus, applyCertificateToListener, applyLanHttp, attachUserManagementInternal, attributeStall, bindPendingLanHttp, bootstrapSchema, brokerCallForCap, brokerTransportLink, buildBinaryPath, buildCapRouters, buildHeapSample, buildLinkChain, buildNativeCapProxy, buildNodeManifest, buildNpmChildEnv, buildStorageLocationRegistry, builderMountedCapNames, caFingerprint, caFingerprintCompact, callRegisterNodeWithRetry, callWithServiceDiscovery, canServeDataPlane, capActionLabel, capActionName, capActionSuffix, capBareAction, capServiceName, checkClusterSecret, classifyAddonDir, classifyCapRoute, clearHttpsListener, clearPendingRestart, clearPlatformKeychainKey, closeLanHttp, clusterEventTopic, clusterSecretMatches, collectCertIdentity, collectModelFiles, computeHubJoinProof, computeNodeJoinProof, contentTypeFor, copyDirRecursive, copyExtraFileDirs, createAddonContext, createAddonDataPlaneFacility, createAddonPeerBytesFacility, createAddonService, createAgentEventScope, createArrayBufferCensusGate, createAuthenticatedFileServer, createBroker, createBrokerDeviceManagerApi, createCapActionCensus, createCidrMatcher, createCoreCapService, createDeferredHeapWatchSink, createDoorSettingsView, createEventPlaneMeter, createEventPlaneReader, createFileDataPlaneHandler, createHubCapForwardService, createHubService, createInspectorArrayBufferCensus, createKernelHwAccel, createKernelInferenceEngine, createLocalTransport, createLoopDelayMeter, createMeshAccessMiddleware, createMeshCsrPem, createMeshQueueReader, createOutboundQueueGate, createParentUnownedCallHandler, createProcessService, createReadinessService, createReadinessServiceForRegistry, createScopedProcessManager, createSocketDirectionCounters, createSocketPlaneMeter, createSocketPlaneReader, createStreamProbeBrokerService, createUdsAddonContext, createUdsEventBridge, createUdsEventBus, createUdsLogger, createUdsLoggerWithControl, createV8Reclaimer, decideMeshAutoEnforce, deleteModelFromDisk, deriveAgentListenPort, describeProviderKindDrift, describeRss, detectWorkspacePackagesDir, deviceCapResolverLink, deviceOfGetStatus, diffCapActionCensus, diffEventPlane, diffSocketPlane, downloadBinary, downloadFile, downloadModel, emitDownForOwnedCaps, emitHeapDiagnosticReport, encodeFrame, enrollMeshNode, ensureAddonNativePrebuilds, ensureBinary, ensureDir, ensureFfmpeg, ensureLibraryBuilt, ensureModel, ensureNativePrebuilds, ensurePython, ensureTlsCert, evaluateExistingCert, expandCapMethods, exportMeshPrivateKeyPem, fetchJson, findInPath, formatArrayBufferCensus, formatEventPlane, formatHeapSpaces, formatLogLine, formatMeshQueue, formatOutboundQueueVerdict, formatSocketPlane, generateBackupKeyPair, generateMeshCa, generateMeshKeyPair, getBrokerEventBus, getBrokerTlsTransporter, getCapUsageRegistry, getFfmpegDownloadUrl, getLoggingGate, getModelFilePath, getMoleculerEventStats, getOrInitReadinessRegistry, getOrInitReadinessRegistryForClient, getPidStats, getPlatformInfo, getPlatformKeychainKey, getProcessClusterSecretGate, getProcessJwtSigningKeyState, getProcessMeshAuthMode, getProcessMeshAuthStatus, getProcessMeshCaState, getProcessNodeMeshTransport, getPythonDownloadUrl, getRestartMarkerPath, getSinglePidStats, getUserManagementInternal, getWorkerDeviceRegistry, hasDotNode, hashClusterSecret, heapSpaceField, hostNodeIdOf, hubMainRssBudget, installManifestNativeDeps, installManifestPythonDeps, installManifestSystemDeps, installPackageFromNpm, installPythonPackages, installPythonRequirements, ipcParentLink, isAddonDeploySource, isAllowedAgentDashboardReturnTo, isArrayBufferCensusReport, isArrayOutputSchema, isClusterSecretMismatchError, isCollectionArrayMethod, isCredentialKeyName, isInfraCapability, isMeshAuthMode, isModelDownloaded, isOwnChildNodeId, isPeerEventPacket, isRemoteForbiddenAction, isRemoteForbiddenOnAgent, isSettingsReadUnavailable, isSourceNewer, isolatedBuiltinPhase, issueMeshLeafForNode, issueMeshLeafFromCsr, leafFingerprintOf, loadMeshCa, loadTlsCert, localEndpointPath, localProviderLink, localSupportedPythonRuntimes, mapSignalsToInferenceHardware, meshErrorType, mintAgentUiUnlockTicket, mintMeshJoinToken, mountNativeCapService, nextRssBudgetState, normalizeIp, overlayGetStatus, parseAgentDashboardOrigins, parseCapAction, parseCidrList, parseMeshAuthMode, parseRangeHeader, parseRssBudgetMb, parseTokenExpiry, parseTokenizedUrl, partitionIsolatedBuiltinIds, prepareBootTls, prepareRestoreArchive, probePlatform, processJoinTokenJtiStore, processJwtSigningKey, processMeshCrl, proxyToUpstream, quarantineAddonResidue, readBackupEncryptionHeader, readCidrSetting, readExtraSans, readHeapSpaces, readLanHttpState, readPendingRestart, readSocketQueues, readTlsAccessStatus, readTlsMode, readinessKey, reclaimIntervalMs, recordSocketFrame, redactLogEntry, redactLogMeta, redactLogText, regenerateCertificate, registerEventBusService, registerHttpsListener, registerLanHttpHandler, reissueTlsLeaf, reloadHttpsListener, requestProcessMeshEnforcement, requireProcessMeshCa, resolveFilePath, resolveFormatRevision, resolveHwAccel, resolveNpmInvocation, revertToGeneratedCertificate, revisionWeightUrl, runHubAddonBoot, runNpm, sampleSocketDirection, scheduleSelfRestart, scopeKey, scopesAllowAddon, scopesAllowDeviceCap, selectAddonResidue, selectReportedSpaces, serializeTypedArrays, servedHttpsLeafFingerprint, setHubConnected, setNodeEventInterest, setPlatformKeychainKey, setProcessClusterSecretGate, setProcessMeshAuthMode, setProcessMeshAuthStatusSource, setProcessMeshEnforcer, setProcessMeshPeerTransportLookup, setProcessMeshTlsEnabler, setWrapperActive, shouldReclaim, signalAllRunnerGroups, socketDirectionBytes, socketDirectionMessages, splitPemCertificates, stampCallerAddonId, startEventLoopStallMonitor, startHeapWatch, startRunnerHeapWatch, staticJwtSigningKey, storeMayAnswer, storeUploadedCertificate, strandedMb, stripCamstackDeps, stripForgedIdentity, stripForwardedCaller, subscribePassthrough, udsChildLogToWorkerEntry, validateProviderRegistrations, validateUploadedTls, verifyAgentUiUnlockTicket, verifyMeshJoinToken, waitUntilReady, writeExtraSans, writePendingRestart, writeTlsMode };
|
package/dist/kernel/index.d.ts
CHANGED
|
@@ -39,7 +39,7 @@ export { buildStorageLocationRegistry } from "./storage-location-registry.js";
|
|
|
39
39
|
export type { StorageLocationRegistry } from "./storage-location-registry.js";
|
|
40
40
|
export { createBroker, deriveAgentListenPort, getBrokerTlsTransporter } from "./moleculer/broker-factory.js";
|
|
41
41
|
export type { BrokerConfig } from "./moleculer/broker-factory.js";
|
|
42
|
-
export { caFingerprint, caFingerprintCompact, createMeshCsrPem, enrollMeshNode, exportMeshPrivateKeyPem, getProcessNodeMeshTransport, setProcessMeshPeerTransportLookup, generateMeshCa, generateMeshKeyPair, getProcessMeshCaState, issueMeshLeafForNode, issueMeshLeafFromCsr, JoinTokenJtiStore, loadMeshCa, MESH_CA_FIELD, MESH_CA_KEY_REF, MESH_CA_SETTINGS_KEY, MeshCaKeeper, MeshCrl, mintMeshJoinToken, processMeshCrl, processJoinTokenJtiStore, requireProcessMeshCa, setProcessMeshTlsEnabler, TlsTcpTransporter, verifyMeshJoinToken, DEFAULT_HUB_TLS_TCP_PORT } from "./moleculer/mesh-mtls/index.js";
|
|
42
|
+
export { caFingerprint, caFingerprintCompact, createMeshCsrPem, enrollMeshNode, exportMeshPrivateKeyPem, getProcessNodeMeshTransport, setProcessMeshPeerTransportLookup, generateMeshCa, generateMeshKeyPair, getProcessMeshCaState, issueMeshLeafForNode, issueMeshLeafFromCsr, JoinTokenJtiStore, loadMeshCa, MESH_CA_FIELD, MESH_CA_KEY_REF, MESH_CA_SETTINGS_KEY, MeshCaKeeper, MeshCrl, mintMeshJoinToken, processMeshCrl, processJoinTokenJtiStore, requireProcessMeshCa, setProcessMeshTlsEnabler, TlsTcpTransporter, verifyMeshJoinToken, DEFAULT_HUB_TLS_TCP_PORT, MESH_TLS_PORT_HELLO_FIELD } from "./moleculer/mesh-mtls/index.js";
|
|
43
43
|
export type { MeshCaSigner, MeshEnrollResult, MeshPeerTransportLookup, MeshTransport, MeshJoinTokenClaims, MeshTlsMaterial } from "./moleculer/mesh-mtls/index.js";
|
|
44
44
|
export { type AddonDeploySource, isAddonDeploySource } from "./moleculer/addon-deploy-source.js";
|
|
45
45
|
export { createAddonService, validateProviderRegistrations } from "./moleculer/addon-service-factory.js";
|
|
@@ -62,6 +62,10 @@ export { createMeshAccessMiddleware, stripForgedIdentity } from "./moleculer/mes
|
|
|
62
62
|
export type { MeshAccessMiddlewareOptions, MeshCallGate } from "./moleculer/mesh-access-middleware.js";
|
|
63
63
|
export { AgentMeshAuthenticator, AGENT_REGISTER_NODE_ACTION, isOwnChildNodeId, isRemoteForbiddenOnAgent } from "./moleculer/agent-mesh-authenticator.js";
|
|
64
64
|
export type { AgentMeshAuthenticatorDeps } from "./moleculer/agent-mesh-authenticator.js";
|
|
65
|
+
export { DEFAULT_MESH_JOIN_MAX_HELD, DEFAULT_MESH_JOIN_MAX_HOLD_MS, MeshJoinHold } from "./moleculer/mesh-join-hold.js";
|
|
66
|
+
export type { MeshGateVerdict, MeshHeldKind, MeshHeldVerdict, MeshJoinHoldOptions, MeshJoinHoldReport } from "./moleculer/mesh-join-hold.js";
|
|
67
|
+
export { createAgentEventScope, isPeerEventPacket } from "./moleculer/agent-event-scope.js";
|
|
68
|
+
export type { AgentEventScope, AgentEventScopeOptions, AgentEventScopeStats, OutboundPacket, TransitPublish } from "./moleculer/agent-event-scope.js";
|
|
65
69
|
export { MeshJoinClient } from "./moleculer/mesh-join-client.js";
|
|
66
70
|
export type { MeshJoinCall, MeshJoinClientOptions, MeshJoinState } from "./moleculer/mesh-join-client.js";
|
|
67
71
|
export { computeHubJoinProof, computeNodeJoinProof, meshErrorType, MESH_ACTION_FORBIDDEN_TYPE, MESH_JOIN_AUTHENTICATE_ACTION, MESH_JOIN_CHALLENGE_ACTION, MESH_JOIN_CHALLENGE_INVALID_TYPE, MESH_JOIN_PROTOCOL, MESH_NODE_UNAUTHENTICATED_TYPE } from "./moleculer/mesh-join-proof.js";
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An agent's events go to the hub, and to no other node (D848).
|
|
3
|
+
*
|
|
4
|
+
* `getBrokerEventBus(...).emit` broadcasts `camstack.evt.<cat>` to every node
|
|
5
|
+
* whose `$event-bus` subscribes to it — and every node's does
|
|
6
|
+
* (`camstack.evt.**`). On an agent that meant every telemetry event
|
|
7
|
+
* (`pipeline.inference-result`, `pipeline.trace`, `motion.*`: ~3,000/min per
|
|
8
|
+
* agent on the 2026-10-13 cluster) was also written to every PEER agent, in
|
|
9
|
+
* clear text, where the peer's inbound gate (`AgentMeshAuthenticator`, D802)
|
|
10
|
+
* refused it by design: only the hub may send an agent anything. The bytes
|
|
11
|
+
* were paid for nothing.
|
|
12
|
+
*
|
|
13
|
+
* This middleware stops them at the source: an EVENT packet an agent
|
|
14
|
+
* publishes to any node other than the hub is not written. Nothing a peer
|
|
15
|
+
* agent receives changes — it refused every such packet already — and the
|
|
16
|
+
* hub, the only consumer, still gets every event. A packet to the agent's own
|
|
17
|
+
* node id never reaches the transport (Moleculer delivers it in-process).
|
|
18
|
+
*
|
|
19
|
+
* Counted, never silent: {@link AgentEventScope.stats} reports what was held
|
|
20
|
+
* back per peer, and the first event withheld from each peer is logged.
|
|
21
|
+
*/
|
|
22
|
+
import type { Middleware } from "moleculer";
|
|
23
|
+
/** The part of a Moleculer `Packet` this gate reads. */
|
|
24
|
+
export interface OutboundPacket {
|
|
25
|
+
readonly type: string;
|
|
26
|
+
readonly target: string | null;
|
|
27
|
+
}
|
|
28
|
+
/** `Transit.publish` — what a `transitPublish` hook wraps. */
|
|
29
|
+
export type TransitPublish = (packet: OutboundPacket) => Promise<unknown>;
|
|
30
|
+
export interface AgentEventScopeOptions {
|
|
31
|
+
/** The only node an agent's events are written to. */
|
|
32
|
+
readonly hubNodeId: string;
|
|
33
|
+
/** Told once per peer, the first time an event to it is withheld. */
|
|
34
|
+
readonly log?: (message: string) => void;
|
|
35
|
+
}
|
|
36
|
+
export interface AgentEventScopeStats {
|
|
37
|
+
/** EVENT packets written to the hub. */
|
|
38
|
+
readonly toHub: number;
|
|
39
|
+
/** EVENT packets withheld, per peer node id. */
|
|
40
|
+
readonly withheld: Readonly<Record<string, number>>;
|
|
41
|
+
}
|
|
42
|
+
export interface AgentEventScope {
|
|
43
|
+
/** Pass to `createBroker({ middlewares })` on every agent broker. */
|
|
44
|
+
readonly middleware: Middleware;
|
|
45
|
+
stats(): AgentEventScopeStats;
|
|
46
|
+
}
|
|
47
|
+
/** Is this an event packet addressed to a node other than the hub? */
|
|
48
|
+
export declare function isPeerEventPacket(packet: OutboundPacket, hubNodeId: string): boolean;
|
|
49
|
+
export declare function createAgentEventScope(opts: AgentEventScopeOptions): AgentEventScope;
|
|
@@ -17,6 +17,10 @@
|
|
|
17
17
|
* cluster secret, `transition` when it does not — so an upgrading agent
|
|
18
18
|
* without a secret still serves the hub.
|
|
19
19
|
*
|
|
20
|
+
* The hub's requests that arrive while a join is in flight are HELD, not
|
|
21
|
+
* refused (D848 §3, {@link MeshJoinHold}): delivered when the join proves the
|
|
22
|
+
* hub, refused and reported when it fails or the bound runs out.
|
|
23
|
+
*
|
|
20
24
|
* Unlike the hub gate, `$process.*` is allowed from an authenticated hub:
|
|
21
25
|
* the hub polls `$process.list` on agents. `$node.*` stays forbidden from
|
|
22
26
|
* every remote peer. Forged `caller` / `callerAddonId` are stripped by the
|
|
@@ -26,8 +30,8 @@
|
|
|
26
30
|
* (`docs/design/2026-10-09-mesh-mtls-plan.md`) — same residual as the hub.
|
|
27
31
|
*/
|
|
28
32
|
import type { MeshAuthMode, MeshNodeAuthState } from "./mesh-auth-mode.js";
|
|
29
|
-
import type { MeshCallVerdict } from "./mesh-authenticator.js";
|
|
30
33
|
import type { MeshJoinState } from "./mesh-join-client.js";
|
|
34
|
+
import { type MeshGateVerdict, type MeshJoinHoldReport } from "./mesh-join-hold.js";
|
|
31
35
|
/** The child's register action on its parent agent. */
|
|
32
36
|
export declare const AGENT_REGISTER_NODE_ACTION = "$agent.registerNode";
|
|
33
37
|
export declare function isRemoteForbiddenOnAgent(action: string): boolean;
|
|
@@ -40,13 +44,21 @@ export interface AgentMeshAuthenticatorDeps {
|
|
|
40
44
|
readonly now?: () => number;
|
|
41
45
|
/** First time a peer is tolerated without proof on this connection. */
|
|
42
46
|
readonly onTolerated?: (nodeId: string, action: string) => void;
|
|
47
|
+
/** Every decision about the hub's requests held before the join settled. */
|
|
48
|
+
readonly onHoldReport?: (report: MeshJoinHoldReport) => void;
|
|
49
|
+
/** Bounds of that hold (defaults: 1000 items, 15 s). */
|
|
50
|
+
readonly maxHeld?: number;
|
|
51
|
+
readonly maxHoldMs?: number;
|
|
43
52
|
}
|
|
44
53
|
export declare class AgentMeshAuthenticator {
|
|
45
54
|
private readonly deps;
|
|
46
55
|
private readonly nodes;
|
|
47
56
|
private readonly hubNodeId;
|
|
48
57
|
private readonly now;
|
|
58
|
+
private readonly hold;
|
|
49
59
|
constructor(deps: AgentMeshAuthenticatorDeps);
|
|
60
|
+
/** How many of the hub's requests wait for the join right now. */
|
|
61
|
+
heldCount(): number;
|
|
50
62
|
/** Current mode: secret configured → enforce; else tolerate (upgrade path). */
|
|
51
63
|
mode(): MeshAuthMode;
|
|
52
64
|
/**
|
|
@@ -59,8 +71,8 @@ export declare class AgentMeshAuthenticator {
|
|
|
59
71
|
noteChildRegistered(sender: string, proof?: "authenticated" | "legacy"): void;
|
|
60
72
|
/** The peer's connection dropped. */
|
|
61
73
|
forget(nodeId: string): void;
|
|
62
|
-
admitCall(sender: string, action: string):
|
|
63
|
-
admitEvent(sender: string, eventName: string):
|
|
74
|
+
admitCall(sender: string, action: string): MeshGateVerdict;
|
|
75
|
+
admitEvent(sender: string, eventName: string): MeshGateVerdict;
|
|
64
76
|
stateOf(nodeId: string): MeshNodeAuthState;
|
|
65
77
|
authenticatedNodeIds(): readonly string[];
|
|
66
78
|
private admitSender;
|
|
@@ -25,6 +25,12 @@ interface BrokerConfig {
|
|
|
25
25
|
*/
|
|
26
26
|
readonly agentListenPort?: number;
|
|
27
27
|
/**
|
|
28
|
+
* Port an ENROLLED agent listens on for the hub's mutual-TLS dial (default
|
|
29
|
+
* 6443). It is advertised to the hub in every gossip HELLO, so two
|
|
30
|
+
* nodes on one host (a dev or test cluster) need not collide on 6443.
|
|
31
|
+
*/
|
|
32
|
+
readonly agentTlsListenPort?: number;
|
|
33
|
+
/**
|
|
28
34
|
* Broker middlewares (D802): the hub passes its mesh gate
|
|
29
35
|
* (`createMeshAccessMiddleware`); an agent passes inbound access
|
|
30
36
|
* (`AgentMeshAuthenticator` + the same middleware) and its outbound join
|
|
@@ -14,11 +14,15 @@
|
|
|
14
14
|
* Calls a node makes to itself (`ctx.nodeID` = own) pass untouched.
|
|
15
15
|
*/
|
|
16
16
|
import { type Middleware } from "moleculer";
|
|
17
|
-
import type {
|
|
18
|
-
/**
|
|
17
|
+
import type { MeshGateVerdict } from "./mesh-join-hold.js";
|
|
18
|
+
/**
|
|
19
|
+
* Minimal surface the middleware needs — hub and agent authenticators both fit.
|
|
20
|
+
* Only the agent's ever answers `hold` (its hub's requests before the join
|
|
21
|
+
* settles, D848): the request waits for that verdict, then runs or is refused.
|
|
22
|
+
*/
|
|
19
23
|
export interface MeshCallGate {
|
|
20
|
-
admitCall(sender: string, action: string):
|
|
21
|
-
admitEvent(sender: string, eventName: string):
|
|
24
|
+
admitCall(sender: string, action: string): MeshGateVerdict;
|
|
25
|
+
admitEvent(sender: string, eventName: string): MeshGateVerdict;
|
|
22
26
|
}
|
|
23
27
|
/**
|
|
24
28
|
* The params of a request from another node, with every identity it claimed
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What an agent does with the hub's events and calls that arrive BEFORE its
|
|
3
|
+
* mesh join has settled (D848 §3).
|
|
4
|
+
*
|
|
5
|
+
* The agent's inbound gate admits the hub only once the mutual join has
|
|
6
|
+
* proven it (`AgentMeshAuthenticator`, D802). The hub, though, starts sending
|
|
7
|
+
* the moment it sees the agent's connection — a one-shot event broadcast at
|
|
8
|
+
* that instant reached a gate that had not yet heard the join's answer, and
|
|
9
|
+
* was refused: dropped, with only a rate-limited "mesh event refused" line.
|
|
10
|
+
* An ordering fix on the hub cannot close it: the agent verifies the hub's
|
|
11
|
+
* proof asynchronously, after the answer that carries it, so even an event
|
|
12
|
+
* the hub sends strictly after its answer can be decoded first.
|
|
13
|
+
*
|
|
14
|
+
* So the agent HOLDS what the hub sends while a join is in flight, and
|
|
15
|
+
* decides when the join decides:
|
|
16
|
+
* - the join proves the hub → everything held is delivered, in arrival order;
|
|
17
|
+
* - the join fails (mismatch, unverified hub, no answer) → everything held is
|
|
18
|
+
* refused, and said so with the count;
|
|
19
|
+
* - the bound runs out first ({@link MeshJoinHoldOptions.maxHoldMs} since the
|
|
20
|
+
* first item was held) → refused and said so, and nothing more is held until
|
|
21
|
+
* the next join starts;
|
|
22
|
+
* - more than {@link MeshJoinHoldOptions.maxHeld} items → the excess is refused
|
|
23
|
+
* on arrival and counted into the next report.
|
|
24
|
+
*
|
|
25
|
+
* The timer is the bound itself, never a wait for a node (D3): delivery is
|
|
26
|
+
* driven by the join settling. Nothing held is ever dropped without a report
|
|
27
|
+
* (D49).
|
|
28
|
+
*/
|
|
29
|
+
import type { MeshCallVerdict } from "./mesh-authenticator.js";
|
|
30
|
+
/** The gate cannot answer yet: the request waits for the join. */
|
|
31
|
+
export interface MeshHeldVerdict {
|
|
32
|
+
readonly verdict: "hold";
|
|
33
|
+
readonly settled: Promise<MeshCallVerdict>;
|
|
34
|
+
}
|
|
35
|
+
/** Every verdict a mesh gate may give (`MeshCallGate`). */
|
|
36
|
+
export type MeshGateVerdict = MeshCallVerdict | MeshHeldVerdict;
|
|
37
|
+
export type MeshHeldKind = "call" | "event";
|
|
38
|
+
export interface MeshJoinHoldReport {
|
|
39
|
+
/** `delivered` when the join proved the hub, else `refused`. */
|
|
40
|
+
readonly outcome: "delivered" | "refused";
|
|
41
|
+
/** `authenticated`, the failed join state, or `bound` (time ran out). */
|
|
42
|
+
readonly reason: string;
|
|
43
|
+
readonly events: number;
|
|
44
|
+
readonly calls: number;
|
|
45
|
+
/** Refused on arrival because the hold was full. */
|
|
46
|
+
readonly overflow: number;
|
|
47
|
+
/** From the first held item to the decision. */
|
|
48
|
+
readonly heldForMs: number;
|
|
49
|
+
}
|
|
50
|
+
export interface MeshJoinHoldOptions {
|
|
51
|
+
readonly hubNodeId: string;
|
|
52
|
+
/** Most items held at once (default 1000). */
|
|
53
|
+
readonly maxHeld?: number;
|
|
54
|
+
/** Longest an item is held, from the first one (default 15 s). */
|
|
55
|
+
readonly maxHoldMs?: number;
|
|
56
|
+
readonly now?: () => number;
|
|
57
|
+
readonly onReport?: (report: MeshJoinHoldReport) => void;
|
|
58
|
+
}
|
|
59
|
+
export declare const DEFAULT_MESH_JOIN_MAX_HELD = 1e3;
|
|
60
|
+
export declare const DEFAULT_MESH_JOIN_MAX_HOLD_MS = 15e3;
|
|
61
|
+
export declare class MeshJoinHold {
|
|
62
|
+
private readonly opts;
|
|
63
|
+
private waiters;
|
|
64
|
+
private firstHeldAt;
|
|
65
|
+
private overflow;
|
|
66
|
+
private timer;
|
|
67
|
+
/** Holding is open while a join is in flight; closed after a decision or the bound. */
|
|
68
|
+
private open;
|
|
69
|
+
private readonly now;
|
|
70
|
+
constructor(opts: MeshJoinHoldOptions);
|
|
71
|
+
/** Whether a request arriving now would be held (a join is in flight). */
|
|
72
|
+
get holding(): boolean;
|
|
73
|
+
/** How many requests wait right now. */
|
|
74
|
+
get size(): number;
|
|
75
|
+
/** A join started: hold again. */
|
|
76
|
+
reopen(): void;
|
|
77
|
+
/** Hold one request; `null` when holding is closed (the caller refuses it). */
|
|
78
|
+
hold(kind: MeshHeldKind): MeshHeldVerdict | null;
|
|
79
|
+
/** The join proved the hub: deliver everything held, in order. */
|
|
80
|
+
release(): void;
|
|
81
|
+
/** The join failed, or the bound ran out: refuse everything held. */
|
|
82
|
+
refuse(reason: string): void;
|
|
83
|
+
private refusal;
|
|
84
|
+
private settle;
|
|
85
|
+
}
|
|
@@ -7,4 +7,4 @@ export { enrollMeshNode } from "./mesh-enroll.js";
|
|
|
7
7
|
export type { EnrollMeshNodeDeps, MeshEnrollRequest, MeshEnrollResult } from "./mesh-enroll.js";
|
|
8
8
|
export { JoinTokenJtiStore, mintMeshJoinToken, processJoinTokenJtiStore, verifyMeshJoinToken, type MeshJoinTokenClaims, type MintJoinTokenInput } from "./mesh-join-token.js";
|
|
9
9
|
export { getProcessMeshTlsEnabler, requestProcessMeshTlsEnable, setProcessMeshTlsEnabler, type MeshTlsEnabler } from "./mesh-tls-enabler.js";
|
|
10
|
-
export { TlsTcpTransporter, type MeshTlsMaterial, type TlsTcpTransporterOptions } from "./tls-tcp-transporter.js";
|
|
10
|
+
export { helloMeshTlsPort, keepOnlyGossipNodes, MESH_TLS_PORT_HELLO_FIELD, TlsTcpTransporter, type FilteredGossip, type MeshTlsMaterial, type TlsTcpTransporterOptions } from "./tls-tcp-transporter.js";
|