@camstack/system 1.2.434 → 1.2.436
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/device-manager.addon.js +2 -2
- package/dist/builtins/device-manager/device-manager.addon.mjs +2 -2
- package/dist/builtins/hub-forwarder/index.js +1 -1
- package/dist/builtins/hub-forwarder/index.mjs +1 -1
- package/dist/builtins/keychain/index.js +6 -7
- package/dist/builtins/keychain/index.mjs +6 -7
- package/dist/builtins/keychain/keychain-service.d.ts +1 -2
- package/dist/builtins/keychain/system-held-secrets.d.ts +5 -5
- 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.d.ts +4 -2
- package/dist/builtins/local-network/local-network.addon.js +23 -13
- package/dist/builtins/local-network/local-network.addon.mjs +23 -13
- 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/index.js +1 -1
- package/dist/builtins/sqlite-storage/index.mjs +1 -1
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +3 -3
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +3 -3
- 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.d.ts +3 -24
- package/dist/builtins/system-config/system-config.addon.js +105 -1410
- package/dist/builtins/system-config/system-config.addon.mjs +108 -1402
- package/dist/builtins/winston-logging/index.js +1 -1
- package/dist/builtins/winston-logging/index.mjs +1 -1
- package/dist/{composition-sources-B7R1oQnY.js → composition-sources-BAOlCu4j.js} +1 -1
- package/dist/{composition-sources-CqrDyHM1.mjs → composition-sources-gN_BWUKp.mjs} +1 -1
- package/dist/constants-BFpowodq.mjs +20 -0
- package/dist/constants-GENKqk9k.js +66 -0
- package/dist/{device-ca-CDjGQQPd.mjs → device-ca-BNM5ai4t.mjs} +1 -1
- package/dist/{device-ca-D21ZP00q.js → device-ca-CuWuRW9N.js} +1 -1
- package/dist/{dist-CCH3XPqO.js → dist-DVe0Nsp8.js} +48 -16
- package/dist/{dist-CYcBqnXk.mjs → dist-DjD2M79P.mjs} +43 -5
- package/dist/file-host-worker.js +1 -1
- package/dist/file-host-worker.mjs +1 -1
- package/dist/index.js +132 -795
- package/dist/index.mjs +133 -753
- package/dist/kernel/index.d.ts +7 -21
- package/dist/kernel/moleculer/agent-ui-unlock.d.ts +7 -32
- package/dist/kernel/moleculer/broker-factory.d.ts +3 -9
- package/dist/kernel/moleculer/broker-transport-swap.d.ts +17 -0
- package/dist/kernel/moleculer/hub-service.d.ts +6 -16
- package/dist/kernel/moleculer/mesh-access-middleware.d.ts +7 -17
- package/dist/kernel/moleculer/mesh-identity.d.ts +57 -0
- package/dist/kernel/moleculer/mesh-mtls/constants.d.ts +1 -4
- package/dist/kernel/moleculer/mesh-mtls/index.d.ts +1 -4
- package/dist/kernel/moleculer/mesh-mtls/mesh-ca.d.ts +1 -1
- package/dist/kernel/moleculer/mesh-mtls/mesh-renewal.d.ts +1 -1
- package/dist/kernel/moleculer/node-registry.d.ts +0 -6
- package/dist/kernel/moleculer/register-node-client.d.ts +9 -7
- package/dist/{restore-archive-5ml7uYMf.mjs → restore-archive-BxmP1ChO.mjs} +1 -1
- package/dist/{restore-archive-Do0QwAik.js → restore-archive-D4h904rb.js} +1 -1
- package/dist/{retired-settings-keys-CyDdyjLP.mjs → retired-settings-keys-CQaknvx1.mjs} +1 -1
- package/dist/{retired-settings-keys-CEiCaI_j.js → retired-settings-keys-CYP5IZJ5.js} +1 -1
- package/dist/{wal-maintenance-LZYd8iT-.js → wal-maintenance-Br60onAQ.js} +0 -0
- package/dist/{wal-maintenance-DgLLPK14.mjs → wal-maintenance-CaDsrJM_.mjs} +0 -0
- package/package.json +1 -1
- package/dist/builtins/system-config/cluster-secret-keeper.d.ts +0 -63
- package/dist/constants-CrMPWOug.mjs +0 -102
- package/dist/constants-CuOfMdYe.js +0 -221
- package/dist/kernel/moleculer/agent-mesh-authenticator.d.ts +0 -91
- package/dist/kernel/moleculer/cluster-secret.d.ts +0 -46
- package/dist/kernel/moleculer/mesh-auth-mode.d.ts +0 -58
- package/dist/kernel/moleculer/mesh-authenticator.d.ts +0 -77
- package/dist/kernel/moleculer/mesh-auto-enforce.d.ts +0 -46
- package/dist/kernel/moleculer/mesh-join-client.d.ts +0 -73
- package/dist/kernel/moleculer/mesh-join-hold.d.ts +0 -85
- package/dist/kernel/moleculer/mesh-join-proof.d.ts +0 -39
- package/dist/kernel/moleculer/mesh-mtls/mesh-enroll.d.ts +0 -34
- package/dist/kernel/moleculer/mesh-mtls/mesh-join-token.d.ts +0 -56
package/dist/kernel/index.d.ts
CHANGED
|
@@ -41,8 +41,8 @@ export { createAgentTransport, createBroker, deriveAgentListenPort, getBrokerTls
|
|
|
41
41
|
export type { AgentTransport, BrokerConfig } from "./moleculer/broker-factory.js";
|
|
42
42
|
export { buildTransporter, connectBrokerTransport, currentBrokerTransporter, disconnectBrokerTransport, installBrokerTransporter, isInstalledTransporter } from "./moleculer/broker-transport-swap.js";
|
|
43
43
|
export type { PendingTransporter } from "./moleculer/broker-transport-swap.js";
|
|
44
|
-
export { caFingerprint, caFingerprintCompact, describeMeshLeaf, dropProcessPeer, emitProcessNodeRegistered, onProcessNodeRegistered, getProcessMeshCertificateRegistry, getProcessPeerLeaf, MESH_NODE_CERTIFICATES_COLLECTION, MESH_NODE_CERTIFICATES_COLUMNS, MeshCertificateRegistry, getProcessMeshTlsListenerState, openMeshTlsWhenRevocationsLoaded, RENEWAL_ABANDONED, setProcessMeshTlsListenerState, renewMeshCertificate, revokeMeshCertificate, setProcessMeshCertificateRegistry, createMeshCsrPem,
|
|
45
|
-
export type { MeshCertificateRecord, MeshLeafDescription, MeshLog, MeshPeerLeaf, MeshPeers, MeshRegistrations, MeshTlsListenerState, NodeMeshClient, RenewMeshResult, RevokeMeshResult, MeshCaSigner,
|
|
44
|
+
export { caFingerprint, caFingerprintCompact, describeMeshLeaf, dropProcessPeer, emitProcessNodeRegistered, onProcessNodeRegistered, getProcessMeshCertificateRegistry, getProcessPeerLeaf, MESH_NODE_CERTIFICATES_COLLECTION, MESH_NODE_CERTIFICATES_COLUMNS, MeshCertificateRegistry, getProcessMeshTlsListenerState, openMeshTlsWhenRevocationsLoaded, RENEWAL_ABANDONED, setProcessMeshTlsListenerState, renewMeshCertificate, revokeMeshCertificate, setProcessMeshCertificateRegistry, createMeshCsrPem, exportMeshPrivateKeyPem, getProcessNodeMeshTransport, isProcessVerifiedMeshPeer, setProcessMeshPeerTransportLookup, generateMeshCa, generateMeshKeyPair, getProcessMeshCaState, issueMeshLeafForNode, issueMeshLeafFromCsr, loadMeshCa, MESH_CA_FIELD, MESH_CA_KEY_REF, MESH_CA_SETTINGS_KEY, MeshCaKeeper, MeshCrl, processMeshCrl, requireProcessMeshCa, setProcessMeshTlsEnabler, TlsTcpTransporter, DEFAULT_HUB_TLS_TCP_PORT, MESH_TLS_PORT_HELLO_FIELD } from "./moleculer/mesh-mtls/index.js";
|
|
45
|
+
export type { MeshCertificateRecord, MeshLeafDescription, MeshLog, MeshPeerLeaf, MeshPeers, MeshRegistrations, MeshTlsListenerState, NodeMeshClient, RenewMeshResult, RevokeMeshResult, MeshCaSigner, MeshPeerTransportLookup, MeshTransport, MeshTlsMaterial, VerifiedMeshPeer } from "./moleculer/mesh-mtls/index.js";
|
|
46
46
|
export * from "./moleculer/mesh-mtls/pairing/index.js";
|
|
47
47
|
export { type AddonDeploySource, isAddonDeploySource } from "./moleculer/addon-deploy-source.js";
|
|
48
48
|
export { createAddonService, validateProviderRegistrations } from "./moleculer/addon-service-factory.js";
|
|
@@ -57,28 +57,14 @@ export { HubNodeRegistry } from "./moleculer/node-registry.js";
|
|
|
57
57
|
export type { CallFn, NodeRootPackageInfo, RegisteredAddonManifest, RegisteredNativeCap, RegisterNodeParams, RegisterNodeResult, NodeCapEntry, NodeNativeCapEntry } from "./moleculer/node-registry.js";
|
|
58
58
|
export { callRegisterNodeWithRetry, buildNodeManifest } from "./moleculer/register-node-client.js";
|
|
59
59
|
export type { RegisterNodeBroker, CallRegisterNodeOptions } from "./moleculer/register-node-client.js";
|
|
60
|
-
export {
|
|
61
|
-
export type {
|
|
62
|
-
export { MeshAuthenticator, isRemoteForbiddenAction, MESH_JOIN_CHALLENGE_TTL_MS } from "./moleculer/mesh-authenticator.js";
|
|
63
|
-
export type { MeshAuthenticatorDeps, MeshCallVerdict } from "./moleculer/mesh-authenticator.js";
|
|
60
|
+
export { AgentMeshIdentityGate, isRemoteForbiddenAction, isRemoteForbiddenOnAgent, MeshIdentityGate, meshErrorType, MESH_ACTION_FORBIDDEN_TYPE, MESH_NODE_UNAUTHENTICATED_TYPE } from "./moleculer/mesh-identity.js";
|
|
61
|
+
export type { AgentMeshIdentityGateDeps, MeshCallGate, MeshCallVerdict, MeshIdentityGateDeps, PeerVerifier } from "./moleculer/mesh-identity.js";
|
|
64
62
|
export { createMeshAccessMiddleware, stripForgedIdentity } from "./moleculer/mesh-access-middleware.js";
|
|
65
|
-
export type { MeshAccessMiddlewareOptions
|
|
66
|
-
export { AgentMeshAuthenticator, AGENT_REGISTER_NODE_ACTION, isOwnChildNodeId, isRemoteForbiddenOnAgent } from "./moleculer/agent-mesh-authenticator.js";
|
|
67
|
-
export type { AgentMeshAuthenticatorDeps } from "./moleculer/agent-mesh-authenticator.js";
|
|
68
|
-
export { DEFAULT_MESH_JOIN_MAX_HELD, DEFAULT_MESH_JOIN_MAX_HOLD_MS, MeshJoinHold } from "./moleculer/mesh-join-hold.js";
|
|
69
|
-
export type { MeshGateVerdict, MeshHeldKind, MeshHeldVerdict, MeshJoinHoldOptions, MeshJoinHoldReport } from "./moleculer/mesh-join-hold.js";
|
|
63
|
+
export type { MeshAccessMiddlewareOptions } from "./moleculer/mesh-access-middleware.js";
|
|
70
64
|
export { createAgentEventScope, isPeerEventPacket } from "./moleculer/agent-event-scope.js";
|
|
71
65
|
export type { AgentEventScope, AgentEventScopeOptions, AgentEventScopeStats, OutboundPacket, TransitPublish } from "./moleculer/agent-event-scope.js";
|
|
72
|
-
export {
|
|
73
|
-
export type {
|
|
74
|
-
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";
|
|
75
|
-
export type { MeshJoinAuthenticateParams, MeshJoinAuthenticateResult, MeshJoinChallenge } from "./moleculer/mesh-join-proof.js";
|
|
76
|
-
export { getProcessMeshAuthMode, getProcessMeshAuthStatus, isMeshAuthMode, MESH_AUTH_MODE_FIELD, parseMeshAuthMode, requestProcessMeshEnforcement, setProcessMeshAuthMode, setProcessMeshAuthStatusSource, setProcessMeshEnforcer } from "./moleculer/mesh-auth-mode.js";
|
|
77
|
-
export { decideMeshAutoEnforce, MESH_AUTO_ENFORCE_GRACE_MS } from "./moleculer/mesh-auto-enforce.js";
|
|
78
|
-
export type { MeshAutoEnforceDecision, MeshAutoEnforceInput } from "./moleculer/mesh-auto-enforce.js";
|
|
79
|
-
export { AGENT_DASHBOARD_ORIGINS_FIELD, AGENT_UI_UNLOCK_DOMAIN, AGENT_UI_UNLOCK_TYP, AGENT_UI_UNLOCK_USE, mintAgentUiUnlockTicketEs256, verifyAgentUiUnlockTicketEs256, AGENT_UI_UNLOCK_TTL_MS, AGENT_UI_UNLOCK_VERSION, isAllowedAgentDashboardReturnTo, mintAgentUiUnlockTicket, parseAgentDashboardOrigins, UnlockTicketJtiStore, verifyAgentUiUnlockTicket } from "./moleculer/agent-ui-unlock.js";
|
|
80
|
-
export type { AgentUiUnlockPayload, MintAgentUiUnlockTicketEs256Input, MintAgentUiUnlockTicketInput, VerifyAgentUiUnlockTicketEs256Options, VerifyAgentUiUnlockTicketOptions } from "./moleculer/agent-ui-unlock.js";
|
|
81
|
-
export type { MeshAuthMode, MeshAuthStatus, MeshEnforcer, MeshNodeAuthEntry, MeshNodeAuthState } from "./moleculer/mesh-auth-mode.js";
|
|
66
|
+
export { AGENT_DASHBOARD_ORIGINS_FIELD, AGENT_UI_UNLOCK_TYP, AGENT_UI_UNLOCK_USE, AGENT_UI_UNLOCK_TTL_MS, AGENT_UI_UNLOCK_VERSION, isAllowedAgentDashboardReturnTo, mintAgentUiUnlockTicket, parseAgentDashboardOrigins, UnlockTicketJtiStore, verifyAgentUiUnlockTicket } from "./moleculer/agent-ui-unlock.js";
|
|
67
|
+
export type { AgentUiUnlockPayload, MintAgentUiUnlockTicketInput, VerifyAgentUiUnlockTicketOptions } from "./moleculer/agent-ui-unlock.js";
|
|
82
68
|
export { serializeTypedArrays } from "./moleculer/typed-array-serde.js";
|
|
83
69
|
export { createReadinessService, createReadinessServiceForRegistry, AGENT_READINESS_SERVICE_NAME } from "./moleculer/readiness-service.js";
|
|
84
70
|
export type { ReadinessServiceDeps } from "./moleculer/readiness-service.js";
|
|
@@ -1,11 +1,6 @@
|
|
|
1
|
-
export declare const AGENT_UI_UNLOCK_DOMAIN = "camstack-agent-ui-unlock/v1";
|
|
2
|
-
export declare const AGENT_UI_UNLOCK_VERSION: 1;
|
|
3
|
-
/**
|
|
4
|
-
* D857 (transition release): a ticket signed by the MESH CA key (ES256 JWS) is accepted by an agent
|
|
5
|
-
* IN ADDITION to the HMAC ticket. The removal release mints only this form.
|
|
6
|
-
*/
|
|
7
1
|
export declare const AGENT_UI_UNLOCK_TYP = "camstack-agent-ui-unlock+jwt";
|
|
8
2
|
export declare const AGENT_UI_UNLOCK_USE = "agent-ui-unlock";
|
|
3
|
+
export declare const AGENT_UI_UNLOCK_VERSION: 1;
|
|
9
4
|
/** Ticket lifetime — long enough for a redirect hop, short enough to steal poorly. */
|
|
10
5
|
export declare const AGENT_UI_UNLOCK_TTL_MS: number;
|
|
11
6
|
/**
|
|
@@ -33,8 +28,8 @@ export declare class UnlockTicketJtiStore {
|
|
|
33
28
|
private gc;
|
|
34
29
|
}
|
|
35
30
|
export interface MintAgentUiUnlockTicketInput {
|
|
36
|
-
/**
|
|
37
|
-
readonly
|
|
31
|
+
/** The mesh CA's private key, PKCS#8 PEM (`MeshCaSigner.keyPem`). */
|
|
32
|
+
readonly caKeyPem: string;
|
|
38
33
|
readonly nodeId: string;
|
|
39
34
|
readonly ttlMs?: number;
|
|
40
35
|
readonly nowMs?: number;
|
|
@@ -51,10 +46,11 @@ export interface VerifyAgentUiUnlockTicketOptions {
|
|
|
51
46
|
readonly notBeforeMs?: number;
|
|
52
47
|
}
|
|
53
48
|
/**
|
|
54
|
-
* Verify a ticket
|
|
55
|
-
* signature, shape, expiry or nodeId fails
|
|
49
|
+
* Verify a ticket against the mesh CA certificate the agent pinned. Returns the
|
|
50
|
+
* payload, or `null` when the signature, header, shape, expiry or nodeId fails
|
|
51
|
+
* (no reason string — refuse quietly).
|
|
56
52
|
*/
|
|
57
|
-
export declare function verifyAgentUiUnlockTicket(
|
|
53
|
+
export declare function verifyAgentUiUnlockTicket(caCertPem: string, ticket: string, options: VerifyAgentUiUnlockTicketOptions): AgentUiUnlockPayload | null;
|
|
58
54
|
/**
|
|
59
55
|
* True when `returnTo` may receive a ticket redirect. Default: any http(s)
|
|
60
56
|
* origin whose port is 4444. Extra origins come from
|
|
@@ -69,24 +65,3 @@ export declare function isAllowedAgentDashboardReturnTo(returnTo: string, extraO
|
|
|
69
65
|
*/
|
|
70
66
|
export declare function isKnownAgentAddress(returnTo: string, knownNames: readonly string[] | null, listedOrigins?: readonly string[]): boolean;
|
|
71
67
|
export declare function parseAgentDashboardOrigins(stored: unknown): readonly string[];
|
|
72
|
-
export interface MintAgentUiUnlockTicketEs256Input {
|
|
73
|
-
/** The mesh CA's private key, PKCS#8 PEM (`MeshCaSigner.keyPem`). */
|
|
74
|
-
readonly caKeyPem: string;
|
|
75
|
-
readonly nodeId: string;
|
|
76
|
-
readonly ttlMs?: number;
|
|
77
|
-
readonly nowMs?: number;
|
|
78
|
-
readonly jti?: string;
|
|
79
|
-
}
|
|
80
|
-
export declare function mintAgentUiUnlockTicketEs256(input: MintAgentUiUnlockTicketEs256Input): string;
|
|
81
|
-
export interface VerifyAgentUiUnlockTicketEs256Options {
|
|
82
|
-
readonly expectedNodeId: string;
|
|
83
|
-
readonly nowMs?: number;
|
|
84
|
-
/** Refuse a ticket issued before this instant (the agent's boot). */
|
|
85
|
-
readonly notBeforeMs?: number;
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Verify a ticket against the mesh CA certificate the agent pinned. Returns the
|
|
89
|
-
* payload, or `null` when the signature, header, shape, expiry or nodeId fails
|
|
90
|
-
* (no reason string — refuse quietly).
|
|
91
|
-
*/
|
|
92
|
-
export declare function verifyAgentUiUnlockTicketEs256(caCertPem: string, ticket: string, options: VerifyAgentUiUnlockTicketEs256Options): AgentUiUnlockPayload | null;
|
|
@@ -68,17 +68,11 @@ interface BrokerConfig {
|
|
|
68
68
|
*/
|
|
69
69
|
declare function deriveAgentListenPort(nodeID: string): number;
|
|
70
70
|
declare function createBroker(config: BrokerConfig): ServiceBroker;
|
|
71
|
-
/** What an agent's transport is made of:
|
|
72
|
-
|
|
71
|
+
/** What an agent's transport is made of: always the mTLS transporter (D857). */
|
|
72
|
+
interface AgentTransport {
|
|
73
73
|
readonly kind: "tls";
|
|
74
74
|
readonly transporter: TlsTcpTransporter;
|
|
75
|
-
}
|
|
76
|
-
readonly kind: "tcp";
|
|
77
|
-
readonly descriptor: {
|
|
78
|
-
readonly type: "TCP";
|
|
79
|
-
readonly options: Record<string, unknown>;
|
|
80
|
-
};
|
|
81
|
-
};
|
|
75
|
+
}
|
|
82
76
|
/**
|
|
83
77
|
* The transport of an agent broker, from its config. An agent with no hub address dials nobody
|
|
84
78
|
* and stays `unconfigured` until one is set (the agent UI lists the hubs found over mDNS, D839).
|
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reconnecting a broker's TRANSPORT in place, without rebuilding the broker (D856 amendment).
|
|
3
|
+
*
|
|
4
|
+
* An agent changes how it dials the hub (a new hub address, a new cluster secret, a mesh leaf
|
|
5
|
+
* swap or its rollback) by replacing its transporter. It used to stop the whole `ServiceBroker`
|
|
6
|
+
* and build another. That threw away everything bound to the old one: the `$process` service
|
|
7
|
+
* (whose `stopped()` SIGTERMs every runner - the "child gone" lines), `$agent-cap-fwd`,
|
|
8
|
+
* `$agent`, the event bus, the addon services and every closure that captured the broker. The
|
|
9
|
+
* node came back ONLINE and capless, and the hub's confirm step then failed with
|
|
10
|
+
* "`$agent-cap-fwd.forward` is not found".
|
|
11
|
+
*
|
|
12
|
+
* The broker, its services, its registries and its child runners are all independent of the
|
|
13
|
+
* wire. So only the wire is replaced: disconnect the transit, forget the remote nodes (their
|
|
14
|
+
* connection is gone, and the next `$node.connected` is what re-runs the mesh join), install a
|
|
15
|
+
* new transporter on the SAME transit and connect it. Children never notice; the join's settle
|
|
16
|
+
* re-sends the full manifest (D3), which still carries every child.
|
|
17
|
+
*/
|
|
1
18
|
import type { AgentTransport } from "./broker-factory.js";
|
|
2
19
|
/** The slice of a Moleculer transporter this module drives. */
|
|
3
20
|
interface TransporterLike {
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import type { ServiceSchema } from "moleculer";
|
|
2
2
|
import type { LogTags } from "@camstack/types";
|
|
3
3
|
import type { RegisterNodeParams } from "./node-registry.js";
|
|
4
|
-
import {
|
|
5
|
-
import type { MeshAuthenticator } from "./mesh-authenticator.js";
|
|
4
|
+
import type { MeshIdentityGate } from "./mesh-identity.js";
|
|
6
5
|
interface HubServiceDeps {
|
|
7
6
|
readonly getAddonConfig: (addonId: string) => unknown;
|
|
8
7
|
readonly getSettings: (scope: string, key?: string) => unknown;
|
|
@@ -26,21 +25,12 @@ interface HubServiceDeps {
|
|
|
26
25
|
/** Explicit deregistration (graceful shutdown). `$node.disconnected` covers crashes. */
|
|
27
26
|
readonly onUnregisterNode?: (nodeId: string) => void;
|
|
28
27
|
/**
|
|
29
|
-
* The hub's
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* Absent → `off` (test brokers); the hub always passes the keychain's gate.
|
|
28
|
+
* The hub's mesh identity gate (D857). When present, `registerNode` asks it
|
|
29
|
+
* whether the SENDER may register: a node registers only itself, and only
|
|
30
|
+
* while it holds a certificate identity. Absent → no sender check (test
|
|
31
|
+
* brokers); the hub always passes its gate.
|
|
34
32
|
*/
|
|
35
|
-
readonly
|
|
36
|
-
/**
|
|
37
|
-
* The hub's per-node mesh identity (D802). When present, `joinChallenge` /
|
|
38
|
-
* `authenticateNode` run the challenge–response and `registerNode` asks it
|
|
39
|
-
* whether the SENDER may register (`MeshAuthenticator.admitRegistration`);
|
|
40
|
-
* `clusterSecretGate` is then read through it. Absent → the D797 hash gate
|
|
41
|
-
* alone (test brokers).
|
|
42
|
-
*/
|
|
43
|
-
readonly meshAuth?: MeshAuthenticator;
|
|
33
|
+
readonly meshIdentity?: MeshIdentityGate;
|
|
44
34
|
}
|
|
45
35
|
declare function createHubService(deps: HubServiceDeps): ServiceSchema;
|
|
46
36
|
export { createHubService };
|
|
@@ -1,29 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Mesh gate middleware (D802): wraps every LOCAL action and event handler
|
|
3
|
-
* it sees each request another node sends with `ctx.nodeID` = the sender.
|
|
2
|
+
* Mesh gate middleware (D802, D857): wraps every LOCAL action and event handler
|
|
3
|
+
* so it sees each request another node sends with `ctx.nodeID` = the sender.
|
|
4
4
|
*
|
|
5
5
|
* Used on both sides of the mesh:
|
|
6
|
-
* - hub: {@link
|
|
7
|
-
* - agent: {@link
|
|
8
|
-
* children via `$agent.registerNode`).
|
|
6
|
+
* - hub: {@link MeshIdentityGate} (the sender holds a verified certificate);
|
|
7
|
+
* - agent: {@link AgentMeshIdentityGate} (the sender is the certified hub).
|
|
9
8
|
*
|
|
10
9
|
* For a request from another node it:
|
|
11
|
-
* 1. asks the gate's `admitCall` — refuse
|
|
10
|
+
* 1. asks the gate's `admitCall` — refuse or allow;
|
|
12
11
|
* 2. strips a forged identity from the params ({@link stripForgedIdentity}).
|
|
13
12
|
*
|
|
14
13
|
* Calls a node makes to itself (`ctx.nodeID` = own) pass untouched.
|
|
15
14
|
*/
|
|
16
15
|
import { type Middleware } from "moleculer";
|
|
17
|
-
import type
|
|
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
|
-
*/
|
|
23
|
-
export interface MeshCallGate {
|
|
24
|
-
admitCall(sender: string, action: string): MeshGateVerdict;
|
|
25
|
-
admitEvent(sender: string, eventName: string): MeshGateVerdict;
|
|
26
|
-
}
|
|
16
|
+
import { type MeshCallGate } from "./mesh-identity.js";
|
|
27
17
|
/**
|
|
28
18
|
* The params of a request from another node, with every identity it claimed
|
|
29
19
|
* removed:
|
|
@@ -41,7 +31,7 @@ interface GateLogger {
|
|
|
41
31
|
}
|
|
42
32
|
export interface MeshAccessMiddlewareOptions {
|
|
43
33
|
readonly ownNodeId: string;
|
|
44
|
-
readonly
|
|
34
|
+
readonly gate: MeshCallGate;
|
|
45
35
|
readonly logger?: GateLogger;
|
|
46
36
|
}
|
|
47
37
|
/**
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/** Moleculer error `type`: the sender has no certificate identity this node accepts. */
|
|
2
|
+
export declare const MESH_NODE_UNAUTHENTICATED_TYPE = "MESH_NODE_UNAUTHENTICATED";
|
|
3
|
+
/** Moleculer error `type`: the action is never callable from another node. */
|
|
4
|
+
export declare const MESH_ACTION_FORBIDDEN_TYPE = "MESH_ACTION_FORBIDDEN";
|
|
5
|
+
/** Reads a Moleculer error's `type`, including after an RPC round-trip. */
|
|
6
|
+
export declare function meshErrorType(err: unknown): string | null;
|
|
7
|
+
export type MeshCallVerdict = {
|
|
8
|
+
readonly verdict: "allow";
|
|
9
|
+
readonly errorType?: undefined;
|
|
10
|
+
} | {
|
|
11
|
+
readonly verdict: "deny";
|
|
12
|
+
readonly errorType: string;
|
|
13
|
+
readonly message: string;
|
|
14
|
+
};
|
|
15
|
+
/** A gate the broker middleware asks about every inbound action and event. */
|
|
16
|
+
export interface MeshCallGate {
|
|
17
|
+
admitCall(sender: string, action: string): MeshCallVerdict;
|
|
18
|
+
admitEvent(sender: string, eventName: string): MeshCallVerdict;
|
|
19
|
+
}
|
|
20
|
+
export declare function isRemoteForbiddenAction(action: string): boolean;
|
|
21
|
+
export declare function isRemoteForbiddenOnAgent(action: string): boolean;
|
|
22
|
+
/** `true` when `nodeId` is a certificate-verified mesh peer right now. */
|
|
23
|
+
export type PeerVerifier = (nodeId: string) => boolean;
|
|
24
|
+
export interface MeshIdentityGateDeps {
|
|
25
|
+
/** The node's own id — its local calls never pass through here. */
|
|
26
|
+
readonly ownNodeId: string;
|
|
27
|
+
readonly isVerifiedPeer: PeerVerifier;
|
|
28
|
+
/** A sender was refused for lack of a certificate identity (rate-limit in the caller). */
|
|
29
|
+
readonly onRefused?: (nodeId: string, what: string) => void;
|
|
30
|
+
}
|
|
31
|
+
/** The hub's gate: every other node must hold a verified certificate identity. */
|
|
32
|
+
export declare class MeshIdentityGate implements MeshCallGate {
|
|
33
|
+
private readonly deps;
|
|
34
|
+
constructor(deps: MeshIdentityGateDeps);
|
|
35
|
+
admitCall(sender: string, action: string): MeshCallVerdict;
|
|
36
|
+
/** Same rule as a call, for an inbound event. */
|
|
37
|
+
admitEvent(sender: string, eventName: string): MeshCallVerdict;
|
|
38
|
+
/** Throws when `sender` may not register `nodeId`: a node registers only itself. */
|
|
39
|
+
admitRegistration(sender: string, nodeId: string): void;
|
|
40
|
+
private admitSender;
|
|
41
|
+
}
|
|
42
|
+
export interface AgentMeshIdentityGateDeps extends MeshIdentityGateDeps {
|
|
43
|
+
readonly hubNodeId?: string;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* An agent's inbound gate: the hub, proven by the certificate the agent's TLS
|
|
47
|
+
* listener already verified, and nobody else. An agent that is not paired holds
|
|
48
|
+
* no certificate, so it admits no one.
|
|
49
|
+
*/
|
|
50
|
+
export declare class AgentMeshIdentityGate implements MeshCallGate {
|
|
51
|
+
private readonly deps;
|
|
52
|
+
private readonly hubNodeId;
|
|
53
|
+
constructor(deps: AgentMeshIdentityGateDeps);
|
|
54
|
+
admitCall(sender: string, action: string): MeshCallVerdict;
|
|
55
|
+
admitEvent(sender: string, eventName: string): MeshCallVerdict;
|
|
56
|
+
private admitSender;
|
|
57
|
+
}
|
|
@@ -4,15 +4,12 @@ export declare const MESH_CA_KEY_REF: string;
|
|
|
4
4
|
export declare const MESH_CA_SETTINGS_KEY = "cluster.meshCa";
|
|
5
5
|
/** Field inside the `cluster` section. */
|
|
6
6
|
export declare const MESH_CA_FIELD = "meshCa";
|
|
7
|
-
/**
|
|
8
|
-
export declare const MESH_JOIN_TOKEN_MAX_TTL_SEC: number;
|
|
7
|
+
/** Leaf lifetimes. */
|
|
9
8
|
export declare const MESH_LEAF_VALIDITY_DAYS = 30;
|
|
10
9
|
export declare const MESH_CA_VALIDITY_DAYS = 3650;
|
|
11
10
|
/** Hub legacy clear TCP (retired on hub — D826) and TLS listen port. */
|
|
12
11
|
export declare const DEFAULT_HUB_TCP_PORT = 6e3;
|
|
13
12
|
export declare const DEFAULT_HUB_TLS_TCP_PORT = 6443;
|
|
14
|
-
/** Join token payload version. */
|
|
15
|
-
export declare const MESH_JOIN_TOKEN_VERSION: 1;
|
|
16
13
|
/** Subject of the mesh root. Distinct from the HTTPS local CA. */
|
|
17
14
|
export declare const MESH_CA_COMMON_NAME = "CamStack Mesh CA";
|
|
18
15
|
/** Client + server auth EKU OIDs (mutual TLS). */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { CLIENT_AUTH_OID, DEFAULT_HUB_TCP_PORT, DEFAULT_HUB_TLS_TCP_PORT, MESH_CA_COMMON_NAME, MESH_CA_FIELD, MESH_CA_KEY_REF, MESH_CA_SETTINGS_KEY, MESH_CA_VALIDITY_DAYS,
|
|
1
|
+
export { CLIENT_AUTH_OID, DEFAULT_HUB_TCP_PORT, DEFAULT_HUB_TLS_TCP_PORT, MESH_CA_COMMON_NAME, MESH_CA_FIELD, MESH_CA_KEY_REF, MESH_CA_SETTINGS_KEY, MESH_CA_VALIDITY_DAYS, MESH_LEAF_VALIDITY_DAYS, SERVER_AUTH_OID } from "./constants.js";
|
|
2
2
|
export { caFingerprint, caFingerprintCompact, createMeshCsrPem, exportMeshPrivateKeyPem, generateMeshCa, generateMeshKeyPair, issueMeshLeafForNode, issueMeshLeafFromCsr, loadMeshCa, MESH_KEY_ALGORITHM, MESH_SIGNING_ALGORITHM, subjectCn, type MeshCaSigner, type MeshLeafMaterial } from "./mesh-ca.js";
|
|
3
3
|
export { clearProcessMeshCa, getProcessMeshCaState, loadOrGenerateMeshCa, MESH_CA_RETRY_MS, MeshCaKeeper, requireProcessMeshCa, setProcessMeshCa, type MeshCaKeeperDeps, type MeshCaState } from "./mesh-ca-keeper.js";
|
|
4
4
|
export { clearProcessMeshCrl, MeshCrl, processMeshCrl } from "./mesh-crl.js";
|
|
@@ -6,9 +6,6 @@ export { describeMeshLeaf, getProcessMeshCertificateRegistry, MESH_NODE_CERTIFIC
|
|
|
6
6
|
export { getProcessMeshTlsListenerState, type MeshTlsGateDeps, type MeshTlsListenerState, openMeshTlsWhenRevocationsLoaded, setProcessMeshTlsListenerState } from "./mesh-tls-gate.js";
|
|
7
7
|
export { renewMeshCertificate, revokeMeshCertificate, type MeshLog, type MeshPeers, type MeshRegistrations, type NodeMeshClient, type RenewMeshDeps, type RenewMeshResult, type RevokeMeshResult } from "./mesh-renewal.js";
|
|
8
8
|
export { dropProcessPeer, emitProcessNodeRegistered, getProcessPeerLeaf, onProcessNodeRegistered, getProcessNodeMeshTransport, isProcessVerifiedMeshPeer, setProcessMeshPeerTransportLookup, type MeshPeerLeaf, type MeshPeerTransportLookup, type MeshTransport } from "./mesh-peer-transport.js";
|
|
9
|
-
export { enrollMeshNode } from "./mesh-enroll.js";
|
|
10
|
-
export type { EnrollMeshNodeDeps, MeshEnrollRequest, MeshEnrollResult } from "./mesh-enroll.js";
|
|
11
|
-
export { JoinTokenJtiStore, mintMeshJoinToken, processJoinTokenJtiStore, verifyMeshJoinToken, type MeshJoinTokenClaims, type MintJoinTokenInput } from "./mesh-join-token.js";
|
|
12
9
|
export { getProcessMeshTlsEnabler, requestProcessMeshTlsEnable, setProcessMeshTlsEnabler, type MeshTlsEnabler } from "./mesh-tls-enabler.js";
|
|
13
10
|
export { helloMeshTlsPort, keepOnlyGossipNodes, MESH_TLS_PORT_HELLO_FIELD, TlsTcpTransporter, type FilteredGossip, type MeshTlsMaterial, type TlsTcpTransporterOptions, type VerifiedMeshPeer } from "./tls-tcp-transporter.js";
|
|
14
11
|
export * from "./pairing/index.js";
|
|
@@ -21,7 +21,7 @@ export interface MeshLeafMaterial {
|
|
|
21
21
|
}
|
|
22
22
|
/** SHA-256 fingerprint of the DER cert, colon-hex uppercase (Node style). */
|
|
23
23
|
export declare function caFingerprint(certPem: string): string;
|
|
24
|
-
/** Compact fingerprint (lowercase hex, no colons)
|
|
24
|
+
/** Compact fingerprint (lowercase hex, no colons). */
|
|
25
25
|
export declare function caFingerprintCompact(certPem: string): string;
|
|
26
26
|
export declare function generateMeshCa(now?: Date): Promise<MeshCaSigner>;
|
|
27
27
|
export declare function loadMeshCa(certPem: string, keyPem: string): Promise<MeshCaSigner>;
|
|
@@ -121,7 +121,7 @@ export interface RevokeMeshResult {
|
|
|
121
121
|
}
|
|
122
122
|
/**
|
|
123
123
|
* Revoke every live mesh leaf of `nodeId` and cut its connection. The node cannot
|
|
124
|
-
* reconnect: it must
|
|
124
|
+
* reconnect: it must be paired again. The node is NOT forgotten
|
|
125
125
|
* (that stays `clusterNodes.forgetNode`).
|
|
126
126
|
*/
|
|
127
127
|
export declare function revokeMeshCertificate(deps: {
|
|
@@ -56,12 +56,6 @@ interface RegisterNodeParams {
|
|
|
56
56
|
*/
|
|
57
57
|
readonly nativeCaps?: readonly RegisteredNativeCap[];
|
|
58
58
|
/**
|
|
59
|
-
* SHA-256 hash of the node's cluster secret. Optional — absent
|
|
60
|
-
* when the node has no secret configured. Verified by the `registerNode`
|
|
61
|
-
* receiver; never carries the raw secret. (Cluster-secret registration gate.)
|
|
62
|
-
*/
|
|
63
|
-
readonly clusterSecretHash?: string;
|
|
64
|
-
/**
|
|
65
59
|
* The node's root-package identity. Optional — absent from UDS child
|
|
66
60
|
* manifests and pre-phase-2 agents; present on agents running the
|
|
67
61
|
* runtime-updatable root model.
|
|
@@ -23,17 +23,19 @@ interface CallRegisterNodeOptions {
|
|
|
23
23
|
readonly signal?: AbortSignal;
|
|
24
24
|
/** Optional logger for retry diagnostics. */
|
|
25
25
|
readonly log?: (msg: string) => void;
|
|
26
|
+
/** Told about every failed attempt (the loop keeps going); lets the caller surface a cause. */
|
|
27
|
+
readonly onAttemptFailed?: (err: unknown) => void;
|
|
26
28
|
}
|
|
27
29
|
/**
|
|
28
30
|
* Build a `RegisterNodeParams` from a node id, its per-addon manifests,
|
|
29
|
-
* optionally its device-scoped native caps, optionally the
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
* omitted
|
|
33
|
-
*
|
|
34
|
-
*
|
|
31
|
+
* optionally its device-scoped native caps, and optionally the node's
|
|
32
|
+
* root-package identity (runtime-updatable node packages: version
|
|
33
|
+
* visibility). `nativeCaps` is omitted entirely on the first handshake;
|
|
34
|
+
* `rootPackage` is omitted by nodes that do not run the root-package model
|
|
35
|
+
* (UDS children). Who the sender is comes from its certificate (D857), not
|
|
36
|
+
* from the payload.
|
|
35
37
|
*/
|
|
36
|
-
declare function buildNodeManifest(nodeId: string, addons: readonly RegisteredAddonManifest[], nativeCaps?: readonly RegisteredNativeCap[],
|
|
38
|
+
declare function buildNodeManifest(nodeId: string, addons: readonly RegisteredAddonManifest[], nativeCaps?: readonly RegisteredNativeCap[], rootPackage?: NodeRootPackageInfo): RegisterNodeParams;
|
|
37
39
|
/**
|
|
38
40
|
* Call `<target>.registerNode` and retry until the parent acks. The loop
|
|
39
41
|
* terminates ONLY on a successful ack or an abort — there is no fixed
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { v as DATABASE_SNAPSHOT_SUFFIX } from "./dist-
|
|
1
|
+
import { v as DATABASE_SNAPSHOT_SUFFIX } from "./dist-DjD2M79P.mjs";
|
|
2
2
|
import { createCipheriv, createDecipheriv, createHash, createPrivateKey, createPublicKey, diffieHellman, generateKeyPairSync, hkdfSync, randomBytes } from "node:crypto";
|
|
3
3
|
import { Buffer as Buffer$1 } from "buffer";
|
|
4
4
|
import * as fsp from "node:fs/promises";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const require_chunk = require("./chunk-Cek0wNdY.js");
|
|
2
|
-
const require_dist = require("./dist-
|
|
2
|
+
const require_dist = require("./dist-DVe0Nsp8.js");
|
|
3
3
|
let node_crypto = require("node:crypto");
|
|
4
4
|
let buffer = require("buffer");
|
|
5
5
|
let node_fs_promises = require("node:fs/promises");
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Keeps the hub's cluster-secret gate in step with System → Cluster (D797,
|
|
3
|
-
* D802).
|
|
4
|
-
*
|
|
5
|
-
* The field is a `password` of `system-config`: its `system-settings` row
|
|
6
|
-
* (`cluster.clusterSecret`) holds a keychain marker, the value lives in the
|
|
7
|
-
* keychain (owner `system`). The gate the mesh join reads:
|
|
8
|
-
*
|
|
9
|
-
* - no marker → the secret is MANDATORY (D802): the keeper asks
|
|
10
|
-
* its owner to generate one (`generateSecret`), and
|
|
11
|
-
* until that succeeds the gate is `off` — no node can
|
|
12
|
-
* authenticate (mesh auth is always enforced, D821);
|
|
13
|
-
* - marker + value → `on` — nodes prove the secret;
|
|
14
|
-
* - marker, no answer → `unknown` — refused, retryably, and retried here.
|
|
15
|
-
* A locked keychain or a value lost to a reset NEVER opens the gate, and
|
|
16
|
-
* never triggers a generation (the operator decides what replaces a value
|
|
17
|
-
* the keychain lost).
|
|
18
|
-
*
|
|
19
|
-
* It also publishes the mesh mode (`cluster.meshAuth`, `mesh-auth-mode.ts`).
|
|
20
|
-
*/
|
|
21
|
-
import { type SecretsAccess } from "@camstack/types";
|
|
22
|
-
/** The field key inside the `cluster` section. */
|
|
23
|
-
export declare const CLUSTER_SECRET_FIELD = "clusterSecret";
|
|
24
|
-
export declare const CLUSTER_SECRET_RETRY_MS = 3e4;
|
|
25
|
-
interface KeeperLogger {
|
|
26
|
-
info(message: string, meta?: {
|
|
27
|
-
meta?: Record<string, unknown>;
|
|
28
|
-
}): void;
|
|
29
|
-
error(message: string, meta?: {
|
|
30
|
-
meta?: Record<string, unknown>;
|
|
31
|
-
}): void;
|
|
32
|
-
}
|
|
33
|
-
export interface ClusterSecretKeeperDeps {
|
|
34
|
-
/** Keychain handle for owner `system`; `null` without a keychain door. */
|
|
35
|
-
readonly secrets: SecretsAccess | null;
|
|
36
|
-
/** The stored `cluster` section (markers, never values). Throws when unreadable. */
|
|
37
|
-
readonly readSection: () => Promise<Record<string, unknown>>;
|
|
38
|
-
readonly logger: KeeperLogger;
|
|
39
|
-
readonly retryMs?: number;
|
|
40
|
-
/**
|
|
41
|
-
* Generate and store a new secret (D802). Called when no marker is stored.
|
|
42
|
-
* Throws when it cannot (no keychain, locked): the keeper retries on its
|
|
43
|
-
* timer. Absent → nothing is generated (tests of the D797 states).
|
|
44
|
-
*/
|
|
45
|
-
readonly generateSecret?: () => Promise<void>;
|
|
46
|
-
}
|
|
47
|
-
export declare class ClusterSecretKeeper {
|
|
48
|
-
private readonly deps;
|
|
49
|
-
private retryTimer;
|
|
50
|
-
private unsubscribe;
|
|
51
|
-
private stopped;
|
|
52
|
-
private last;
|
|
53
|
-
constructor(deps: ClusterSecretKeeperDeps);
|
|
54
|
-
start(): Promise<void>;
|
|
55
|
-
stop(): void;
|
|
56
|
-
/** Re-read the row and the keychain; publish the gate. */
|
|
57
|
-
reload(): Promise<void>;
|
|
58
|
-
private generate;
|
|
59
|
-
private compute;
|
|
60
|
-
private report;
|
|
61
|
-
private scheduleRetry;
|
|
62
|
-
}
|
|
63
|
-
export {};
|
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
import { Nr as buildSecretRef } from "./dist-CYcBqnXk.mjs";
|
|
2
|
-
import { createHash, timingSafeEqual } from "node:crypto";
|
|
3
|
-
//#region src/kernel/moleculer/cluster-secret.ts
|
|
4
|
-
/**
|
|
5
|
-
* Cluster-secret registration gate (opt-in). A registering node sends a
|
|
6
|
-
* SHA-256 hash of its cluster secret; the receiver of a `registerNode` RPC
|
|
7
|
-
* verifies it. The raw secret is never transmitted.
|
|
8
|
-
*
|
|
9
|
-
* Where the secret lives (D797) — never in an environment variable:
|
|
10
|
-
* - the HUB: the keychain, owner `system` ({@link CLUSTER_SECRET_REF}), set
|
|
11
|
-
* from System → Cluster (a `password` field of `system-config`, whose
|
|
12
|
-
* `system-settings` row {@link CLUSTER_SECRET_SETTINGS_KEY} holds the
|
|
13
|
-
* marker). Empty = the gate is off, exactly as a hub without a secret
|
|
14
|
-
* always was;
|
|
15
|
-
* - an AGENT: its bootstrap credential, entered at pairing / first run and
|
|
16
|
-
* kept in its own `agent.json` (0600) — or, in the desktop app, in the OS
|
|
17
|
-
* keychain — because it needs it before it can reach the hub.
|
|
18
|
-
*/
|
|
19
|
-
/** The keychain ref of the hub's cluster secret: `secret://system/global/clusterSecret`. */
|
|
20
|
-
var CLUSTER_SECRET_REF = buildSecretRef({
|
|
21
|
-
owner: "system",
|
|
22
|
-
scope: { kind: "global" },
|
|
23
|
-
fieldPath: "clusterSecret"
|
|
24
|
-
});
|
|
25
|
-
/** The `system-settings` key whose value is the cluster secret's keychain marker. */
|
|
26
|
-
var CLUSTER_SECRET_SETTINGS_KEY = "cluster.clusterSecret";
|
|
27
|
-
/** Moleculer error `type` marking a registration rejected for a bad cluster secret. */
|
|
28
|
-
var CLUSTER_SECRET_MISMATCH_TYPE = "CLUSTER_SECRET_MISMATCH";
|
|
29
|
-
/** Process exit code a runner uses when its registration is rejected for a bad secret. */
|
|
30
|
-
var CLUSTER_SECRET_REJECTED_EXIT_CODE = 78;
|
|
31
|
-
/** SHA-256 hex digest of a cluster secret. Never transmit or log the raw secret. */
|
|
32
|
-
function hashClusterSecret(secret) {
|
|
33
|
-
return createHash("sha256").update(secret, "utf8").digest("hex");
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* True if a registration carrying `presentedHash` is allowed against a
|
|
37
|
-
* receiver whose own secret hashes to `expectedHash`.
|
|
38
|
-
* - `expectedHash` undefined → the gate is OFF; everything is allowed.
|
|
39
|
-
* - otherwise `presentedHash` must be present and equal (constant-time).
|
|
40
|
-
*/
|
|
41
|
-
function clusterSecretMatches(expectedHash, presentedHash) {
|
|
42
|
-
if (expectedHash === void 0) return true;
|
|
43
|
-
if (presentedHash === void 0 || presentedHash.length !== expectedHash.length) return false;
|
|
44
|
-
return timingSafeEqual(Buffer.from(expectedHash), Buffer.from(presentedHash));
|
|
45
|
-
}
|
|
46
|
-
/** Recognises a cluster-secret rejection, including after a Moleculer RPC round-trip. */
|
|
47
|
-
function isClusterSecretMismatchError(err) {
|
|
48
|
-
if (typeof err !== "object" || err === null || !("type" in err)) return false;
|
|
49
|
-
const { type } = err;
|
|
50
|
-
return type === CLUSTER_SECRET_MISMATCH_TYPE;
|
|
51
|
-
}
|
|
52
|
-
/** Moleculer error `type` of a registration refused because the hub cannot read its own secret yet. */
|
|
53
|
-
var CLUSTER_SECRET_UNAVAILABLE_TYPE = "CLUSTER_SECRET_UNAVAILABLE";
|
|
54
|
-
function checkClusterSecret(gate, presentedHash) {
|
|
55
|
-
switch (gate.kind) {
|
|
56
|
-
case "off": return "allow";
|
|
57
|
-
case "unknown": return "unavailable";
|
|
58
|
-
case "on": return clusterSecretMatches(gate.hash, presentedHash) ? "allow" : "mismatch";
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
var GATE_SLOT = Symbol.for("camstack.cluster.secret-gate");
|
|
62
|
-
var NOT_LOADED = {
|
|
63
|
-
kind: "unknown",
|
|
64
|
-
reason: "not-loaded"
|
|
65
|
-
};
|
|
66
|
-
function isGate(value) {
|
|
67
|
-
if (value === null || typeof value !== "object") return false;
|
|
68
|
-
const kind = Reflect.get(value, "kind");
|
|
69
|
-
if (kind === "off") return true;
|
|
70
|
-
if (kind === "on") return typeof Reflect.get(value, "hash") === "string";
|
|
71
|
-
return kind === "unknown" && typeof Reflect.get(value, "reason") === "string";
|
|
72
|
-
}
|
|
73
|
-
/** Register the hub's gate. Called by `system-config`, which owns the field. */
|
|
74
|
-
function setProcessClusterSecretGate(gate) {
|
|
75
|
-
Reflect.set(globalThis, GATE_SLOT, gate);
|
|
76
|
-
}
|
|
77
|
-
/** The hub's gate; `unknown` until `system-config` loaded it. */
|
|
78
|
-
function getProcessClusterSecretGate() {
|
|
79
|
-
const value = Reflect.get(globalThis, GATE_SLOT);
|
|
80
|
-
return isGate(value) ? value : NOT_LOADED;
|
|
81
|
-
}
|
|
82
|
-
/** `secret://system/global/meshCaKey` — EC P-256 PKCS#8 PEM of the hub mesh CA. */
|
|
83
|
-
var MESH_CA_KEY_REF = buildSecretRef({
|
|
84
|
-
owner: "system",
|
|
85
|
-
scope: { kind: "global" },
|
|
86
|
-
fieldPath: "meshCaKey"
|
|
87
|
-
});
|
|
88
|
-
/** `system-settings` key holding the public CA certificate PEM. */
|
|
89
|
-
var MESH_CA_SETTINGS_KEY = "cluster.meshCa";
|
|
90
|
-
/** Field inside the `cluster` section. */
|
|
91
|
-
var MESH_CA_FIELD = "meshCa";
|
|
92
|
-
/** Join-token / leaf lifetimes. */
|
|
93
|
-
var MESH_JOIN_TOKEN_MAX_TTL_SEC = 3600;
|
|
94
|
-
var MESH_CA_VALIDITY_DAYS = 3650;
|
|
95
|
-
var DEFAULT_HUB_TLS_TCP_PORT = 6443;
|
|
96
|
-
/** Subject of the mesh root. Distinct from the HTTPS local CA. */
|
|
97
|
-
var MESH_CA_COMMON_NAME = "CamStack Mesh CA";
|
|
98
|
-
/** Client + server auth EKU OIDs (mutual TLS). */
|
|
99
|
-
var SERVER_AUTH_OID = "1.3.6.1.5.5.7.3.1";
|
|
100
|
-
var CLIENT_AUTH_OID = "1.3.6.1.5.5.7.3.2";
|
|
101
|
-
//#endregion
|
|
102
|
-
export { getProcessClusterSecretGate as _, MESH_CA_KEY_REF as a, setProcessClusterSecretGate as b, MESH_JOIN_TOKEN_MAX_TTL_SEC as c, CLUSTER_SECRET_REF as d, CLUSTER_SECRET_REJECTED_EXIT_CODE as f, clusterSecretMatches as g, checkClusterSecret as h, MESH_CA_FIELD as i, SERVER_AUTH_OID as l, CLUSTER_SECRET_UNAVAILABLE_TYPE as m, DEFAULT_HUB_TLS_TCP_PORT as n, MESH_CA_SETTINGS_KEY as o, CLUSTER_SECRET_SETTINGS_KEY as p, MESH_CA_COMMON_NAME as r, MESH_CA_VALIDITY_DAYS as s, CLIENT_AUTH_OID as t, CLUSTER_SECRET_MISMATCH_TYPE as u, hashClusterSecret as v, isClusterSecretMismatchError as y };
|