@camstack/system 1.2.381 → 1.2.383

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.
Files changed (133) hide show
  1. package/dist/addon-runner.js +4 -2
  2. package/dist/addon-runner.mjs +4 -2
  3. package/dist/addon-utils.js +1 -1
  4. package/dist/addon-utils.mjs +1 -1
  5. package/dist/auth/admin-token-manager.d.ts +75 -0
  6. package/dist/auth/api-key-manager.d.ts +1 -14
  7. package/dist/auth/auth-audit-log.d.ts +59 -0
  8. package/dist/auth/auth-manager.d.ts +28 -16
  9. package/dist/auth/cidr.d.ts +22 -0
  10. package/dist/auth/login-session-manager.d.ts +158 -0
  11. package/dist/auth/user-management-internal.d.ts +69 -0
  12. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
  13. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
  14. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
  15. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
  16. package/dist/builtins/alerts/alerts.addon.js +1 -1
  17. package/dist/builtins/alerts/alerts.addon.mjs +1 -1
  18. package/dist/builtins/autotrack/index.js +1 -1
  19. package/dist/builtins/autotrack/index.mjs +1 -1
  20. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.d.ts +14 -0
  21. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +291 -3631
  22. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +284 -3617
  23. package/dist/builtins/backup-orchestrator/encryption-key-store.d.ts +36 -0
  24. package/dist/builtins/backup-orchestrator/manifest-store.d.ts +19 -1
  25. package/dist/builtins/backup-orchestrator/restore-archive.d.ts +24 -0
  26. package/dist/builtins/calendars/calendars.addon.js +1 -1
  27. package/dist/builtins/calendars/calendars.addon.mjs +1 -1
  28. package/dist/builtins/camera-grid/index.js +1 -1
  29. package/dist/builtins/camera-grid/index.mjs +1 -1
  30. package/dist/builtins/composer/composer.addon.js +2 -2
  31. package/dist/builtins/composer/composer.addon.mjs +2 -2
  32. package/dist/builtins/console-logging/index.js +1 -1
  33. package/dist/builtins/console-logging/index.mjs +1 -1
  34. package/dist/builtins/core-blocks/core-blocks.addon.js +2 -2
  35. package/dist/builtins/core-blocks/core-blocks.addon.mjs +2 -2
  36. package/dist/builtins/device-manager/device-manager.addon.js +2 -2
  37. package/dist/builtins/device-manager/device-manager.addon.mjs +2 -2
  38. package/dist/builtins/hub-forwarder/index.js +1 -1
  39. package/dist/builtins/hub-forwarder/index.mjs +1 -1
  40. package/dist/builtins/keychain/index.js +1110 -735
  41. package/dist/builtins/keychain/index.mjs +1109 -734
  42. package/dist/builtins/keychain/keychain-reset-trigger.d.ts +25 -0
  43. package/dist/builtins/keychain/keychain-service.d.ts +36 -3
  44. package/dist/builtins/keychain/keychain-store.d.ts +24 -1
  45. package/dist/builtins/keychain/system-held-secrets.d.ts +2 -1
  46. package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
  47. package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
  48. package/dist/builtins/local-auth/local-auth.addon.d.ts +16 -0
  49. package/dist/builtins/local-auth/local-auth.addon.js +1028 -294
  50. package/dist/builtins/local-auth/local-auth.addon.mjs +1035 -299
  51. package/dist/builtins/local-network/local-network.addon.js +3 -3
  52. package/dist/builtins/local-network/local-network.addon.mjs +3 -3
  53. package/dist/builtins/loki-logging/index.js +97 -29
  54. package/dist/builtins/loki-logging/index.mjs +97 -29
  55. package/dist/builtins/loki-logging/loki-logging.addon.d.ts +7 -23
  56. package/dist/builtins/loki-logging/retire-enabled-flag.d.ts +23 -0
  57. package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
  58. package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
  59. package/dist/builtins/platform-probe/index.js +1 -1
  60. package/dist/builtins/platform-probe/index.mjs +1 -1
  61. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
  62. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
  63. package/dist/builtins/snapshot/index.js +1 -1
  64. package/dist/builtins/snapshot/index.mjs +1 -1
  65. package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
  66. package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
  67. package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +0 -0
  68. package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +0 -0
  69. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +2 -2
  70. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +2 -2
  71. package/dist/builtins/system-backup/backup-encryption.d.ts +57 -0
  72. package/dist/builtins/system-backup/system-backup.service.d.ts +16 -1
  73. package/dist/builtins/system-config/cluster-secret-keeper.d.ts +7 -0
  74. package/dist/builtins/system-config/index.d.ts +1 -0
  75. package/dist/builtins/system-config/index.js +2 -0
  76. package/dist/builtins/system-config/index.mjs +2 -2
  77. package/dist/builtins/system-config/mesh-actions.d.ts +19 -0
  78. package/dist/builtins/system-config/system-config.addon.d.ts +47 -4
  79. package/dist/builtins/system-config/system-config.addon.js +87858 -43
  80. package/dist/builtins/system-config/system-config.addon.mjs +87813 -39
  81. package/dist/builtins/winston-logging/index.js +1 -1
  82. package/dist/builtins/winston-logging/index.mjs +1 -1
  83. package/dist/{child-cap-dispatch-hf-Gce_4.js → child-cap-dispatch-BD8fhJ1b.js} +7 -4
  84. package/dist/{child-cap-dispatch-BTe4eKep.mjs → child-cap-dispatch-C68N2a6Y.mjs} +11 -8
  85. package/dist/{composition-sources-4SmsP0O4.js → composition-sources-ChpT_Yw4.js} +1 -1
  86. package/dist/{composition-sources-CgOQVIwa.mjs → composition-sources-DM7Ft_tp.mjs} +1 -1
  87. package/dist/{cluster-secret-BUiG8DCo.js → constants-CDpry1_T.js} +82 -1
  88. package/dist/{cluster-secret-DgJTZ4qY.mjs → constants-e3mCa1jG.mjs} +23 -2
  89. package/dist/{dist-BugrtARh.js → dist-CUNGH0fs.js} +1755 -157
  90. package/dist/{dist-BC0GnGeg.mjs → dist-osl3bkF0.mjs} +1732 -158
  91. package/dist/{event-loop-stall-monitor-GgpnfAC0.mjs → event-loop-stall-monitor-BeeWMnyT.mjs} +15 -15
  92. package/dist/{event-loop-stall-monitor-CnQ-K6Gn.js → event-loop-stall-monitor-Dk28EF8B.js} +15 -15
  93. package/dist/{hub-cap-forward-CH6_VWVO.mjs → hub-cap-forward-CDiN1p98.mjs} +18 -2
  94. package/dist/{hub-cap-forward-COCmYaup.js → hub-cap-forward-W8oEm4ME.js} +23 -1
  95. package/dist/index.d.ts +16 -1
  96. package/dist/index.js +1023 -83525
  97. package/dist/index.mjs +1218 -83794
  98. package/dist/{jwt-signing-key-CsuVKA1W.mjs → jwt-signing-key-MQLxLfgF.mjs} +1 -1
  99. package/dist/{jwt-signing-key-CjoZcol8.js → jwt-signing-key-WI6z7JBo.js} +1 -1
  100. package/dist/kernel/index.d.ts +17 -1
  101. package/dist/kernel/moleculer/agent-mesh-authenticator.d.ts +41 -0
  102. package/dist/kernel/moleculer/broker-factory.d.ts +25 -2
  103. package/dist/kernel/moleculer/child-addon-call-dispatch.d.ts +1 -0
  104. package/dist/kernel/moleculer/hub-service.d.ts +9 -0
  105. package/dist/kernel/moleculer/mesh-access-middleware.d.ts +33 -0
  106. package/dist/kernel/moleculer/mesh-auth-mode.d.ts +64 -0
  107. package/dist/kernel/moleculer/mesh-authenticator.d.ts +71 -0
  108. package/dist/kernel/moleculer/mesh-auto-enforce.d.ts +26 -0
  109. package/dist/kernel/moleculer/mesh-join-client.d.ts +51 -0
  110. package/dist/kernel/moleculer/mesh-join-proof.d.ts +39 -0
  111. package/dist/kernel/moleculer/mesh-mtls/constants.d.ts +20 -0
  112. package/dist/kernel/moleculer/mesh-mtls/index.d.ts +9 -0
  113. package/dist/kernel/moleculer/mesh-mtls/mesh-ca-keeper.d.ts +55 -0
  114. package/dist/kernel/moleculer/mesh-mtls/mesh-ca.d.ts +45 -0
  115. package/dist/kernel/moleculer/mesh-mtls/mesh-crl.d.ts +16 -0
  116. package/dist/kernel/moleculer/mesh-mtls/mesh-enroll.d.ts +27 -0
  117. package/dist/kernel/moleculer/mesh-mtls/mesh-join-token.d.ts +55 -0
  118. package/dist/kernel/moleculer/mesh-mtls/mesh-tls-enabler.d.ts +5 -0
  119. package/dist/kernel/moleculer/mesh-mtls/tls-tcp-transporter.d.ts +92 -0
  120. package/dist/kernel/system-settings-policy.d.ts +4 -3
  121. package/dist/kernel/transport/hub-cap-forward.d.ts +14 -3
  122. package/dist/kernel/transport/index.d.ts +1 -1
  123. package/dist/ms-DlIWNkkk.mjs +160 -0
  124. package/dist/ms-t68_FaqE.js +171 -0
  125. package/dist/restore-archive-C5f9yX90.js +4139 -0
  126. package/dist/restore-archive-CZRtI1k9.mjs +4045 -0
  127. package/dist/{retired-settings-keys-MCVhxPkJ.mjs → retired-settings-keys-LuDd4y3M.mjs} +1 -1
  128. package/dist/{retired-settings-keys-DCuetwOt.js → retired-settings-keys-WLrbzdPR.js} +1 -1
  129. package/dist/tls-BWpwU-d5.js +1160 -0
  130. package/dist/tls-C2NT-Orr.mjs +949 -0
  131. package/dist/{tls-CCMX7MjX.js → x509.es-BhTzcFhZ.js} +65 -1108
  132. package/dist/{tls-CJHogwTl.mjs → x509.es-Xf3K_brW.mjs} +40 -950
  133. package/package.json +3 -2
