mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-30 09:50:39 +00:00
Fix NODE_EXTRA_CA_CERTS missing from LaunchAgent environment on macOS
launchd services do not inherit the shell environment, so Node's undici/fetch cannot locate the macOS system CA bundle (/etc/ssl/cert.pem). This causes TLS verification failures for all HTTPS requests (e.g. Telegram, webhooks) when the gateway runs as a LaunchAgent, while the same gateway works fine in a terminal. Add NODE_EXTRA_CA_CERTS defaulting to /etc/ssl/cert.pem on macOS in both buildServiceEnvironment and buildNodeServiceEnvironment. User-supplied NODE_EXTRA_CA_CERTS is always respected and takes precedence. Fixes #22856 Co-authored-by: Clawborn <tianrun.yang103@gmail.com>
This commit is contained in:
@@ -328,6 +328,24 @@ describe("buildServiceEnvironment", () => {
|
||||
expect(env.NO_PROXY).toBe("localhost,127.0.0.1");
|
||||
expect(env.http_proxy).toBe("http://proxy.local:7890");
|
||||
expect(env.all_proxy).toBe("socks5://proxy.local:1080");
|
||||
it("defaults NODE_EXTRA_CA_CERTS to system cert bundle on macOS", () => {
|
||||
const env = buildServiceEnvironment({
|
||||
env: { HOME: "/home/user" },
|
||||
port: 18789,
|
||||
});
|
||||
if (process.platform === "darwin") {
|
||||
expect(env.NODE_EXTRA_CA_CERTS).toBe("/etc/ssl/cert.pem");
|
||||
} else {
|
||||
expect(env.NODE_EXTRA_CA_CERTS).toBeUndefined();
|
||||
}
|
||||
});
|
||||
|
||||
it("respects user-provided NODE_EXTRA_CA_CERTS over the default", () => {
|
||||
const env = buildServiceEnvironment({
|
||||
env: { HOME: "/home/user", NODE_EXTRA_CA_CERTS: "/custom/certs/ca.pem" },
|
||||
port: 18789,
|
||||
});
|
||||
expect(env.NODE_EXTRA_CA_CERTS).toBe("/custom/certs/ca.pem");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -365,6 +383,24 @@ describe("buildNodeServiceEnvironment", () => {
|
||||
});
|
||||
expect(env.TMPDIR).toBe(os.tmpdir());
|
||||
});
|
||||
|
||||
it("defaults NODE_EXTRA_CA_CERTS to system cert bundle on macOS for node services", () => {
|
||||
const env = buildNodeServiceEnvironment({
|
||||
env: { HOME: "/home/user" },
|
||||
});
|
||||
if (process.platform === "darwin") {
|
||||
expect(env.NODE_EXTRA_CA_CERTS).toBe("/etc/ssl/cert.pem");
|
||||
} else {
|
||||
expect(env.NODE_EXTRA_CA_CERTS).toBeUndefined();
|
||||
}
|
||||
});
|
||||
|
||||
it("respects user-provided NODE_EXTRA_CA_CERTS for node services", () => {
|
||||
const env = buildNodeServiceEnvironment({
|
||||
env: { HOME: "/home/user", NODE_EXTRA_CA_CERTS: "/custom/certs/ca.pem" },
|
||||
});
|
||||
expect(env.NODE_EXTRA_CA_CERTS).toBe("/custom/certs/ca.pem");
|
||||
});
|
||||
});
|
||||
|
||||
describe("resolveGatewayStateDir", () => {
|
||||
|
||||
@@ -248,11 +248,17 @@ export function buildServiceEnvironment(params: {
|
||||
// Keep a usable temp directory for supervised services even when the host env omits TMPDIR.
|
||||
const tmpDir = env.TMPDIR?.trim() || os.tmpdir();
|
||||
const proxyEnv = readServiceProxyEnvironment(env);
|
||||
// On macOS, launchd services don't inherit the shell environment, so Node's undici/fetch
|
||||
// cannot locate the system CA bundle. Default to /etc/ssl/cert.pem so TLS verification
|
||||
// works correctly when running as a LaunchAgent without extra user configuration.
|
||||
const nodeCaCerts =
|
||||
env.NODE_EXTRA_CA_CERTS ?? (process.platform === "darwin" ? "/etc/ssl/cert.pem" : undefined);
|
||||
return {
|
||||
HOME: env.HOME,
|
||||
TMPDIR: tmpDir,
|
||||
PATH: buildMinimalServicePath({ env }),
|
||||
...proxyEnv,
|
||||
NODE_EXTRA_CA_CERTS: nodeCaCerts,
|
||||
OPENCLAW_PROFILE: profile,
|
||||
OPENCLAW_STATE_DIR: stateDir,
|
||||
OPENCLAW_CONFIG_PATH: configPath,
|
||||
@@ -274,11 +280,17 @@ export function buildNodeServiceEnvironment(params: {
|
||||
const configPath = env.OPENCLAW_CONFIG_PATH;
|
||||
const tmpDir = env.TMPDIR?.trim() || os.tmpdir();
|
||||
const proxyEnv = readServiceProxyEnvironment(env);
|
||||
// On macOS, launchd services don't inherit the shell environment, so Node's undici/fetch
|
||||
// cannot locate the system CA bundle. Default to /etc/ssl/cert.pem so TLS verification
|
||||
// works correctly when running as a LaunchAgent without extra user configuration.
|
||||
const nodeCaCerts =
|
||||
env.NODE_EXTRA_CA_CERTS ?? (process.platform === "darwin" ? "/etc/ssl/cert.pem" : undefined);
|
||||
return {
|
||||
HOME: env.HOME,
|
||||
TMPDIR: tmpDir,
|
||||
PATH: buildMinimalServicePath({ env }),
|
||||
...proxyEnv,
|
||||
NODE_EXTRA_CA_CERTS: nodeCaCerts,
|
||||
OPENCLAW_STATE_DIR: stateDir,
|
||||
OPENCLAW_CONFIG_PATH: configPath,
|
||||
OPENCLAW_LAUNCHD_LABEL: resolveNodeLaunchAgentLabel(),
|
||||
|
||||
Reference in New Issue
Block a user