From b1e0d783e6466eddbb26dc5bf621fc7d7cca7eb8 Mon Sep 17 00:00:00 2001 From: Codex Bot Date: Thu, 5 Nov 2026 21:39:11 +0800 Subject: [PATCH] Mount system CA roots for OAuth HTTPS requests --- README.md | 11 +++++++++++ deploy/release.sh | 8 ++++++++ 2 files changed, 19 insertions(+) diff --git a/README.md b/README.md index f797b83..5efc091 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,17 @@ Google OAuth 的授权回调地址为 `https://api.foundry.entroia.com/auth/goog 用同一个 Google 测试账号分别登录两个项目,确认用户 ID 不同。用 A 的会话请求 B 的 `me` 应返回 401。验证兑换码重放被拒绝,并确认退出 A 后 B 的会话仍有效。 +## Runtime HTTPS trust + +The Go backend needs an operating-system CA bundle for Google and Slack HTTPS +requests. The `node:24-bookworm-slim` runtime does not include that trust store; +Node's own successful HTTPS checks do not validate Go's trust configuration. +`deploy/release.sh` mounts the deployment host's +`/etc/ssl/certs/ca-certificates.crt` read-only and sets `SSL_CERT_FILE` to that +path. The deployment fails before switching traffic if the host bundle is +missing or unreadable in the candidate. Keep TLS certificate verification +enabled and maintain the deployment host's trusted CA package. + ## Codex execution When enabled, `POST /projects/{project}/codex/exec` accepts a JSON object diff --git a/deploy/release.sh b/deploy/release.sh index 22f6be7..cace2aa 100644 --- a/deploy/release.sh +++ b/deploy/release.sh @@ -39,6 +39,10 @@ PYCONFIG export FOUNDRY_PROJECTS test -s "$foundry/database.env" +# Go's HTTPS client uses the OS trust store, not Node's bundled roots. +# The slim Node runtime has no system CA bundle of its own. +ca_bundle=/etc/ssl/certs/ca-certificates.crt +test -s "$ca_bundle" docker network inspect "$network" >/dev/null python3 "$(dirname "$0")/migrate.py" @@ -88,6 +92,8 @@ docker run -d --name "$candidate" "${codex_mounts[@]}" "${mail_env[@]}" "${slack -e GOOGLE_CLIENT_ID -e GOOGLE_CLIENT_SECRET -e FOUNDRY_PROJECTS -e FOUNDRY_ONBOARDING \ --user 1000:1000 --cap-drop ALL --security-opt no-new-privileges \ --read-only --memory 128m \ + --mount "type=bind,source=$ca_bundle,target=/etc/ssl/certs/ca-certificates.crt,readonly" \ + -e SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt \ --mount "type=bind,source=$release/foundry,target=/opt/foundry,readonly" \ node:24-bookworm-slim /opt/foundry >/dev/null @@ -98,7 +104,9 @@ trap cleanup_candidate EXIT docker exec "$candidate" node -e ' const assert = require("node:assert/strict"); + const fs = require("node:fs"); async function verify() { + assert.ok(fs.readFileSync(process.env.SSL_CERT_FILE, "utf8").includes("-----BEGIN CERTIFICATE-----")); const base = "http://127.0.0.1:8080"; for (let attempt = 0; ; attempt++) { try { -- 2.52.0