@@ -1,4 +1,4 @@
1
- import { xr as buildSecretRef } from "./dist-BC0GnGeg.mjs";
1
+ import { Sr as buildSecretRef } from "./dist-osl3bkF0.mjs";
2
2
  import { randomBytes } from "node:crypto";
3
3
  //#region src/auth/jwt-signing-key.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- const require_dist = require("./dist-BugrtARh.js");
1
+ const require_dist = require("./dist-CUNGH0fs.js");
2
2
  let node_crypto = require("node:crypto");
3
3
  //#region src/auth/jwt-signing-key.ts
4
4
  /**
@@ -37,8 +37,10 @@ export type { AddonSettingsView } from './config-manager.js';
37
37
  export { DeviceRegistry } from './device-registry.js';
38
38
  export { buildStorageLocationRegistry } from './storage-location-registry.js';
39
39
  export type { StorageLocationRegistry } from './storage-location-registry.js';
40
- export { createBroker, deriveAgentListenPort } from './moleculer/broker-factory.js';
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, 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';
43
+ export type { MeshCaSigner, MeshEnrollResult, MeshJoinTokenClaims, MeshTlsMaterial, } from './moleculer/mesh-mtls/index.js';
42
44
  export { type AddonDeploySource, isAddonDeploySource } from './moleculer/addon-deploy-source.js';
43
45
  export { createAddonService, validateProviderRegistrations, } from './moleculer/addon-service-factory.js';
44
46
  export { createCoreCapService, CORE_CAP_SERVICE_NAME } from './moleculer/core-cap-service.js';
@@ -54,6 +56,20 @@ export { callRegisterNodeWithRetry, buildNodeManifest } from './moleculer/regist
54
56
  export type { RegisterNodeBroker, CallRegisterNodeOptions, } from './moleculer/register-node-client.js';
55
57
  export { hashClusterSecret, clusterSecretMatches, isClusterSecretMismatchError, CLUSTER_SECRET_MISMATCH_TYPE, CLUSTER_SECRET_REJECTED_EXIT_CODE, CLUSTER_SECRET_REF, CLUSTER_SECRET_SETTINGS_KEY, CLUSTER_SECRET_UNAVAILABLE_TYPE, checkClusterSecret, getProcessClusterSecretGate, setProcessClusterSecretGate, } from './moleculer/cluster-secret.js';
56
58
  export type { ClusterSecretGate, ClusterSecretVerdict } from './moleculer/cluster-secret.js';
59
+ export { MeshAuthenticator, isRemoteForbiddenAction, MESH_JOIN_CHALLENGE_TTL_MS, } from './moleculer/mesh-authenticator.js';
60
+ export type { MeshAuthenticatorDeps, MeshCallVerdict, } from './moleculer/mesh-authenticator.js';
61
+ export { createMeshAccessMiddleware, stripForgedIdentity, } from './moleculer/mesh-access-middleware.js';
62
+ export type { MeshAccessMiddlewareOptions, MeshCallGate, } from './moleculer/mesh-access-middleware.js';
63
+ export { AgentMeshAuthenticator, AGENT_REGISTER_NODE_ACTION, isOwnChildNodeId, isRemoteForbiddenOnAgent, } from './moleculer/agent-mesh-authenticator.js';
64
+ export type { AgentMeshAuthenticatorDeps } from './moleculer/agent-mesh-authenticator.js';
65
+ export { MeshJoinClient } from './moleculer/mesh-join-client.js';
66
+ export type { MeshJoinCall, MeshJoinClientOptions, MeshJoinState, } from './moleculer/mesh-join-client.js';
67
+ 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';
68
+ export type { MeshJoinAuthenticateParams, MeshJoinAuthenticateResult, MeshJoinChallenge, } from './moleculer/mesh-join-proof.js';
69
+ export { getProcessMeshAuthMode, getProcessMeshAuthStatus, isMeshAuthMode, MESH_AUTH_MODE_FIELD, parseMeshAuthMode, requestProcessMeshEnforcement, setProcessMeshAuthMode, setProcessMeshAuthStatusSource, setProcessMeshEnforcer, } from './moleculer/mesh-auth-mode.js';
70
+ export { decideMeshAutoEnforce, MESH_AUTO_ENFORCE_GRACE_MS, } from './moleculer/mesh-auto-enforce.js';
71
+ export type { MeshAutoEnforceDecision, MeshAutoEnforceInput, } from './moleculer/mesh-auto-enforce.js';
72
+ export type { MeshAuthMode, MeshAuthStatus, MeshEnforcer, MeshNodeAuthEntry, MeshNodeAuthState, } from './moleculer/mesh-auth-mode.js';
57
73
  export { serializeTypedArrays } from './moleculer/typed-array-serde.js';
58
74
  export { createReadinessService, createReadinessServiceForRegistry, AGENT_READINESS_SERVICE_NAME, } from './moleculer/readiness-service.js';
59
75
  export type { ReadinessServiceDeps } from './moleculer/readiness-service.js';
@@ -0,0 +1,41 @@
1
+ import { MeshAuthMode, MeshNodeAuthState } from './mesh-auth-mode.js';
2
+ import { MeshCallVerdict } from './mesh-authenticator.js';
3
+ import { MeshJoinState } from './mesh-join-client.js';
4
+ /** The child's register action on its parent agent. */
5
+ export declare const AGENT_REGISTER_NODE_ACTION = "$agent.registerNode";
6
+ export declare function isRemoteForbiddenOnAgent(action: string): boolean;
7
+ export declare function isOwnChildNodeId(ownNodeId: string, sender: string): boolean;
8
+ export interface AgentMeshAuthenticatorDeps {
9
+ readonly ownNodeId: string;
10
+ readonly hubNodeId?: string;
11
+ /** True when `agent.json` holds a cluster secret. */
12
+ readonly hasSecret: () => boolean;
13
+ readonly now?: () => number;
14
+ /** First time a peer is tolerated without proof on this connection. */
15
+ readonly onTolerated?: (nodeId: string, action: string) => void;
16
+ }
17
+ export declare class AgentMeshAuthenticator {
18
+ private readonly deps;
19
+ private readonly nodes;
20
+ private readonly hubNodeId;
21
+ private readonly now;
22
+ constructor(deps: AgentMeshAuthenticatorDeps);
23
+ /** Current mode: secret configured → enforce; else tolerate (upgrade path). */
24
+ mode(): MeshAuthMode;
25
+ /**
26
+ * Reflect a settled mesh join. `authenticated` stamps the hub; a blocking
27
+ * failure forgets it so an impostor cannot call in; transitional states
28
+ * leave the hub unmarked (calls are tolerated while mode is `transition`).
29
+ */
30
+ noteHubJoinState(state: MeshJoinState): void;
31
+ /** A child's `$agent.registerNode` was accepted (secret hash matched or none required). */
32
+ noteChildRegistered(sender: string, proof?: 'authenticated' | 'legacy'): void;
33
+ /** The peer's connection dropped. */
34
+ forget(nodeId: string): void;
35
+ admitCall(sender: string, action: string): MeshCallVerdict;
36
+ admitEvent(sender: string, eventName: string): MeshCallVerdict;
37
+ stateOf(nodeId: string): MeshNodeAuthState;
38
+ authenticatedNodeIds(): readonly string[];
39
+ private admitSender;
40
+ private record;
41
+ }
@@ -1,4 +1,5 @@
1
- import { ServiceBroker } from 'moleculer';
1
+ import { ServiceBroker, Middleware } from 'moleculer';
2
+ import { MeshTlsMaterial, TlsTcpTransporter } from './mesh-mtls/index.js';
2
3
  interface BrokerConfig {
3
4
  readonly nodeID: string;
4
5
  readonly mode: 'hub' | 'agent' | 'test';
@@ -10,6 +11,11 @@ interface BrokerConfig {
10
11
  * when UDP multicast discovery is disabled.
11
12
  */
12
13
  readonly tcpPort?: number;
14
+ /**
15
+ * Second hub listen port for mesh mTLS (Release A). Default 6443.
16
+ * Clear traffic stays on {@link tcpPort}; enrolled agents dial this.
17
+ */
18
+ readonly tlsPort?: number;
13
19
  /** UDP port for cluster discovery (default: 4445). */
14
20
  readonly udpPort?: number;
15
21
  /**
@@ -20,6 +26,20 @@ interface BrokerConfig {
20
26
  * on one host.
21
27
  */
22
28
  readonly agentListenPort?: number;
29
+ /**
30
+ * Broker middlewares (D802): the hub passes its mesh gate
31
+ * (`createMeshAccessMiddleware`); an agent passes inbound access
32
+ * (`AgentMeshAuthenticator` + the same middleware) and its outbound join
33
+ * gate (`MeshJoinClient.middleware`). They must be given at construction —
34
+ * Moleculer wraps action handlers when services register.
35
+ */
36
+ readonly middlewares?: readonly Middleware[];
37
+ /**
38
+ * Mesh mTLS material. On the hub, enables the TLS listener (may also be
39
+ * attached later via {@link getBrokerTlsTransporter}). On an agent, dials
40
+ * the hub's TLS port (6443) instead of clear 6000.
41
+ */
42
+ readonly meshTls?: MeshTlsMaterial;
23
43
  }
24
44
  /**
25
45
  * Derive a STABLE Moleculer reader port for an agent from its nodeID.
@@ -44,5 +64,8 @@ interface BrokerConfig {
44
64
  */
45
65
  declare function deriveAgentListenPort(nodeID: string): number;
46
66
  declare function createBroker(config: BrokerConfig): ServiceBroker;
47
- export { createBroker, deriveAgentListenPort };
67
+ declare function normalizeHubUrl(raw: string, defaultPort: number): string;
68
+ /** The hub's {@link TlsTcpTransporter}, or null when the broker is not mesh-TLS. */
69
+ declare function getBrokerTlsTransporter(broker: ServiceBroker): TlsTcpTransporter | null;
70
+ export { createBroker, deriveAgentListenPort, getBrokerTlsTransporter, normalizeHubUrl };
48
71
  export type { BrokerConfig };
@@ -13,6 +13,7 @@ export interface SerializableRouteDescriptor {
13
13
  readonly path: string;
14
14
  readonly access?: string;
15
15
  readonly description?: string;
16
+ readonly rateLimit?: string;
16
17
  }
17
18
  /**
18
19
  * Resolved `addon-routes` provider lookup — the live provider object the addon
@@ -2,6 +2,7 @@ import { ServiceSchema } from 'moleculer';
2
2
  import { LogTags } from '@camstack/types';
3
3
  import { RegisterNodeParams } from './node-registry.js';
4
4
  import { ClusterSecretGate } from './cluster-secret.js';
5
+ import { MeshAuthenticator } from './mesh-authenticator.js';
5
6
  interface HubServiceDeps {
6
7
  readonly getAddonConfig: (addonId: string) => unknown;
7
8
  readonly getSettings: (scope: string, key?: string) => unknown;
@@ -32,6 +33,14 @@ interface HubServiceDeps {
32
33
  * Absent → `off` (test brokers); the hub always passes the keychain's gate.
33
34
  */
34
35
  readonly clusterSecretGate?: () => ClusterSecretGate;
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;
35
44
  }
