fix(release): CGO=0-safe pure-Go sqlite driver + thin all-in-one image - #5662
Merged
norman-abramovitz merged 8 commits intoJul 21, 2026
Merged
Conversation
The release binaries are cross-compiled with CGO_ENABLED=0, but the sqlite
driver was mattn/go-sqlite3 (cgo-only). At CGO=0 it compiles to a stub that
errors on the first DB touch ("requires cgo to work"). Every shipped config
(run-local config.example, cf, all-in-one) defaults DATABASE_PROVIDER=sqlite,
so all three deployment modes were broken for their default DB. Tests passed
only because `go test` defaults CGO_ENABLED=1.
Swap to modernc-style pure-Go: ncruces/go-sqlite3 (sqlite compiled to wasm,
run on wazero). It registers the same "sqlite3" driver name, so datastore,
goose, and the session store keep working unchanged, and CGO=0 cross-compiles
now produce fully static, sqlite-capable binaries on all platforms.
nwmac/sqlitestore (the sqlite gorilla session store) blank-imported
mattn/go-sqlite3, which re-registered "sqlite3" and collided with ncruces.
Stratos only calls NewSqliteStoreFromConnection with an already-open *sql.DB,
so vendor the 344-line MIT store into repository/sqlitestore/ minus that dead
import. This drops both mattn/go-sqlite3 and nwmac/sqlitestore from go.mod.
`make build backend PLATFORM=...` (used by the cf/korifi paths) ran `go build` without setting CGO_ENABLED, so it inherited Go's host-dependent default: CGO=1 when the target matches the host (native linux CI), CGO=0 when cross (mac). That made the cf zip's sqlite work-or-not depend on where it was built. Pin CGO_ENABLED=0 to match cross-compile.sh, so every backend build is the same static, pure-Go binary regardless of host.
…facts The docker/all-in-one deployment mode (mode 3) was broken: the old deploy/Dockerfile.all-in-one built current source on splatform/stratos-* :leap15_2 (Node 12), which cannot run the ESM/bun build, and docker.yml referenced a non-existent deploy/all-in-one/Dockerfile so its job silently skipped and reported green while shipping no image. Rebuild it as a thin image that reuses what the release already produces — now possible because the CGO=0 binaries are sqlite-capable (pure-Go driver): - deploy/all-in-one/stage-aio.sh assembles dist/aio-package/ from the release-built jetstream + ui + templates + plugins + all-in-one config, and generates dev-certs. It builds nothing. - deploy/all-in-one/Dockerfile COPYs that payload onto debian:bookworm-slim. No Node/Go toolchain, no source build. One image serves both `docker run` (HTTPS :5443) and `cf push -o` (VCAP -> $PORT via cloudfoundryhosting). - make release aio wires the staging into the verb system (actions.mk + Makefile), so `make release cf github aio` composes in one pass. - release.yml stages the payload and a new build-all-in-one-image job pushes ghcr.io/<owner>/stratos, built for prereleases too so rc tags get an image. - docker.yml's silent-skip all-in-one job is removed (superseded here). Deletes the broken deploy/Dockerfile.all-in-one. linux/amd64 only for now. Validated: docker run of the image serves :5443 and reads sqlite live.
The changelog had no entry past 4.5.0 (2023) — nothing for the 5.0.0 line. Add a 5.0.0 section covering the signal-native frontend rebuild, Tailwind v4 / OKLCH theming, the pure-Go sqlite fix, the three reuse-the-same-artifacts deployment modes, and the GitHub Actions release automation, so the release notes have real content to extract.
The release pipeline publishes the all-in-one console image to ghcr.io/cloudfoundry/stratos, but the deploy docs and manifest still told users to pull splatform/stratos:stable from Docker Hub (never published by this pipeline). Update manifest-docker.yml, the all-in-one guide, and the cloud-foundry docker-image push method to ghcr.io/cloudfoundry/stratos:latest. The separate splatform/stratos-uaa dev image is left as-is (not published here).
The vendored sqlitestore emits session cookies via http.SetCookie whose Secure flag comes from the runtime session.Options. initSessionStore already sets Options.Secure = true for every provider, so this was correct at runtime, but CodeQL (go/cookie-secure-not-set) cannot trace the runtime option and flagged both SetCookie sinks once the store moved in-tree. The sibling pg/mysql stores have the same pattern but live in external deps CodeQL does not scan. Set Secure = true locally at both sinks (Save and Delete). Stratos serves the console over HTTPS in every mode, so this is behavior-preserving and adds defense-in-depth: the store now guarantees secure cookies independent of the caller.
Clears four Dependabot alerts: - js-yaml < 4.3.0 (quadratic CPU via YAML merge-key chains, High) — root package.json direct dev dep and the devkit transitive. - webpack-dev-server <= 5.2.5 (DoS via malformed Host/Origin header; CSRF via internal dev endpoints, Moderate) — pinned in the devkit override block. Bump the root js-yaml to 4.3.0 (bun.lock regenerated), add a js-yaml 4.3.0 override in devkit, and move the devkit webpack-dev-server override to 5.2.6 (package-lock.json regenerated). bun install --frozen-lockfile passes, so this does not repeat the Dependabot-npm-PR lockfile-mismatch CI failure.
CodeQL go/cookie-secure-not-set tracks the Secure field on the *http.Cookie handed to http.SetCookie; it does not model gorilla sessions.NewCookie propagating Options.Secure, so setting session.Options.Secure = true did not clear the alert. Set cookie.Secure = true on the returned cookie directly in Save and Delete. Behaviour is unchanged (Stratos already runs HTTPS-only and initSessionStore forces Options.Secure = true).
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.
Why
v5.0.0-rc.1 is broken for its default database in every deployment mode. The
release binaries cross-compile with
CGO_ENABLED=0, but the sqlite driver wasmattn/go-sqlite3(cgo-only). At CGO=0 it compiles to a stub that errors on thefirst DB touch. Every shipped config (run-local
config.example, cf, all-in-one)defaults
DATABASE_PROVIDER=sqlite, so run-local,cf push, and the all-in-oneimage were all broken. Tests were green only because
go testdefaultsCGO_ENABLED=1.What
mattn/go-sqlite3→ncruces/go-sqlite3(sqlite compiled to wasm, run on wazero). It registers the same
"sqlite3"driver name, so datastore, goose migrations, and the session store are
unchanged. CGO=0 cross-compiles now produce fully static, sqlite-capable
binaries on all platforms.
nwmac/sqlitestoreblank-importedmattn/go-sqlite3, re-registering"sqlite3"and colliding with ncruces.Stratos only calls
NewSqliteStoreFromConnectionwith an already-open*sql.DB, so the 344-line MIT store is vendored intorepository/sqlitestore/minus that dead import. Drops bothmattnandnwmacfrom go.mod.CGO_ENABLED=0in the single-platform backend build so the buildis no longer host-dependent (native linux implicitly went CGO=1 and masked
the bug; mac cross went CGO=0 and broke).
deploy/all-in-one/Dockerfile(
debian:bookworm-slim, COPY prebuilt jetstream + ui, no source build),make release aio, and abuild-all-in-one-imagerelease job that pushes toghcr. Deletes the broken
deploy/Dockerfile.all-in-one.at
ghcr.io/cloudfoundry/stratos.Verification
CGO_ENABLED=0 go test . -run TestConsoleSetuppasses (was the stub failure).grep -c mattn/go-sqlite3 src/jetstream/go.mod→ 0.from a token decrypted out of sqlite.
docker runof the AIO image serves and reads sqlite.