mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-18 08:01:26 +00:00
feat: register mounted CA certificates in windmill_extra at startup (#10545)
* feat: register mounted CA certificates in windmill_extra at startup Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: only claim a CA update when update-ca-certificates can read the mount Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: detect mounted CA certificates the way update-ca-certificates finds them Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+12
-3
@@ -118,9 +118,18 @@ not enough on its own, since `requests` carries its own bundle and Node reads on
|
||||
`NODE_EXTRA_CA_CERTS`. Registry settings are deliberately not forwarded: they carry credentials and
|
||||
only the service needs them.
|
||||
|
||||
To install that CA into the container's system store in the first place, set `INIT_SCRIPT` on the
|
||||
`windmill_extra` container (e.g. `INIT_SCRIPT=update-ca-certificates`). It runs before any service
|
||||
starts and aborts startup if it fails, the same hook a worker offers.
|
||||
Registering that CA in the container's system store happens on its own: mount it into
|
||||
`/usr/local/share/ca-certificates/` **named `*.crt`**, the only extension `update-ca-certificates`
|
||||
reads, and `windmill_extra` runs it before starting any service. `RUN_UPDATE_CA_CERTIFICATE_AT_START=true` forces the same thing whether or not
|
||||
certificates are mounted there, and `RUN_UPDATE_CA_CERTIFICATE_PATH` overrides the tool, matching
|
||||
the server and worker. Both are best-effort: a UID that cannot write `/etc/ssl/certs` logs a warning
|
||||
and the container still boots. `INIT_SCRIPT` remains the hook for anything more involved, and unlike
|
||||
the CA update it aborts startup when it fails.
|
||||
|
||||
Note what the system store does *not* cover, which is most of what a debug session installs with:
|
||||
uv trusts its own bundled roots unless `PY_NATIVE_CERT`/`UV_NATIVE_TLS` is `true`, Bun and Node read
|
||||
only `NODE_EXTRA_CA_CERTS`, and `requests` carries certifi. Registering the CA fixes Python's stdlib
|
||||
`ssl`, `curl` and `git`; the rest still needs the variables above.
|
||||
|
||||
Keeping the settings out of the session's environment only bounds what the debugged script can read
|
||||
from itself. An unsandboxed session runs under the same user as the service and can still read the
|
||||
|
||||
@@ -187,6 +187,10 @@ services:
|
||||
# - DEBUG_ALLOWED_ORIGINS=https://your-windmill-host # Optional CSWSH hardening: comma-separated allowlist of browser Origins permitted to open debug WebSockets
|
||||
volumes:
|
||||
- lsp_cache:/pyls/.cache
|
||||
# Behind a TLS-intercepting proxy, mount its CA here (as .crt) and it is registered in the
|
||||
# system trust store before any service starts. That alone does not cover dependency
|
||||
# installation — see debugger/README.md for the variables it also needs
|
||||
# - ./corp-ca.crt:/usr/local/share/ca-certificates/corp-ca.crt:ro
|
||||
logging: *default-logging
|
||||
|
||||
caddy:
|
||||
|
||||
@@ -33,6 +33,44 @@ if [ ! -w "$HOME" ]; then
|
||||
fi
|
||||
export HOME
|
||||
|
||||
# Register CA certificates mounted into the image before anything opens a TLS connection.
|
||||
# Best-effort on purpose, unlike INIT_SCRIPT below: a non-root UID cannot write /etc/ssl/certs, and
|
||||
# a deployment that never needed a custom CA must still boot. Env var names and the default-off
|
||||
# behavior match the server/worker binary, so one setting covers every container. What the system
|
||||
# trust store does and does not reach is documented in debugger/README.md.
|
||||
CA_CERT_DIR=/usr/local/share/ca-certificates
|
||||
|
||||
update_ca_certificates() {
|
||||
local reason="$1"
|
||||
local tool="${RUN_UPDATE_CA_CERTIFICATE_PATH:-/usr/sbin/update-ca-certificates}"
|
||||
local output
|
||||
if [ ! -x "$tool" ]; then
|
||||
echo "[entrypoint] $reason but $tool is not executable, skipping CA update"
|
||||
return
|
||||
fi
|
||||
echo "[entrypoint] $reason, running $tool"
|
||||
if output=$("$tool" 2>&1); then
|
||||
echo "[entrypoint] CA certificates updated"
|
||||
else
|
||||
# Carry the tool's own message: the usual cause is an unwritable /etc/ssl/certs under a
|
||||
# non-root UID, but guessing that in place of the real error hides everything else.
|
||||
echo "[entrypoint] WARNING: $tool failed (UID $(id -u)): ${output:-no output}; continuing" >&2
|
||||
fi
|
||||
}
|
||||
|
||||
if [ "$(echo "${RUN_UPDATE_CA_CERTIFICATE_AT_START:-false}" | tr '[:upper:]' '[:lower:]')" = "true" ]; then
|
||||
update_ca_certificates "RUN_UPDATE_CA_CERTIFICATE_AT_START=true"
|
||||
elif [ -n "$(find -L "$CA_CERT_DIR" -type f -name '*.crt' -print -quit 2>/dev/null)" ]; then
|
||||
# Certificates mounted there are unambiguous intent, and they do nothing until registered, so
|
||||
# take the same action without making the operator also find the env var.
|
||||
update_ca_certificates "Found certificates in $CA_CERT_DIR"
|
||||
elif [ -n "$(ls -A "$CA_CERT_DIR" 2>/dev/null)" ]; then
|
||||
# Reporting success over a mount update-ca-certificates ignores would be worse than saying
|
||||
# nothing: .pem is the spelling people reach for, and only .crt is read.
|
||||
echo "[entrypoint] WARNING: $CA_CERT_DIR has files but none named *.crt, the only extension" \
|
||||
"update-ca-certificates reads; they will be ignored" >&2
|
||||
fi
|
||||
|
||||
# INIT_SCRIPT is the documented hook for preparing the host before anything reaches the network
|
||||
# (CA certificates, proxies, mounts), matching the worker's INIT_SCRIPT. It must therefore complete
|
||||
# before any service starts, and a failure has to abort: services that come up with an unprepared
|
||||
|
||||
Reference in New Issue
Block a user