Merge pull request '修复 Google/Slack OAuth 回调的系统 CA 证书缺失' (#6) from codex/fix-oauth-ca into main
Foundry Go checks / check (push) Successful in 2m47s
Deploy Foundry Core / deploy (push) Successful in 2m30s

Reviewed-on: #6
This commit was merged in pull request #6.
This commit is contained in:
2026-11-05 15:16:11 +00:00
2 changed files with 19 additions and 0 deletions
+11
View File
@@ -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
+8
View File
@@ -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 {