@xdarkicex/openclaw-memory-libravdb 1.4.79 → 1.5.0

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/README.md CHANGED
@@ -187,7 +187,7 @@ All keys are optional. For the full reference, see [Configuration](./docs/config
187
187
 
188
188
  - New install: [Install](./docs/install.md), [Installation reference](./docs/installation.md)
189
189
  - Understand the design: [Problem](./docs/problem.md), [Architecture](./docs/architecture.md), [ADRs](./docs/architecture-decisions/README.md)
190
- - Configure: [Configuration](./docs/configuration.md), [Features](./docs/features.md), [Embedding profiles](./docs/embedding-profiles.md), [Models](./docs/models.md)
190
+ - Configure: [Configuration](./docs/configuration.md), [TLS configuration](./docs/TLS_configuration.md), [Features](./docs/features.md), [Embedding profiles](./docs/embedding-profiles.md), [Models](./docs/models.md)
191
191
  - Operate safely: [Security](./docs/security.md), [Uninstall](./docs/uninstall.md)
192
192
  - Advanced operations: [Performance and tuning](./docs/performance-and-tuning.md)
193
193
  - Work from source: [Development](./docs/development.md), [Contributing](./docs/contributing.md)
@@ -1,10 +1,27 @@
1
+ import * as grpc from "@grpc/grpc-js";
1
2
  export interface GrpcClientOptions {
2
3
  endpoint: string;
3
4
  secret?: string;
4
5
  timeoutMs?: number;
6
+ tlsCaPath?: string;
7
+ tlsMode?: "auto" | "tls" | "insecure";
5
8
  }
6
9
  export declare function resolveGrpcTarget(endpoint: string): string;
7
- export declare function resolveGrpcCredentialMode(endpoint: string): "insecure" | "tls";
10
+ /**
11
+ * Selects gRPC credential mode based on endpoint address class.
12
+ *
13
+ * - Unix socket endpoints → plaintext (local-only transport)
14
+ * - Loopback addresses (localhost, 127.0.0.1, ::1) → plaintext
15
+ * - All other TCP and DNS targets → TLS
16
+ *
17
+ * resolveGrpcCredentials uses this classification to return the
18
+ * appropriate grpc.ChannelCredentials. Pass tlsCaPath to load a
19
+ * custom CA certificate PEM file for self-signed or private CA
20
+ * deployments. Omit tlsCaPath for publicly trusted certificates
21
+ * (Let's Encrypt, cert-manager) — the system CA pool is used.
22
+ */
23
+ export declare function resolveGrpcCredentialMode(endpoint: string, tlsMode?: "auto" | "tls" | "insecure"): "insecure" | "tls";
24
+ export declare function resolveGrpcCredentials(endpoint: string, tlsCaPath?: string, tlsMode?: "auto" | "tls" | "insecure"): grpc.ChannelCredentials;
8
25
  export declare class GrpcKernelClient {
9
26
  private client;
10
27
  private readonly secret;
@@ -1,6 +1,7 @@
1
1
  import { createHmac } from "node:crypto";
2
2
  import path from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
+ import * as fs from "fs";
4
5
  import * as grpc from "@grpc/grpc-js";
5
6
  import * as protoLoader from "@grpc/proto-loader";
6
7
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
@@ -10,18 +11,47 @@ const PROTO_PATH = path.resolve(__dirname, "./proto/intelligence_kernel/v1/kerne
10
11
  export function resolveGrpcTarget(endpoint) {
11
12
  return endpoint.startsWith("tcp:") ? endpoint.substring(4) : endpoint;
12
13
  }
13
- export function resolveGrpcCredentialMode(endpoint) {
14
+ /**
15
+ * Selects gRPC credential mode based on endpoint address class.
16
+ *
17
+ * - Unix socket endpoints → plaintext (local-only transport)
18
+ * - Loopback addresses (localhost, 127.0.0.1, ::1) → plaintext
19
+ * - All other TCP and DNS targets → TLS
20
+ *
21
+ * resolveGrpcCredentials uses this classification to return the
22
+ * appropriate grpc.ChannelCredentials. Pass tlsCaPath to load a
23
+ * custom CA certificate PEM file for self-signed or private CA
24
+ * deployments. Omit tlsCaPath for publicly trusted certificates
25
+ * (Let's Encrypt, cert-manager) — the system CA pool is used.
26
+ */
27
+ export function resolveGrpcCredentialMode(endpoint, tlsMode) {
28
+ if (tlsMode === "tls")
29
+ return "tls";
30
+ if (tlsMode === "insecure")
31
+ return "insecure";
32
+ // "auto" or undefined — address-based heuristic
14
33
  const target = resolveGrpcTarget(endpoint).trim();
15
- if (target.startsWith("unix:")) {
34
+ if (target.startsWith("unix:"))
16
35
  return "insecure";
17
- }
18
36
  const host = extractGrpcHost(target);
19
37
  return isLoopbackHost(host) ? "insecure" : "tls";
20
38
  }
21
- function resolveGrpcCredentials(endpoint) {
22
- return resolveGrpcCredentialMode(endpoint) === "insecure"
23
- ? grpc.credentials.createInsecure()
24
- : grpc.credentials.createSsl();
39
+ export function resolveGrpcCredentials(endpoint, tlsCaPath, tlsMode) {
40
+ if (resolveGrpcCredentialMode(endpoint, tlsMode) === "insecure") {
41
+ return grpc.credentials.createInsecure();
42
+ }
43
+ if (tlsCaPath) {
44
+ let rootCerts;
45
+ try {
46
+ rootCerts = fs.readFileSync(tlsCaPath);
47
+ }
48
+ catch (err) {
49
+ const msg = err instanceof Error ? err.message : String(err);
50
+ throw new Error(`LibraVDB: failed to load TLS CA certificate from "${tlsCaPath}": ${msg}`);
51
+ }
52
+ return grpc.credentials.createSsl(rootCerts, null, null);
53
+ }
54
+ return grpc.credentials.createSsl();
25
55
  }
26
56
  function extractGrpcHost(target) {
27
57
  const withoutDnsPrefix = target.startsWith("dns:///") ? target.slice("dns:///".length) : target;
@@ -54,7 +84,7 @@ export class GrpcKernelClient {
54
84
  const protoDescriptor = grpc.loadPackageDefinition(packageDefinition);
55
85
  const kernelService = protoDescriptor.intelligence_kernel.v1.IntelligenceKernel;
56
86
  const target = resolveGrpcTarget(options.endpoint);
57
- this.client = new kernelService(target, resolveGrpcCredentials(options.endpoint));
87
+ this.client = new kernelService(target, resolveGrpcCredentials(options.endpoint, options.tlsCaPath, options.tlsMode));
58
88
  }
59
89
  getMetadata(signed = true) {
60
90
  const md = new grpc.Metadata();
package/dist/index.js CHANGED
@@ -8810,14 +8810,14 @@ var require_tls_helpers = __commonJS({
8810
8810
  Object.defineProperty(exports2, "__esModule", { value: true });
8811
8811
  exports2.CIPHER_SUITES = void 0;
8812
8812
  exports2.getDefaultRootsData = getDefaultRootsData;
8813
- var fs4 = __require("fs");
8813
+ var fs5 = __require("fs");
8814
8814
  exports2.CIPHER_SUITES = process.env.GRPC_SSL_CIPHER_SUITES;
8815
8815
  var DEFAULT_ROOTS_FILE_PATH = process.env.GRPC_DEFAULT_SSL_ROOTS_FILE_PATH;
8816
8816
  var defaultRootsData = null;
8817
8817
  function getDefaultRootsData() {
8818
8818
  if (DEFAULT_ROOTS_FILE_PATH) {
8819
8819
  if (defaultRootsData === null) {
8820
- defaultRootsData = fs4.readFileSync(DEFAULT_ROOTS_FILE_PATH);
8820
+ defaultRootsData = fs5.readFileSync(DEFAULT_ROOTS_FILE_PATH);
8821
8821
  }
8822
8822
  return defaultRootsData;
8823
8823
  }
@@ -14324,7 +14324,7 @@ var require_fetch = __commonJS({
14324
14324
  module2.exports = fetch;
14325
14325
  var asPromise = require_aspromise();
14326
14326
  var inquire2 = require_inquire();
14327
- var fs4 = inquire2("fs");
14327
+ var fs5 = inquire2("fs");
14328
14328
  function fetch(filename, options, callback) {
14329
14329
  if (typeof options === "function") {
14330
14330
  callback = options;
@@ -14333,8 +14333,8 @@ var require_fetch = __commonJS({
14333
14333
  options = {};
14334
14334
  if (!callback)
14335
14335
  return asPromise(fetch, this, filename, options);
14336
- if (!options.xhr && fs4 && fs4.readFile)
14337
- return fs4.readFile(filename, function fetchReadFileCallback(err, contents) {
14336
+ if (!options.xhr && fs5 && fs5.readFile)
14337
+ return fs5.readFile(filename, function fetchReadFileCallback(err, contents) {
14338
14338
  return err && typeof XMLHttpRequest !== "undefined" ? fetch.xhr(filename, options, callback) : err ? callback(err) : callback(null, options.binary ? contents : contents.toString("utf8"));
14339
14339
  });
14340
14340
  return fetch.xhr(filename, options, callback);
@@ -20608,7 +20608,7 @@ var require_util2 = __commonJS({
20608
20608
  "use strict";
20609
20609
  Object.defineProperty(exports2, "__esModule", { value: true });
20610
20610
  exports2.addCommonProtos = exports2.loadProtosWithOptionsSync = exports2.loadProtosWithOptions = void 0;
20611
- var fs4 = __require("fs");
20611
+ var fs5 = __require("fs");
20612
20612
  var path5 = __require("path");
20613
20613
  var Protobuf = require_protobufjs();
20614
20614
  function addIncludePathResolver(root, includePaths) {
@@ -20620,7 +20620,7 @@ var require_util2 = __commonJS({
20620
20620
  for (const directory of includePaths) {
20621
20621
  const fullPath = path5.join(directory, target);
20622
20622
  try {
20623
- fs4.accessSync(fullPath, fs4.constants.R_OK);
20623
+ fs5.accessSync(fullPath, fs5.constants.R_OK);
20624
20624
  return fullPath;
20625
20625
  } catch (err) {
20626
20626
  continue;
@@ -30442,7 +30442,7 @@ var require_certificate_provider = __commonJS({
30442
30442
  "use strict";
30443
30443
  Object.defineProperty(exports2, "__esModule", { value: true });
30444
30444
  exports2.FileWatcherCertificateProvider = void 0;
30445
- var fs4 = __require("fs");
30445
+ var fs5 = __require("fs");
30446
30446
  var logging = require_logging();
30447
30447
  var constants_1 = require_constants();
30448
30448
  var util_1 = __require("util");
@@ -30450,7 +30450,7 @@ var require_certificate_provider = __commonJS({
30450
30450
  function trace(text) {
30451
30451
  logging.trace(constants_1.LogVerbosity.DEBUG, TRACER_NAME, text);
30452
30452
  }
30453
- var readFilePromise = (0, util_1.promisify)(fs4.readFile);
30453
+ var readFilePromise = (0, util_1.promisify)(fs5.readFile);
30454
30454
  var FileWatcherCertificateProvider = class {
30455
30455
  constructor(config) {
30456
30456
  this.config = config;
@@ -39661,21 +39661,37 @@ var protoLoader = __toESM(require_src2(), 1);
39661
39661
  import { createHmac } from "node:crypto";
39662
39662
  import path3 from "node:path";
39663
39663
  import { fileURLToPath } from "node:url";
39664
+ import * as fs3 from "fs";
39664
39665
  var __dirname2 = path3.dirname(fileURLToPath(import.meta.url));
39665
39666
  var PROTO_PATH = path3.resolve(__dirname2, "./proto/intelligence_kernel/v1/kernel.proto");
39666
39667
  function resolveGrpcTarget(endpoint) {
39667
39668
  return endpoint.startsWith("tcp:") ? endpoint.substring(4) : endpoint;
39668
39669
  }
39669
- function resolveGrpcCredentialMode(endpoint) {
39670
+ function resolveGrpcCredentialMode(endpoint, tlsMode) {
39671
+ if (tlsMode === "tls") return "tls";
39672
+ if (tlsMode === "insecure") return "insecure";
39670
39673
  const target = resolveGrpcTarget(endpoint).trim();
39671
- if (target.startsWith("unix:")) {
39672
- return "insecure";
39673
- }
39674
+ if (target.startsWith("unix:")) return "insecure";
39674
39675
  const host = extractGrpcHost(target);
39675
39676
  return isLoopbackHost(host) ? "insecure" : "tls";
39676
39677
  }
39677
- function resolveGrpcCredentials(endpoint) {
39678
- return resolveGrpcCredentialMode(endpoint) === "insecure" ? grpc.credentials.createInsecure() : grpc.credentials.createSsl();
39678
+ function resolveGrpcCredentials(endpoint, tlsCaPath, tlsMode) {
39679
+ if (resolveGrpcCredentialMode(endpoint, tlsMode) === "insecure") {
39680
+ return grpc.credentials.createInsecure();
39681
+ }
39682
+ if (tlsCaPath) {
39683
+ let rootCerts;
39684
+ try {
39685
+ rootCerts = fs3.readFileSync(tlsCaPath);
39686
+ } catch (err) {
39687
+ const msg = err instanceof Error ? err.message : String(err);
39688
+ throw new Error(
39689
+ `LibraVDB: failed to load TLS CA certificate from "${tlsCaPath}": ${msg}`
39690
+ );
39691
+ }
39692
+ return grpc.credentials.createSsl(rootCerts, null, null);
39693
+ }
39694
+ return grpc.credentials.createSsl();
39679
39695
  }
39680
39696
  function extractGrpcHost(target) {
39681
39697
  const withoutDnsPrefix = target.startsWith("dns:///") ? target.slice("dns:///".length) : target;
@@ -39708,7 +39724,7 @@ var GrpcKernelClient = class {
39708
39724
  const protoDescriptor = grpc.loadPackageDefinition(packageDefinition);
39709
39725
  const kernelService = protoDescriptor.intelligence_kernel.v1.IntelligenceKernel;
39710
39726
  const target = resolveGrpcTarget(options.endpoint);
39711
- this.client = new kernelService(target, resolveGrpcCredentials(options.endpoint));
39727
+ this.client = new kernelService(target, resolveGrpcCredentials(options.endpoint, options.tlsCaPath, options.tlsMode));
39712
39728
  }
39713
39729
  getMetadata(signed = true) {
39714
39730
  const md = new grpc.Metadata();
@@ -39782,7 +39798,7 @@ var GrpcKernelClient = class {
39782
39798
  };
39783
39799
 
39784
39800
  // src/sidecar.ts
39785
- import fs3 from "node:fs";
39801
+ import fs4 from "node:fs";
39786
39802
  import net from "node:net";
39787
39803
  import os3 from "node:os";
39788
39804
  import path4 from "node:path";
@@ -40077,7 +40093,7 @@ function resolveConfiguredEndpoint(cfg) {
40077
40093
  function daemonProvisioningHint() {
40078
40094
  return "If you installed the npm package, install and start libravdbd separately; the package does not provision the daemon binary, ONNX Runtime, or model assets.";
40079
40095
  }
40080
- function defaultEndpoint(platform = process.platform, homeDir = os3.homedir(), pathExists = fs3.existsSync) {
40096
+ function defaultEndpoint(platform = process.platform, homeDir = os3.homedir(), pathExists = fs4.existsSync) {
40081
40097
  const envEndpoint = normalizeConfiguredEndpoint(process.env.LIBRAVDB_RPC_ENDPOINT);
40082
40098
  if (envEndpoint) {
40083
40099
  return envEndpoint;
@@ -40175,9 +40191,11 @@ function sleep2(delayMs) {
40175
40191
  }
40176
40192
 
40177
40193
  // src/plugin-runtime.ts
40178
- import { readFileSync as readFileSync2 } from "node:fs";
40194
+ import { readFileSync as readFileSync3 } from "node:fs";
40179
40195
  var DEFAULT_RPC_TIMEOUT_MS = 3e4;
40180
40196
  var STARTUP_HEALTH_TIMEOUT_MS = 2e3;
40197
+ var VALID_TLS_MODES = ["auto", "tls", "insecure"];
40198
+ var isTlsModeValid = (m) => VALID_TLS_MODES.includes(m);
40181
40199
  function resolveStartupHealthTimeoutMs(cfg) {
40182
40200
  return Math.max(STARTUP_HEALTH_TIMEOUT_MS, cfg.rpcTimeoutMs ?? DEFAULT_RPC_TIMEOUT_MS);
40183
40201
  }
@@ -40210,10 +40228,22 @@ function createPluginRuntime(cfg, logger = console) {
40210
40228
  if (cfg.grpcEndpoint) {
40211
40229
  try {
40212
40230
  const secret = loadSecretFromEnv();
40231
+ if (cfg.grpcEndpointTlsMode !== void 0 && !isTlsModeValid(cfg.grpcEndpointTlsMode)) {
40232
+ throw new Error(
40233
+ `LibraVDB: invalid grpcEndpointTlsMode "${cfg.grpcEndpointTlsMode}" \u2014 must be "auto", "tls", or "insecure"`
40234
+ );
40235
+ }
40236
+ if (cfg.grpcEndpointTlsMode === "insecure" && cfg.grpcEndpointTlsCa) {
40237
+ logger.warn?.(
40238
+ `LibraVDB: grpcEndpointTlsCa is set but grpcEndpointTlsMode is "insecure" \u2014 the CA file will not be used`
40239
+ );
40240
+ }
40213
40241
  kernel = new GrpcKernelClient({
40214
40242
  endpoint: cfg.grpcEndpoint,
40215
40243
  secret,
40216
- timeoutMs: cfg.rpcTimeoutMs ?? DEFAULT_RPC_TIMEOUT_MS
40244
+ timeoutMs: cfg.rpcTimeoutMs ?? DEFAULT_RPC_TIMEOUT_MS,
40245
+ tlsCaPath: cfg.grpcEndpointTlsCa,
40246
+ tlsMode: cfg.grpcEndpointTlsMode
40217
40247
  });
40218
40248
  } catch (error) {
40219
40249
  logger.warn?.(`LibraVDB: failed to initialize gRPC kernel client: ${formatError(error)}`);
@@ -40282,7 +40312,7 @@ function loadSecretFromEnv() {
40282
40312
  const path5 = process.env.LIBRAVDB_AUTH_SECRET_FILE;
40283
40313
  if (path5) {
40284
40314
  try {
40285
- return readFileSync2(path5, "utf8").trim();
40315
+ return readFileSync3(path5, "utf8").trim();
40286
40316
  } catch {
40287
40317
  return void 0;
40288
40318
  }
@@ -4,6 +4,8 @@ import type { LoggerLike, PluginConfig } from "./types.js";
4
4
  export type RpcGetter = () => Promise<RpcClient>;
5
5
  export declare const DEFAULT_RPC_TIMEOUT_MS = 30000;
6
6
  export declare const STARTUP_HEALTH_TIMEOUT_MS = 2000;
7
+ export declare const VALID_TLS_MODES: readonly ["auto", "tls", "insecure"];
8
+ export type ValidTlsMode = typeof VALID_TLS_MODES[number];
7
9
  export declare function resolveStartupHealthTimeoutMs(cfg: PluginConfig): number;
8
10
  export interface LifecycleHint {
9
11
  hook: "before_reset" | "session_end";
@@ -5,6 +5,8 @@ import { formatError } from "./format-error.js";
5
5
  import { readFileSync } from "node:fs";
6
6
  export const DEFAULT_RPC_TIMEOUT_MS = 30000;
7
7
  export const STARTUP_HEALTH_TIMEOUT_MS = 2000;
8
+ export const VALID_TLS_MODES = ["auto", "tls", "insecure"];
9
+ const isTlsModeValid = (m) => VALID_TLS_MODES.includes(m);
8
10
  export function resolveStartupHealthTimeoutMs(cfg) {
9
11
  return Math.max(STARTUP_HEALTH_TIMEOUT_MS, cfg.rpcTimeoutMs ?? DEFAULT_RPC_TIMEOUT_MS);
10
12
  }
@@ -39,10 +41,23 @@ export function createPluginRuntime(cfg, logger = console) {
39
41
  if (cfg.grpcEndpoint) {
40
42
  try {
41
43
  const secret = loadSecretFromEnv();
44
+ if (cfg.grpcEndpointTlsMode !== undefined &&
45
+ !isTlsModeValid(cfg.grpcEndpointTlsMode)) {
46
+ throw new Error(`LibraVDB: invalid grpcEndpointTlsMode "${cfg.grpcEndpointTlsMode}" — ` +
47
+ `must be "auto", "tls", or "insecure"`);
48
+ }
49
+ if (cfg.grpcEndpointTlsMode === "insecure" &&
50
+ cfg.grpcEndpointTlsCa) {
51
+ // logger is provided by the host and may not have all methods
52
+ logger.warn?.(`LibraVDB: grpcEndpointTlsCa is set but grpcEndpointTlsMode ` +
53
+ `is "insecure" — the CA file will not be used`);
54
+ }
42
55
  kernel = new GrpcKernelClient({
43
56
  endpoint: cfg.grpcEndpoint,
44
57
  secret,
45
58
  timeoutMs: cfg.rpcTimeoutMs ?? DEFAULT_RPC_TIMEOUT_MS,
59
+ tlsCaPath: cfg.grpcEndpointTlsCa,
60
+ tlsMode: cfg.grpcEndpointTlsMode,
46
61
  });
47
62
  }
48
63
  catch (error) {
package/dist/types.d.ts CHANGED
@@ -90,6 +90,12 @@ export interface PluginConfig {
90
90
  maxRetries?: number;
91
91
  logLevel?: "debug" | "info" | "warn" | "error";
92
92
  grpcEndpoint?: string;
93
+ grpcEndpointTlsCa?: string;
94
+ /** Controls gRPC credential mode.
95
+ * "auto" (default) — loopback and unix → plaintext, remote → TLS.
96
+ * "tls" — always use TLS regardless of address.
97
+ * "insecure" — always use plaintext (service mesh, tunnel). */
98
+ grpcEndpointTlsMode?: "auto" | "tls" | "insecure";
93
99
  }
94
100
  export interface SearchResult {
95
101
  id: string;
@@ -0,0 +1,112 @@
1
+ # TLS Configuration
2
+
3
+ The plugin selects the right credentials automatically based on which address it connects to. Unix sockets and loopback addresses (localhost, 127.0.0.1, ::1) always use plaintext. All other addresses use TLS. In most deployments no TLS configuration is needed at all. The only time manual configuration is required is when the daemon serves TLS on a loopback address, when the daemon uses a self-signed or private-CA certificate, or when infrastructure such as a service mesh handles TLS outside the plugin.
4
+
5
+ ## Default behavior
6
+
7
+ The plugin applies the following rules automatically:
8
+
9
+ | Endpoint type | Credential mode |
10
+ |---|---|
11
+ | Unix socket (`unix:/path/to/socket`) | Plaintext |
12
+ | Loopback (`tcp:127.0.0.1:port`, `tcp:localhost:port`, `[::1]:port`) | Plaintext |
13
+ | Any other TCP or DNS address | TLS |
14
+
15
+ Because these rules are automatic, most users do not set any TLS-related fields. Plaintext is used where it is safe (local transport) and TLS is used where it is needed (network transport).
16
+
17
+ ## Configuration fields
18
+
19
+ | Field | Type | Default | When to use |
20
+ |---|---|---|---|
21
+ | `grpcEndpoint` | string | — | The daemon address. Set to a unix socket path, a loopback address, or a remote host. |
22
+ | `grpcEndpointTlsCa` | string | — | Path to a CA certificate PEM file. Required only when the daemon certificate is self-signed or signed by a private CA not in the system certificate store. |
23
+ | `grpcEndpointTlsMode` | `"auto"` \| `"tls"` \| `"insecure"` | `"auto"` | Override the automatic selection. `"auto"` applies the default rules above. `"tls"` forces TLS regardless of address. `"insecure"` forces plaintext regardless of address. |
24
+
25
+ `grpcEndpointTlsMode` values explained:
26
+
27
+ - **`"auto"`** (default) — apply the automatic rules. Unix sockets and loopback use plaintext; all other addresses use TLS.
28
+ - **`"tls"`** — always use TLS, even for loopback addresses. Use this when the daemon has TLS enabled on a loopback address.
29
+ - **`"insecure"`** — always use plaintext, even for remote addresses. Use this only when a service mesh or TLS-terminating tunnel handles encryption externally.
30
+
31
+ ## Deployment scenarios
32
+
33
+ ### Local daemon (default)
34
+
35
+ The daemon runs on the same machine, listening on a unix socket or a loopback address.
36
+
37
+ ```json
38
+ {
39
+ "grpcEndpoint": "unix:/home/user/.libravdbd/run/libravdb.sock"
40
+ }
41
+ ```
42
+
43
+ or:
44
+
45
+ ```json
46
+ {
47
+ "grpcEndpoint": "tcp:127.0.0.1:9090"
48
+ }
49
+ ```
50
+
51
+ The plugin automatically uses plaintext. No TLS fields are needed.
52
+
53
+ ### Remote daemon with a trusted certificate
54
+
55
+ The daemon runs on a remote host and presents a certificate issued by a public CA such as Let's Encrypt or cert-manager.
56
+
57
+ ```json
58
+ {
59
+ "grpcEndpoint": "tcp:libravdb.k8s.internal:9090"
60
+ }
61
+ ```
62
+
63
+ TLS is automatic. The plugin uses the system certificate store to verify the daemon's certificate, so no additional configuration is needed.
64
+
65
+ ### Remote daemon with a self-signed or private CA certificate
66
+
67
+ The daemon runs on a remote host and uses a self-signed certificate or a certificate signed by a private/internal CA not in the system certificate store.
68
+
69
+ ```json
70
+ {
71
+ "grpcEndpoint": "tcp:libravdb.internal:9090",
72
+ "grpcEndpointTlsCa": "/etc/certs/company-ca.pem"
73
+ }
74
+ ```
75
+
76
+ The CA certificate must be the certificate of the CA that signed the daemon's server certificate — not the server certificate itself. The plugin uses this CA to verify the daemon's certificate during the TLS handshake. Without it, the plugin will reject the daemon's certificate as untrusted.
77
+
78
+ ### TLS on a loopback address
79
+
80
+ The daemon has TLS enabled on a loopback address. This is uncommon. The automatic rules would select plaintext for a loopback address, so an explicit override is required.
81
+
82
+ ```json
83
+ {
84
+ "grpcEndpoint": "tcp:127.0.0.1:9090",
85
+ "grpcEndpointTlsMode": "tls"
86
+ }
87
+ ```
88
+
89
+ Set `grpcEndpointTlsMode` to `"tls"` to force the plugin to use TLS even on the loopback address. The plugin will use the system certificate store for verification. If the daemon uses a self-signed certificate, add `grpcEndpointTlsCa` as well.
90
+
91
+ ## Service mesh and tunnels
92
+
93
+ When the daemon runs behind Istio, Envoy, or any other infrastructure that terminates TLS at the mesh or tunnel layer, the plugin should not attempt its own TLS. Set `grpcEndpointTlsMode` to `"insecure"` so the plugin uses plaintext and lets the mesh handle encryption:
94
+
95
+ ```json
96
+ {
97
+ "grpcEndpoint": "tcp:libravdb.mesh.svc:9090",
98
+ "grpcEndpointTlsMode": "insecure"
99
+ }
100
+ ```
101
+
102
+ This applies even for remote addresses. The mesh terminates TLS at the boundary, and the plugin communicates with the mesh over plaintext on the inside.
103
+
104
+ ## Error reference
105
+
106
+ | Error | Likely cause | Fix |
107
+ |---|---|---|
108
+ | `UNAVAILABLE / connection closed / TLS handshake failed` when connecting to a loopback address | The daemon has TLS enabled on a loopback address but the plugin is using plaintext (the default for loopback). | Add `"grpcEndpointTlsMode": "tls"` to the plugin config. |
109
+ | `x509: certificate signed by unknown authority` | The daemon uses a self-signed certificate or a certificate from a private CA not trusted by the system. | Set `grpcEndpointTlsCa` to the path of the CA certificate PEM file that signed the daemon's server certificate. |
110
+ | `failed to load TLS CA certificate from "...": ENOENT: no such file or directory` | The file path given in `grpcEndpointTlsCa` does not exist on the machine. | Verify the file path is correct and the CA certificate file exists. |
111
+ | `LibraVDB: invalid grpcEndpointTlsMode "..."` | The value set in `grpcEndpointTlsMode` is not one of the accepted values. | Change the value to `"auto"`, `"tls"`, or `"insecure"`. |
112
+ | `LIBRAVDB: grpcEndpointTlsCa is set but grpcEndpointTlsMode is "insecure"` (warning) | Both `grpcEndpointTlsCa` and `grpcEndpointTlsMode: "insecure"` are set. The CA file will not be used. | Remove `grpcEndpointTlsCa` if plaintext is intended, or change `grpcEndpointTlsMode` to `"auto"` or `"tls"` to use the CA file. |
@@ -12,10 +12,60 @@ CPU when a provider is unavailable.
12
12
  | Key | Type | Default | Notes |
13
13
  |---|---|---|---|
14
14
  | `sidecarPath` | string | `auto` | `"auto"` probes standard socket paths; set `unix:/path` or `tcp:host:port` to override |
15
- | `grpcEndpoint` | string | — | Optional gRPC kernel endpoint for hosts using the gRPC kernel transport |
15
+ | `grpcEndpoint` | string | — | gRPC kernel endpoint. See `grpcEndpointTlsMode` for credential control. |
16
+ | `grpcEndpointTlsCa` | string | — | Path to CA certificate PEM file. Only needed for self-signed or private CA certs. Omit when using Let's Encrypt or cert-manager. |
17
+ | `grpcEndpointTlsMode` | string | `"auto"` | gRPC credential mode. `"auto"`: loopback/unix → plaintext, remote → TLS. `"tls"`: always TLS. `"insecure"`: always plaintext. |
16
18
  | `rpcTimeoutMs` | number | `30000` | Per-call timeout for service RPC (ms) |
17
19
  | `dbPath` | string | auto-named | Explicit DB path; when set bypasses model-specific naming |
18
20
 
21
+ ### gRPC TLS behavior
22
+
23
+ The plugin selects credentials automatically based on the endpoint:
24
+
25
+ | Endpoint format | Credential mode |
26
+ |---|---|
27
+ | `unix:/path/to/sock` | Plaintext (local) |
28
+ | `tcp:127.0.0.1:port` / `tcp:localhost:port` / `[::1]:port` | Plaintext (loopback) |
29
+ | Any other TCP or DNS target | TLS |
30
+
31
+ Use `grpcEndpointTlsMode` to override the default behavior:
32
+
33
+ | Value | When to use |
34
+ |---|---|
35
+ | `"auto"` (default) | Standard operation — plugin heuristic matches daemon TLS setting automatically. |
36
+ | `"tls"` | Daemon has TLS enabled on loopback or unix socket (rare; use when the daemon's `LIBRAVDB_GRPC_TLS_*` env vars are set on a local address). |
37
+ | `"insecure"` | Service mesh or TLS-terminating tunnel handles encryption externally; both sides are plaintext. |
38
+
39
+ **Default (local daemon):** No TLS configuration needed.
40
+ Unix socket and loopback endpoints are always plaintext regardless
41
+ of any TLS settings.
42
+
43
+ **K8 / remote daemon with CA-issued cert:**
44
+ No extra configuration needed. The plugin uses the system CA pool,
45
+ which trusts certs issued by Let's Encrypt, cert-manager, and
46
+ other public CAs automatically.
47
+
48
+ **Remote daemon with self-signed or private CA cert:**
49
+ Set `grpcEndpointTlsCa` to the path of the CA certificate PEM file:
50
+ ```json
51
+ {
52
+ "grpcEndpoint": "tcp:yourdaemon.internal:50051",
53
+ "grpcEndpointTlsCa": "/etc/certs/ca.pem"
54
+ }
55
+ ```
56
+ The daemon must be configured with matching TLS cert and key via
57
+ `LIBRAVDB_GRPC_TLS_CERT` and `LIBRAVDB_GRPC_TLS_KEY`.
58
+
59
+ **Local daemon with TLS enabled:**
60
+ If the daemon has `LIBRAVDB_GRPC_TLS_CERT`/`LIBRAVDB_GRPC_TLS_KEY` set on a loopback
61
+ address, explicitly set `grpcEndpointTlsMode: "tls"` to match:
62
+ ```json
63
+ {
64
+ "grpcEndpoint": "tcp:127.0.0.1:9090",
65
+ "grpcEndpointTlsMode": "tls"
66
+ }
67
+ ```
68
+
19
69
  ## Embedding
20
70
 
21
71
  | Key | Type | Default | Notes |
@@ -2,7 +2,7 @@
2
2
  "id": "libravdb-memory",
3
3
  "name": "LibraVDB Memory",
4
4
  "description": "Persistent vector memory with three-tier hybrid scoring",
5
- "version": "1.4.79",
5
+ "version": "1.5.0",
6
6
  "kind": [
7
7
  "memory",
8
8
  "context-engine"
@@ -46,6 +46,19 @@
46
46
  "type": "string",
47
47
  "description": "Optional gRPC kernel endpoint for hosts using the daemon kernel transport."
48
48
  },
49
+ "grpcEndpointTlsCa": {
50
+ "type": "string",
51
+ "description": "Path to a CA certificate PEM file for verifying the daemon's TLS certificate. Only needed for self-signed or private CA certificates. Not required when using a publicly trusted certificate (Let's Encrypt, cert-manager, etc)."
52
+ },
53
+ "grpcEndpointTlsMode": {
54
+ "type": "string",
55
+ "enum": [
56
+ "auto",
57
+ "tls",
58
+ "insecure"
59
+ ],
60
+ "description": "gRPC credential mode. auto (default): loopback and unix socket use plaintext, remote addresses use TLS. tls: always use TLS regardless of address. insecure: always use plaintext (use with service mesh or tunnel that handles TLS externally)."
61
+ },
49
62
  "authoredHardBudgetFraction": {
50
63
  "type": "number",
51
64
  "minimum": 0,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xdarkicex/openclaw-memory-libravdb",
3
- "version": "1.4.79",
3
+ "version": "1.5.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -43,7 +43,7 @@
43
43
  "pluginSdkVersion": "2026.4.11"
44
44
  },
45
45
  "install": {
46
- "minHostVersion": ">=2026.3.22"
46
+ "minHostVersion": ">=2026.4.11"
47
47
  }
48
48
  },
49
49
  "scripts": {