Repository navigation
feat(computer): every runtime in a computer routing sites trusts the deploy's CA (FD-4933) - #537
Merged
earakely-scale merged 5 commits intoNov 8, 2026
Conversation
…deploy's CA, however it was started The trust variables lived only in /etc/profile.d, which only login shells read, so apps launched at boot or from the menu and computer-exec commands never saw them. The local provider's trust convention is now agentenv's for the sites CA too: /etc/agentenv/ca.pem holds every CA agentenv adds and ca-bundle.pem the public roots plus them, a computer routing sites boots with the same SSL_CERT_FILE, REQUESTS_CA_BUNDLE and NODE_EXTRA_CA_CERTS, and routing appends the CA to both files. Every JDK trusts it, apt ones through the system store's hook and the rest by keytool, and routing checks Python through SSL_CERT_FILE alone, Node and curl too, failing the deploy on any runtime or JDK store that doesn't trust it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… the trust variables With every routed name a .localhost one, no CA is made and the install writes no trust files, so SSL_CERT_FILE and REQUESTS_CA_BUNDLE named files that didn't exist and every public HTTPS request through them failed. The computer now boots with them only when a site it routes is served over HTTPS, as issue() decides a CA is needed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…the trust files in the Ubuntu bases, and is refused off Linux - The bundle of public roots plus the CAs agentenv adds starts from Debian's or Red Hat's file of public roots where neither the image nor a provider made it, and routing is refused on a Linux with neither rather than leave it the CA alone. - The ubuntu-24.04 and ubuntu-24.04-headless images ship /etc/agentenv/ca.pem (empty) and ca-bundle.pem (the system bundle), so services started at boot, before routing, find the files the trust variables name. - The trust files and variables are kept per OS type (sites.TRUST_ENVIRONMENTS, Linux's the local provider's), and site routing is refused at save and at deploy on a computer that isn't Linux, which a macOS computer would have half-applied. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tore, so it holds CAs apps added after the image was built The Ubuntu bases copy the system bundle into /etc/agentenv/ca-bundle.pem when they're built, before a composed app's install runs. An app that added a CA with update-ca-certificates would have been left out of the bundle routing kept, so clients reading SSL_CERT_FILE rejected it. Routing now makes the bundle from the system store's public roots as they are then, plus every CA in ca.pem; a Linux with no file of public roots keeps the bundle it has. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…per-OS table names, with no fallback The host now sends the OS's trust variables with the trust files, and install writes exactly those to the profile script, so login shells and the boot environment can't disagree when a variable is added. The fallback for a config without trust files, which nothing sends since the proxy is copied with the host on every route, is gone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
earakely-scale
deleted the
edgararakelyan/fd-4933-m54-the-deploys-ca-its-trust-step-and
branch
November 8, 2026 16:07
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What and why
M5.4 (FD-4933): every program on a deployed Linux computer that checks TLS certificates trusts the deploy's CA, however it was started: browsers, the system store, Node, Python, programs reading
SSL_CERT_FILE(Go, Ruby, OpenSSL tools) and Java. M5.7 (sites by name over HTTPS) and M5.17 (apps that depend on sites) need any app in the computer to loadhttps://<site>/without certificate errors. #448 shipped the CA itself and most stores; the outcome and four decisions are on FD-4933, decisions 1 and 2 revised once the local provider's trust files turned up. Site routing stays Linux-only here, shaped so macOS and Windows can be added: they're M6.6 (FD-5335)./etc/profile.d, which only login shells read. Apps launched at boot or from the menu, andcomputer-execcommands not run through a login shell, never sawNODE_EXTRA_CA_CERTSorREQUESTS_CA_BUNDLE, and nothing setSSL_CERT_FILE./etc/agentenv/ca.pemand/etc/agentenv/ca-bundle.pem(the public roots plus it) and points the three variables at them. That's now the convention for the sites CA too:/etc/agentenv/ca.pemholds every CA agentenv adds and is the fixed path the design names for an app with a certificate list of its own;ca-bundle.pemholds the public roots plus them. A computer routing a site served over HTTPS boots with the same variables, so every process inherits them; one routing only.localhostnames, for which no CA is made, boots without them. The files and variables are kept per OS type (sites.TRUST_ENVIRONMENTS), whose Linux entry is the provider'sLOCAL_TRUST_ENV, so the two can't disagree. Routing appends the CA to both files; both are readable by everyone. The profile script now sets the same variables, sent from the same table, for shells that start a fresh login environment.ubuntu-24.04andubuntu-24.04-headlessimages ship an emptyca.pemandca-bundle.pemas a copy of the system bundle. An app's services start at boot, before routing, and inherit the variables, so until routing appends the CA they get the public roots instead of a missing file. A local run's provider still copies its own files over them.ca-bundle.pemfrom the system's file of public roots as it is then, plus every CA inca.pem(a provider's and the sites'). That file is Debian's (/etc/ssl/certs/ca-certificates.crt) or Red Hat's (/etc/pki/tls/certs/ca-bundle.crt), andupdate-ca-certificateshas just added the sites CA to it. So the bundle also holds any CA a composed app added to the system store after the image was built. On a Linux with neither file, routing keeps the bundle the image or a provider made; with no bundle either, it's refused, naming both files, rather than leave a bundle of the CA alone, which would break public HTTPS for every program readingSSL_CERT_FILE.ca-certificates-java's hook, whichupdate-ca-certificatesruns; every other JDK under/usr/lib/jvm,/optand the app folders gets it withkeytool, its own else any. Each store is checked withkeytool -listfor the CA's SHA-256 fingerprint and recorded intrust.java.SSL_CERT_FILEalone, and through Node and curl where the computer has them, as the session user. Each result is kept in the deploy record'ssites.runtimes, and any runtime or JDK store that fails fails the deploy, naming it.How it was tested
ruff check: clean.Unit tests:
test_computer_site_proxy.py: the install writes the shared trust files and the profile script, its bundle from Red Hat's public roots; the CA joins files a provider made, idempotently, or a bundle started from the system's; the bundle is made again from the system store, holding a CA an app added after the image was built and a provider's CA fromca.pem; an empty bundle with no public roots to start from is refused before either file is written; JDKs: an apt one through the hook store (listed only), a downloaded one and a bundled one withoutkeytool(imported), a link to the same store once, a store whose password differs and one the CA isn't listed in (each named); the runtime checks, withSSL_CERT_FILEunset named.test_computer_sites.py: each failure named; Linux's trust variables equal the local provider's.test_computer_env.py: a routing computer boots with them, one without routing doesn't; the route is given the computer's OS type.test_computer_vm_bundle.py: site routing into a macOS computer is refused, at save and through the check the deploy runs.tst/unit/envandtst/unit/providers: 3929 passed; the onetest_disk_recipefailure fails on macOS only.VM e2e, agent-environments-admin, amd64 and arm64: a new test bundle,
tls, whoseclientsapp installs Node, an apt JDK and curl, copies the JDK under/optwith a store of its own, and, launched at boot, loads its URL through each. With a site routed into the computer,ca_trust_test.pychecks that:SSL_CERT_FILEalone;/etc/agentenv/ca.pemholds the CA, mode 644, and/etc/agentenv/ca-bundle.pemholds it beside the public roots;The routed-site and start-tab tests from M5.12 run again beside it. On f47f064 all 5 passed on both arches (about 14 minutes each). The composed images carry the two files from build: an empty
ca.pemandca-bundle.pemwith 120 public roots, both mode 644. After Greptile's round-3 finding (the image's copy would miss a CA an app adds), the bundle is made again at routing; on ece919c the CA trust test passed again on both arches.🤖 Generated with Claude Code


Confidence Score: 5/5
The PR appears safe to merge; no blocking issue remains.Summary
The PR gives Linux computers shared CA files and trust settings for browsers, Python, Node, curl, and Java.
Diagram
%%{init: {'theme': 'neutral'}}%% flowchart TD A[Shared Linux trust settings] --> B[Computer boot environment] A --> C[Fresh routing config] C --> D[Install CA in trust stores] C --> E[Write login shell exports] D --> F[Check sites and runtimes]Reviews (8) · Last reviewed commit: "refactor(computer): the profile script s..." · Reviewed by Greptile