v1.12.0 — UBI9 production base-image cutover
⚠️ Known issue — non-ASCII header/banner text causes HTTP 500 (fixed in v1.12.1)On this UBI9 image, if
SPARC_HEADER_TEXT(the rules-of-behavior header, rendered on every page) — or any operator-set environment variable rendered into a page, including the consent banner — contains non-ASCII characters (e.g.—,·,©, accented letters), the app returns HTTP 500 on all full-layout pages (including/login).Cause: UBI9 minimal ships no UTF-8 locale, so Ruby reads environment values as BINARY (ASCII-8BIT); rendering them into the UTF-8 page raises
Encoding::CompatibilityError. The prior Debian base setLANG=C.UTF-8implicitly, which masked this.You can still run v1.12.0 — apply either mitigation:
- Set a UTF-8 locale in your container / ECS task definition:
LANG=C.UTF-8andLC_ALL=C.UTF-8. (Recommended — no content changes; restart to apply.)- Use ASCII-only text for
SPARC_HEADER_TEXTand the consent-banner file.Fixed in v1.12.1, which bakes
LANG=C.UTF-8into the image (no action needed) plus a build-time guard so it can't regress. Tracking: #750.
Base-image cutover — Debian → Red Hat UBI9 (#742)
The production image moves from Debian ruby:3.4.4-slim to Red Hat UBI9 minimal (Iron Bank / DISA-aligned), retiring the recurring Debian perl/glibc CVE-disposition treadmill.
| Grype (same vuln DB) | Debian base | UBI9 (v1.12.0) |
|---|---|---|
| Critical | 15 | 0 |
| perl / glibc criticals | yes | 0 / 0 |
./Dockerfileis now UBI9 — Ruby 3.4.4 + jemalloc compiled from source, full app build (assets:precompile + OSCAL schema bundle + hdf-cli + entrypoint), non-root UID 1000. Multi-archamd64+arm64viabuild-sign-publish.Dockerfile_debianpreserves the prior image for rollback;sparc-findings.debian.ymlpreserves the Debian disposition set.- Residual UBI9 Highs (gnutls/curl/libpq/glib2/libacl + erb/net-imap default-gem shadows) are Red Hat-backported and non-gating (
--fail-on critical) — no perpetual dispositions. Gemfile:tzinfo-datais now unconditional (UBI9 ships no usable system zoneinfo).- Dev
docker-compose.yamlbuildsDockerfile_debian(fast apt-based dev loop); newdocker-compose.ubi9.yamlbuilds the UBI9 prod image for local smoke/API over TLS.
Validation
tests/api: 338 / 338.ui-smoke: 197 passed (Chrome, zero CSP violations).- A/B against a locally-built Debian prod image: byte-identical results — zero regression. Full evidence in
docs/dev/ubi9_migration_findings.md.
Supply-chain evidence layout (#741)
- S3 evidence emitters migrated to the canonical
<boundary>/<date|latest>/<repo>/<source>/layout for consistent, discoverable audit artifacts.
Process
- New release rule in
docs/dev/issue_rules.md: refreshdocs/security/SCANNER_FINDINGS_AUDIT.mdon every release (re-run bundle-audit/Trivy/Grype, refresh the review date, reconcile the suppression inventory). The audit is refreshed for v1.12.0/UBI9 (91 findings; 26 inert Debian entries pruned).
Full changelog: v1.11.1...v1.12.0