36
45
  declare function createHubService(deps: HubServiceDeps): ServiceSchema;
37
46
  export { createHubService };
@@ -0,0 +1,33 @@
1
+ import { Middleware } from 'moleculer';
2
+ import { MeshCallVerdict } from './mesh-authenticator.js';
3
+ /** Minimal surface the middleware needs — hub and agent authenticators both fit. */
4
+ export interface MeshCallGate {
5
+ admitCall(sender: string, action: string): MeshCallVerdict;
6
+ admitEvent(sender: string, eventName: string): MeshCallVerdict;
7
+ }
8
+ /**
9
+ * The params of a request from another node, with every identity it claimed
10
+ * removed:
11
+ * - a cap action's input loses `caller` (the user identity the hub's tRPC
12
+ * router injects for `caller: 'required'` methods — `keychainAdmin.reveal`
13
+ * reads it) and `callerAddonId` (the transport's addon stamp the keychain
14
+ * owner-checks);
15
+ * - `$hub-cap-fwd.forward` keeps its envelope `callerAddonId` — the forward
16
+ * service checks it against the sender's registered manifest — but the
17
+ * forwarded `args` lose both.
18
+ */
19
+ export declare function stripForgedIdentity(action: string, params: unknown): unknown;
20
+ interface GateLogger {
21
+ warn(message: string, meta?: Record<string, unknown>): void;
22
+ }
23
+ export interface MeshAccessMiddlewareOptions {
24
+ readonly ownNodeId: string;
25
+ readonly authenticator: MeshCallGate;
26
+ readonly logger?: GateLogger;
27
+ }
28
+ /**
29
+ * Build the middleware. Pass it in `ServiceBroker({ middlewares: [...] })`
30
+ * so it wraps every service, including the ones Moleculer creates itself.
31
+ */
32
+ export declare function createMeshAccessMiddleware(options: MeshAccessMiddlewareOptions): Middleware;
33
+ export {};
@@ -0,0 +1,64 @@
1
+ /**
2
+ * How strictly the hub holds other nodes to the mesh join (D802).
3
+ *
4
+ * - `transition`: a node that has not authenticated is TOLERATED — its calls
5
+ * run, a warning names it, and System → Cluster lists it as "not
6
+ * authenticated". This is how an existing cluster upgrades without
7
+ * splitting: the hub generates its secret, the operator copies it into each
8
+ * agent, and nothing is refused meanwhile.
9
+ * - `enforced`: a node that has not authenticated is refused on every action
10
+ * and its events are dropped. The D797 hash in `registerNode` is no longer
11
+ * accepted either — only the challenge–response.
12
+ *
13
+ * `transition` ends by itself once EVERY node the hub has ever seen (the
14
+ * cluster-node history) has authenticated with the challenge–response
15
+ * (`MeshAuthenticator.onAuthenticated` → `requestProcessMeshEnforcement`).
16
+ * The operator can also switch it in System → Cluster, in both directions.
17
+ *
18
+ * The mode lives in the `cluster` section of `system-settings`
19
+ * (`cluster.meshAuth`), owned by `system-config`, published here as a process
20
+ * slot the hub's broker reads on every call — the same pattern as the cluster
21
+ * secret gate (`cluster-secret.ts`).
22
+ */
23
+ export type MeshAuthMode = 'transition' | 'enforced';
24
+ /** The field key inside the `cluster` section. */
25
+ export declare const MESH_AUTH_MODE_FIELD = "meshAuth";
26
+ export declare function isMeshAuthMode(value: unknown): value is MeshAuthMode;
27
+ /** A stored value that is not a mode reads as `transition`: never refuse on a typo. */
28
+ export declare function parseMeshAuthMode(value: unknown): MeshAuthMode;
29
+ /** How a node stands with the hub right now. */
30
+ export type MeshNodeAuthState =
31
+ /** Answered the challenge–response on its current connection. */
32
+ 'authenticated'
33
+ /** Registered with the D797 hash (replayable) — accepted in `transition` only. */
34
+ | 'legacy'
35
+ /** Presented nothing: tolerated in `transition`, refused in `enforced`. */
36
+ | 'unauthenticated';
37
+ export interface MeshNodeAuthEntry {
38
+ readonly nodeId: string;
39
+ readonly state: MeshNodeAuthState;
40
+ /** Epoch ms of the last change. */
41
+ readonly since: number;
42
+ }
43
+ /** What System → Cluster shows. */
44
+ export interface MeshAuthStatus {
45
+ readonly mode: MeshAuthMode;
46
+ readonly nodes: readonly MeshNodeAuthEntry[];
47
+ }
48
+ /** Published by `system-config` whenever the stored mode is (re)read. */
49
+ export declare function setProcessMeshAuthMode(mode: MeshAuthMode): void;
50
+ /**
51
+ * The hub's mode. Until `system-config` has read it: `transition` — the safe
52
+ * side for an upgrading cluster (nothing that worked before is refused), and
53
+ * exactly what an unread setting means.
54
+ */
55
+ export declare function getProcessMeshAuthMode(): MeshAuthMode;
56
+ export declare function clearProcessMeshAuthMode(): void;
57
+ /** Persists `enforced`; installed by `system-config`, which owns the setting. */
58
+ export type MeshEnforcer = (reason: string) => Promise<void>;
59
+ export declare function setProcessMeshEnforcer(enforcer: MeshEnforcer | null): void;
60
+ /** Ask the owner of the setting to switch to `enforced`. `false` when nobody can. */
61
+ export declare function requestProcessMeshEnforcement(reason: string): Promise<boolean>;
62
+ /** Published by the hub's broker; read by System → Cluster. */
63
+ export declare function setProcessMeshAuthStatusSource(source: (() => MeshAuthStatus) | null): void;
64
+ export declare function getProcessMeshAuthStatus(): MeshAuthStatus | null;
@@ -0,0 +1,71 @@
1
+ import { ClusterSecretGate } from './cluster-secret.js';
2
+ import { MeshAuthMode, MeshAuthStatus, MeshNodeAuthState } from './mesh-auth-mode.js';
3
+ import { MeshJoinAuthenticateParams, MeshJoinAuthenticateResult, MeshJoinChallenge } from './mesh-join-proof.js';
4
+ /** A challenge is answered within this window or not at all. */
5
+ export declare const MESH_JOIN_CHALLENGE_TTL_MS = 60000;
6
+ export declare function isRemoteForbiddenAction(action: string): boolean;
7
+ export type MeshCallVerdict = {
8
+ readonly verdict: 'allow';
9
+ readonly errorType?: undefined;
10
+ } | {
11
+ readonly verdict: 'tolerate';
12
+ readonly errorType?: undefined;
13
+ } | {
14
+ readonly verdict: 'deny';
15
+ readonly errorType: string;
16
+ readonly message: string;
17
+ };
18
+ export interface MeshAuthenticatorDeps {
19
+ /** The hub's own node id — its local calls never pass through here. */
20
+ readonly ownNodeId: string;
21
+ /** The cluster secret as the keychain answers it now (D797). */
22
+ readonly gate: () => ClusterSecretGate;
23
+ readonly mode: () => MeshAuthMode;
24
+ readonly now?: () => number;
25
+ /** A node completed the challenge–response. */
26
+ readonly onAuthenticated?: (nodeId: string) => void;
27
+ /** First time a node is tolerated without proof on this connection. */
28
+ readonly onTolerated?: (nodeId: string, action: string) => void;
29
+ }
30
+ interface RegistrationLike {
31
+ readonly nodeId: string;
32
+ readonly clusterSecretHash?: string;
33
+ }
34
+ export declare class MeshAuthenticator {
35
+ private readonly deps;
36
+ private readonly challenges;
37
+ private readonly nodes;
38
+ /** Completed the challenge–response at least once since the hub started. */
39
+ private readonly everAuthenticated;
40
+ /** Let in WITHOUT the challenge–response at least once since the hub started. */
41
+ private readonly everTolerated;
42
+ private readonly now;
43
+ constructor(deps: MeshAuthenticatorDeps);
44
+ issueChallenge(sender: string): MeshJoinChallenge;
45
+ authenticate(sender: string, params: MeshJoinAuthenticateParams): MeshJoinAuthenticateResult;
46
+ /** The node's connection dropped: it authenticates again when it returns. */
47
+ forget(nodeId: string): void;
48
+ admitCall(sender: string, action: string): MeshCallVerdict;
49
+ /** Same rule as a call, for an inbound event. */
50
+ admitEvent(sender: string, eventName: string): MeshCallVerdict;
51
+ private admitSender;
52
+ /** Throws when `sender` may not register `params`; returns when it may. */
53
+ admitRegistration(sender: string, params: RegistrationLike): void;
54
+ private noteTolerated;
55
+ stateOf(nodeId: string): MeshNodeAuthState;
56
+ /** Node ids that completed the challenge–response on their current connection. */
57
+ authenticatedNodeIds(): readonly string[];
58
+ /** Node ids that ever completed the challenge–response since the hub started. */
59
+ everAuthenticatedNodeIds(): ReadonlySet<string>;
60
+ /**
61
+ * Node ids let in without the challenge–response since the hub started.
62
+ * Bounded: past {@link MAX_TRACKED_NODES} a flood of fake ids stops adding,
63
+ * and the ones already here keep the transition open (the operator can still
64
+ * switch to `enforced` by hand).
65
+ */
66
+ everToleratedNodeIds(): readonly string[];
67
+ snapshot(): MeshAuthStatus;
68
+ private record;
69
+ private secretHashOrThrow;
70
+ }
71
+ export {};
@@ -0,0 +1,26 @@
1
+ import { ClusterSecretGate } from './cluster-secret.js';
2
+ import { MeshAuthMode } from './mesh-auth-mode.js';
3
+ /** Boot grace before an empty or partial roster can end the transition. */
4
+ export declare const MESH_AUTO_ENFORCE_GRACE_MS: number;
5
+ export interface MeshAutoEnforceInput {
6
+ readonly mode: MeshAuthMode;
7
+ readonly gate: ClusterSecretGate['kind'];
8
+ readonly uptimeMs: number;
9
+ readonly graceMs?: number;
10
+ /** Agent node ids from the cluster-node history; `null` = the store did not answer. */
11
+ readonly knownAgents: readonly string[] | null;
12
+ readonly connected: readonly string[];
13
+ readonly toleratedEver: readonly string[];
14
+ readonly authenticatedEver: ReadonlySet<string>;
15
+ /** The hub's own id and its local children (`hub/<runner>`) are not agents. */
16
+ readonly ownNodeId: string;
17
+ }
18
+ export type MeshAutoEnforceDecision = {
19
+ readonly enforce: true;
20
+ readonly reason: string;
21
+ } | {
22
+ readonly enforce: false;
23
+ readonly waitingFor: readonly string[];
24
+ readonly why: string;
25
+ };
26
+ export declare function decideMeshAutoEnforce(input: MeshAutoEnforceInput): MeshAutoEnforceDecision;
@@ -0,0 +1,51 @@
1
+ import { Middleware } from 'moleculer';
2
+ export type MeshJoinState = 'pending' | 'authenticated' | 'no-secret' | 'unsupported' | 'unavailable' | 'secret-mismatch' | 'hub-unverified';
3
+ export type MeshJoinCall = (action: string, params: unknown, opts?: {
4
+ nodeID?: string;
5
+ timeout?: number;
6
+ }) => Promise<unknown>;
7
+ export interface MeshJoinClientOptions {
8
+ readonly nodeId: string;
9
+ /** The agent's cluster secret, read at each join (the operator may enter it at runtime). */
10
+ readonly secret: () => string | null;
11
+ readonly call: MeshJoinCall;
12
+ readonly hubNodeId?: string;
13
+ readonly maxAttempts?: number;
14
+ readonly retryDelayMs?: number;
15
+ readonly callTimeoutMs?: number;
16
+ /** How long a call waits for a pending join before it fails (default 30 s). */
17
+ readonly pendingWaitMs?: number;
18
+ readonly log?: (message: string) => void;
19
+ /** Told about every settled state. */
20
+ readonly onSettled?: (state: MeshJoinState) => void;
21
+ }
22
+ export declare class MeshJoinClient {
23
+ private readonly opts;
24
+ private current;
25
+ private settledWaiters;
26
+ private inFlight;
27
+ private readonly hubNodeId;
28
+ constructor(opts: MeshJoinClientOptions);
29
+ get state(): MeshJoinState;
30
+ /** Did this agent prove itself on the current connection? */
31
+ get authenticated(): boolean;
32
+ /**
33
+ * Run the join. Concurrent callers share one attempt. Resolves with the
34
+ * settled state; never rejects.
35
+ */
36
+ join(): Promise<MeshJoinState>;
37
+ /** The hub connection dropped: the next connection authenticates again. */
38
+ reset(): void;
39
+ /** Resolves when a call to the hub may go out; rejects when it must not. */
40
+ whenCallable(): Promise<void>;
41
+ /**
42
+ * Moleculer middleware for the AGENT broker: every call to the hub node waits
43
+ * for the join; a hub answer "not authenticated" (the hub restarted and lost
44
+ * us) triggers a new join.
45
+ */
46
+ middleware(onUnauthenticated?: () => void): Middleware;
47
+ private secretPresent;
48
+ private settle;
49
+ private runJoin;
50
+ private attempt;
51
+ }
@@ -0,0 +1,39 @@
1
+ /** Protocol version carried by the challenge; the agent refuses one it does not speak. */
2
+ export declare const MESH_JOIN_PROTOCOL = 1;
3
+ /** The hub's action that hands out a single-use nonce. */
4
+ export declare const MESH_JOIN_CHALLENGE_ACTION = "$hub.joinChallenge";
5
+ /** The hub's action that verifies a node's proof and answers with its own. */
6
+ export declare const MESH_JOIN_AUTHENTICATE_ACTION = "$hub.authenticateNode";
7
+ /** Moleculer error `type`: the sender has not authenticated and the hub enforces it. */
8
+ export declare const MESH_NODE_UNAUTHENTICATED_TYPE = "MESH_NODE_UNAUTHENTICATED";
9
+ /** Moleculer error `type`: the action is never callable from another node. */
10
+ export declare const MESH_ACTION_FORBIDDEN_TYPE = "MESH_ACTION_FORBIDDEN";
11
+ /** Moleculer error `type`: the challenge is unknown, used or expired — ask for a new one. */
12
+ export declare const MESH_JOIN_CHALLENGE_INVALID_TYPE = "MESH_JOIN_CHALLENGE_INVALID";
13
+ /** Answer of `$hub.joinChallenge`. */
14
+ export interface MeshJoinChallenge {
15
+ readonly protocol: number;
16
+ readonly nonce: string;
17
+ }
18
+ /** Params of `$hub.authenticateNode`. */
19
+ export interface MeshJoinAuthenticateParams {
20
+ readonly nodeId: string;
21
+ readonly nonce: string;
22
+ readonly clientNonce: string;
23
+ readonly proof: string;
24
+ }
25
+ /** Answer of `$hub.authenticateNode`. */
26
+ export interface MeshJoinAuthenticateResult {
27
+ readonly ok: true;
28
+ readonly hubProof: string;
29
+ }
30
+ /** A fresh 32-byte nonce, hex. */
31
+ export declare function createMeshNonce(): string;
32
+ /** The node's answer to the hub's nonce. `secretHash` is `hashClusterSecret(secret)`. */
33
+ export declare function computeNodeJoinProof(secretHash: string, nodeId: string, nonce: string): string;
34
+ /** The hub's answer to the node's nonce — proves the hub holds the same secret. */
35
+ export declare function computeHubJoinProof(secretHash: string, nodeId: string, nonce: string, clientNonce: string): string;
36
+ /** Constant-time comparison of two hex proofs; any shape mismatch is `false`. */
37
+ export declare function proofsEqual(expected: string, presented: unknown): boolean;
38
+ /** Reads a Moleculer error's `type`, including after an RPC round-trip. */
39
+ export declare function meshErrorType(err: unknown): string | null;
@@ -0,0 +1,20 @@
1
+ /** `secret://system/global/meshCaKey` — EC P-256 PKCS#8 PEM of the hub mesh CA. */
2
+ export declare const MESH_CA_KEY_REF: string;
3
+ /** `system-settings` key holding the public CA certificate PEM. */
4
+ export declare const MESH_CA_SETTINGS_KEY = "cluster.meshCa";
5
+ /** Field inside the `cluster` section (same row as the secret). */
6
+ export declare const MESH_CA_FIELD = "meshCa";
7
+ /** Join-token / leaf lifetimes. */
8
+ export declare const MESH_JOIN_TOKEN_MAX_TTL_SEC: number;
9
+ export declare const MESH_LEAF_VALIDITY_DAYS = 30;
10
+ export declare const MESH_CA_VALIDITY_DAYS = 3650;
11
+ /** Hub clear TCP (existing) and TLS dual-listen port (Release A). */
12
+ export declare const DEFAULT_HUB_TCP_PORT = 6000;
13
+ export declare const DEFAULT_HUB_TLS_TCP_PORT = 6443;
14
+ /** Join token payload version. */
15
+ export declare const MESH_JOIN_TOKEN_VERSION: 1;
16
+ /** Subject of the mesh root. Distinct from the HTTPS local CA. */
17
+ export declare const MESH_CA_COMMON_NAME = "CamStack Mesh CA";
18
+ /** Client + server auth EKU OIDs (mutual TLS). */
19
+ export declare const SERVER_AUTH_OID = "1.3.6.1.5.5.7.3.1";
20
+ export declare const CLIENT_AUTH_OID = "1.3.6.1.5.5.7.3.2";
@@ -0,0 +1,9 @@
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_JOIN_TOKEN_MAX_TTL_SEC, MESH_JOIN_TOKEN_VERSION, MESH_LEAF_VALIDITY_DAYS, SERVER_AUTH_OID, } from './constants.js';
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
+ export { clearProcessMeshCa, getProcessMeshCaState, loadOrGenerateMeshCa, MESH_CA_RETRY_MS, MeshCaKeeper, requireProcessMeshCa, setProcessMeshCa, type MeshCaKeeperDeps, type MeshCaState, } from './mesh-ca-keeper.js';
4
+ export { clearProcessMeshCrl, MeshCrl, processMeshCrl, } from './mesh-crl.js';
5
+ export { enrollMeshNode } from './mesh-enroll.js';
6
+ export type { EnrollMeshNodeDeps, MeshEnrollRequest, MeshEnrollResult, } from './mesh-enroll.js';
7
+ export { JoinTokenJtiStore, mintMeshJoinToken, processJoinTokenJtiStore, verifyMeshJoinToken, type MeshJoinTokenClaims, type MintJoinTokenInput, } from './mesh-join-token.js';
8
+ export { getProcessMeshTlsEnabler, requestProcessMeshTlsEnable, setProcessMeshTlsEnabler, type MeshTlsEnabler, } from './mesh-tls-enabler.js';
9
+ export { TlsTcpTransporter, type MeshTlsMaterial, type TlsTcpTransporterOptions, } from './tls-tcp-transporter.js';
@@ -0,0 +1,55 @@
1
+ import { SecretsAccess } from '@camstack/types';
2
+ import { MeshCaSigner } from './mesh-ca.js';
3
+ export type MeshCaState = {
4
+ readonly state: 'ready';
5
+ readonly ca: MeshCaSigner;
6
+ } | {
7
+ readonly state: 'unavailable';
8
+ readonly reason: string;
9
+ };
10
+ export declare function setProcessMeshCa(state: MeshCaState): void;
11
+ export declare function clearProcessMeshCa(): void;
12
+ export declare function getProcessMeshCaState(): MeshCaState;
13
+ export declare function requireProcessMeshCa(): MeshCaSigner;
14
+ export declare const MESH_CA_RETRY_MS = 30000;
15
+ interface KeeperLogger {
16
+ info(message: string, meta?: {
17
+ meta?: Record<string, unknown>;
18
+ }): void;
19
+ error(message: string, meta?: {
20
+ meta?: Record<string, unknown>;
21
+ }): void;
22
+ warn?(message: string, meta?: {
23
+ meta?: Record<string, unknown>;
24
+ }): void;
25
+ }
26
+ export interface MeshCaKeeperDeps {
27
+ readonly secrets: SecretsAccess | null;
28
+ /** Read `cluster` section (may contain `meshCa` PEM). */
29
+ readonly readClusterSection: () => Promise<Record<string, unknown>>;
30
+ /** Persist the CA cert PEM under `cluster.meshCa`. */
31
+ readonly writeMeshCaCert: (certPem: string) => Promise<void>;
32
+ readonly logger: KeeperLogger;
33
+ readonly retryMs?: number;
34
+ /** Fired when the CA becomes ready (start TLS listener, etc.). */
35
+ readonly onReady?: (ca: MeshCaSigner) => void | Promise<void>;
36
+ }
37
+ export declare class MeshCaKeeper {
38
+ private readonly deps;
39
+ private retryTimer;
40
+ private unsubscribe;
41
+ private stopped;
42
+ constructor(deps: MeshCaKeeperDeps);
43
+ start(): Promise<void>;
44
+ stop(): void;
45
+ private load;
46
+ private apply;
47
+ private scheduleRetry;
48
+ }
49
+ export interface LoadOrGenerateMeshCaDeps {
50
+ readonly secrets: SecretsAccess;
51
+ readonly readClusterSection: () => Promise<Record<string, unknown>>;
52
+ readonly writeMeshCaCert: (certPem: string) => Promise<void>;
53
+ }
54
+ export declare function loadOrGenerateMeshCa(deps: LoadOrGenerateMeshCaDeps): Promise<MeshCaState>;
55
+ export {};
@@ -0,0 +1,45 @@
1
+ import { webcrypto as WebCrypto } from 'node:crypto';
2
+ import { X509Certificate as PeculiarCertificate } from '@peculiar/x509';
3
+ /** Key generation — EC P-256 (plan). WebCrypto DOM names are not in @types/node. */
4
+ export declare const MESH_KEY_ALGORITHM: WebCrypto.EcKeyGenParams;
5
+ /** Signing — ECDSA with SHA-256. */
6
+ export declare const MESH_SIGNING_ALGORITHM: WebCrypto.EcdsaParams;
7
+ export interface MeshCaSigner {
8
+ readonly certPem: string;
9
+ readonly keyPem: string;
10
+ readonly cert: PeculiarCertificate;
11
+ readonly privateKey: WebCrypto.CryptoKey;
12
+ readonly publicKey: WebCrypto.CryptoKey;
13
+ }
14
+ export interface MeshLeafMaterial {
15
+ readonly certPem: string;
16
+ readonly serialNumber: string;
17
+ readonly notAfter: Date;
18
+ readonly commonName: string;
19
+ }
20
+ /** SHA-256 fingerprint of the DER cert, colon-hex uppercase (Node style). */
21
+ export declare function caFingerprint(certPem: string): string;
22
+ /** Compact fingerprint (lowercase hex, no colons) for join-token payloads. */
23
+ export declare function caFingerprintCompact(certPem: string): string;
24
+ export declare function generateMeshCa(now?: Date): Promise<MeshCaSigner>;
25
+ export declare function loadMeshCa(certPem: string, keyPem: string): Promise<MeshCaSigner>;
26
+ /**
27
+ * Issue a leaf from a CSR. CN must be present; when `expectedNodeId` is set
28
+ * it must match. Validity: 30 days.
29
+ */
30
+ export declare function issueMeshLeafFromCsr(ca: MeshCaSigner, csrPem: string, opts?: {
31
+ readonly expectedNodeId?: string;
32
+ readonly now?: Date;
33
+ readonly validDays?: number;
34
+ }): Promise<MeshLeafMaterial>;
35
+ /** Issue a leaf for a known nodeID with a freshly generated key pair (tests / hub self). */
36
+ export declare function issueMeshLeafForNode(ca: MeshCaSigner, nodeId: string, opts?: {
37
+ readonly now?: Date;
38
+ readonly validDays?: number;
39
+ }): Promise<MeshLeafMaterial & {
40
+ readonly keyPem: string;
41
+ }>;
42
+ export declare function subjectCn(subject: string): string | null;
43
+ export declare function createMeshCsrPem(keys: WebCrypto.CryptoKeyPair, commonName: string): Promise<string>;
44
+ export declare function generateMeshKeyPair(): Promise<WebCrypto.CryptoKeyPair>;
45
+ export declare function exportMeshPrivateKeyPem(key: WebCrypto.CryptoKey): Promise<string>;
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Mesh certificate revocation list — in-memory + optional persist hook.
3
+ *
4
+ * Release A can stub persistence; the reader checks serials at handshake and
5
+ * a later "Forget node" closes open sockets (Release A+).
6
+ */
7
+ export declare class MeshCrl {
8
+ private readonly serials;
9
+ revoke(serialNumber: string): void;
10
+ isRevoked(serialNumber: string): boolean;
11
+ list(): readonly string[];
12
+ /** Restore from persisted serials (system-settings). */
13
+ replaceAll(serials: readonly string[]): void;
14
+ }
15
+ export declare function processMeshCrl(): MeshCrl;
16
+ export declare function clearProcessMeshCrl(): void;
@@ -0,0 +1,27 @@
1
+ import { MeshCaSigner } from './mesh-ca.js';
2
+ import { JoinTokenJtiStore, MeshJoinTokenClaims } from './mesh-join-token.js';
3
+ export interface MeshEnrollRequest {
4
+ readonly token: string;
5
+ readonly csr: string;
6
+ }
7
+ export interface MeshEnrollSuccess {
8
+ readonly ok: true;
9
+ readonly cert: string;
10
+ readonly caCert: string;
11
+ readonly nodeId: string;
12
+ readonly notAfter: string;
13
+ readonly serialNumber: string;
14
+ }
15
+ export interface MeshEnrollFailure {
16
+ readonly ok: false;
17
+ readonly error: string;
18
+ readonly status: number;
19
+ }
20
+ export type MeshEnrollResult = MeshEnrollSuccess | MeshEnrollFailure;
21
+ export interface EnrollMeshNodeDeps {
22
+ readonly ca: MeshCaSigner;
23
+ readonly jtiStore?: JoinTokenJtiStore;
24
+ readonly now?: Date;
25
+ }
26
+ export declare function enrollMeshNode(body: MeshEnrollRequest, deps: EnrollMeshNodeDeps): Promise<MeshEnrollResult>;
27
+ export type { MeshJoinTokenClaims };