Repository navigation
Ferrum Foundry v0.3.0
Ferrum Foundry v0.3.0
This release pairs Foundry with Ferrum Edge v0.9.8. Like v0.2.0, it is
intended for a supervised early-access deployment: one gateway, a small
number of administrators, the documented identity-proxy topology. It tightens
static-token authentication, which is a breaking change for static-mode
deployments (see Upgrading from v0.2.0). It also
redacts secrets from write failures and makes effective-policy analysis and
upstream and credential editing more accurate. It makes no compatibility
promise for other Edge releases. Changes since
v0.2.0:
git log v0.2.0..v0.3.0.
Supported pairing
| Foundry | v0.3.0 — ferrumedge/ferrum-foundry:v0.3.0, linux/amd64 and linux/arm64. Deploy it by the multi-architecture digest this release's run publishes |
| Ferrum Edge | Ferrum Edge v0.9.8 — ferrumedge/ferrum-edge@sha256:e5b204f9448d4ec210a57dbd2badece5f4359d5d544522fa48dcdfeef033b385, commit e27f2109216352c3fe9e67a7014611f3f66daa91; linux/amd64 sha256:0e629633ad55368002c415bbf76d4c91f3741519a33dd310045531d791d9a592, linux/arm64 sha256:1e900bd537814fdc864ee1830bbd7a1e1f2785074a5da088a3d9cdd738b532f9 |
| Tested gateway | database mode on SQLite, writable and with FERRUM_ADMIN_READ_ONLY=true; admin JWT with audience and namespace-claim enforcement |
| Tested access | trusted-proxy authentication through the starter's identity proxy; viewer, operator, and admin |
| Tested browser | Chromium (the build bundled with Playwright 1.63.0) |
| CI evidence | The pull request that moved the pin to v0.9.8, and this release's Pre-publication Gates, which re-run every gate against the same image before anything is published |
Best-effort: PostgreSQL/MySQL database mode, cp mode, other browsers,
Kubernetes, static-token authentication (development only). Not qualified:
file/dp/mesh/node_agent modes (so the mesh, waypoint, trust, and
chargeback pages), any other Edge release, and any other Edge image, including
the 0.9.8-ebpf variants. The full envelope, including tested scale, is in
docs/compatibility.md.
Ferrum Edge v0.9.8 leaves the admin API Foundry depends on unchanged from
v0.9.7. Conditional writes (ferrum-edge#5661: a strong ETag on resource reads
and If-Match on PUT/DELETE) keep guarded saves and detail-page deletes
atomic, and the GET /plugins/config?proxy_id= filter (ferrum-edge#5726)
still backs a proxy's Plugins tab. Edge's plugin configuration projection,
which Foundry's secret redaction follows, is the same table.
Highlights since v0.2.0
Authentication
- Static-token mode refuses to start without
FERRUM_JWT_NAMESPACES, and a
set-but-empty value is a startup error in either mode;*alone is the
explicit spelling for every namespace (#460, #462). - Runtime settings can narrow a session's namespace grants but never widen
them, and intrusted-proxymode an emptyX-Ferrum-Namespacesheader is
refused rather than read as "every namespace" (#460, #464). FERRUM_JWT_SECRETis used byte for byte, as Ferrum Edge verifies it,
instead of being trimmed (#486).
Secrets stay out of errors
- Every write that carries a secret — consumer create and credentials, plugin
configurations, upstreams, TLS key material and ACME account credentials,
batch create, backup restore, and API spec import and replacement — replaces
each submitted secret with[REDACTED]in any refusal the gateway echoes,
before anything is shown or kept. Plugin configurations are classified by
Ferrum Edge's own projection table (#466, #478, #485, #487, #491, #493).
Accurate policy
- Effective policy follows the gateway's scope merge: an attached scoped
plugin shadows the same-name global one, a group configuration carrying
proxy_idis excluded, and a proxy protected only byaccess_controlreads
as denied, not public (#469, #470, #472). - The Matched Proxies tab builds its plugin-attachment index once per
collection instead of scanning per proxy (#454).
Safer editing
- Upstream target editors are bound to the target they edit, keep their draft
across refreshes, and are guarded against a background refresh advancing
past the draft (#445, #448, #464). - Upstream subset selectors are edited as lossless key/value rows, and a
sticky-hash cookie's unsetSameSiteis kept (#449, #479). - A consumer credential write that committed but is not yet live disarms the
form, and a lost credential add is reported honestly and cannot be
resubmitted blind (#451, #466). - A restore retires every pre-restore detail cache so reopened editors show
what the gateway now holds (#446). - Guided plugin edits keep literal
"null"strings (#483), and a host-only
proxy keeps its absentlisten_path(#447).
Operating Foundry
- A runtime
adminUrlchange can no longer carry one gateway's cached data,
drafts, or operations to another: the BFF refuses requests declared against
a replaced target with409(#437). - Sessions follow the authentication lifecycle and the shared CSRF cookie
across tabs (#435, #436). - Uploads refused or unread by the gateway are drained under bounded, pooled
limits instead of resetting the connection (#453, #468). - Dashboard request rates are bound to the gateway they were sampled from
(#476). - A UI polish pass: one page header, flush tables, consistent dates and
labels, an accessible mobile drawer, and a lighter brand mark (#450, #455). - Node.js minimums are 22.22.2 and 24.15.0 (#452).
The complete list is in
CHANGELOG.md.
Known limitations
- The cached-config fallback is not atomic. A read Ferrum Edge serves from
its cached configuration (X-Data-Source: cached) carries noETag, so a
write verified against it is sent withoutIf-Match. A stale editor still
cannot revert a newer change, but a writer that commits within that one round
trip is not detected. - One qualified gateway configuration. Modes other than
database, and Edge
releases other than v0.9.8, have not been run in CI. - Scale. Real-gateway testing covers tens of resources per namespace.
Request budgets are measured at 50,000 records against a synthetic gateway;
browser latency is not measured. List search still traverses the
collection, because the admin API offers no server-side search, and the
effective plugin policy of a proxy still traverses the namespace's plugin
configurations, because global and proxy-group configurations cannot be
filtered. - One browser. Only Chromium runs in the release gate.
Install
Run the pairing above, both by digest.
docker pull ferrumedge/ferrum-edge@sha256:e5b204f9448d4ec210a57dbd2badece5f4359d5d544522fa48dcdfeef033b385
docker pull ferrumedge/ferrum-foundry:v0.3.0 # then pin the digest it resolves to- New deployment: follow Getting started
with the starter, then Deployment
for the production checklist. SetFOUNDRY_IMAGEto the Foundry digest; the
starter's default (:main) is the development channel. FERRUM_JWT_SECRETmust equal the gateway'sFERRUM_ADMIN_JWT_SECRET, and
FERRUM_JWT_AUDIENCEitsFERRUM_ADMIN_JWT_AUDIENCE.
Upgrading from v0.2.0
Foundry keeps no persistent state of its own, so an upgrade is an image
replacement.
- Move the gateway to Ferrum Edge v0.9.8 first, following Ferrum Edge's own
upgrade guide
("Upgrading to 0.9.8"). Its changes are to the data plane (HTTP/3 rule
timeouts, therequest_timeoutX-Gateway-Errortoken, the
ValidateJWTSVIDclaims wire type); the admin API Foundry uses is
unchanged. Foundry v0.2.0 is not qualified against v0.9.8, so upgrade both
together. - Apply the configuration changes below before replacing the image.
- Replace the Foundry image with the release digest and confirm
GET /api/health/readyreports version0.3.0and a reachable gateway. - Reload open browser tabs so they run the new SPA bundle.
Configuration changes in this release:
- Breaking, static authentication mode only:
FERRUM_JWT_NAMESPACESis
required. A static-mode BFF without it refuses to start, where v0.2.0 granted
the static principal every namespace. To keep the v0.2.0 behavior, set
FERRUM_JWT_NAMESPACES=*before replacing the image; to scope the principal,
list exact namespace names instead.trusted-proxydeployments, including
the deployment starter, need no change as long as they leave
FERRUM_JWT_NAMESPACESunset. - Breaking, either authentication mode: a set-but-empty
FERRUM_JWT_NAMESPACES— empty, whitespace, or commas only — is now a startup
error, where v0.2.0 treated it as if the variable were unset and left the
principal unrestricted. Operators who set such a value should unset it in
trusted-proxymode, or set*or exact namespace names instaticmode.
Rolling back
- Foundry: redeploy the previous immutable tag or digest. Nothing Foundry
wrote needs undoing — configuration lives in Ferrum Edge — but a rollback
does not revert configuration changes made through the newer version, and
v0.2.0 is not qualified against Ferrum Edge v0.9.8. AFERRUM_JWT_NAMESPACES
set for v0.3.0 is also valid for v0.2.0. - Ferrum Edge: follow Ferrum Edge's own rollback guidance: during Edge's
build-out, cut traffic back to the old binary on the old, untouched
database rather than pointing an older binary at a new one. Take a backup
per namespace with Settings → Download Backup (GET /backup, admin role)
before either upgrade. - Confirm
FERRUM_JWT_SECRETandFERRUM_JWT_AUDIENCEstill match the gateway
after any rollback.
Docker
docker pull ferrumedge/ferrum-foundry:v0.3.0
docker pull ghcr.io/ferrum-edge/ferrum-foundry:v0.3.0Production quick start
Run Foundry only behind an identity-aware reverse proxy that removes
client-supplied identity headers and injects the trusted proxy proof:
export FERRUM_JWT_SECRET=$(openssl rand -hex 32)
export FERRUM_TRUSTED_PROXY_SECRET=$(openssl rand -hex 32)
docker run \
-e FERRUM_ADMIN_URL=https://your-gateway:9443 \
-e FERRUM_JWT_SECRET \
-e FERRUM_AUTH_MODE=trusted-proxy \
-e FERRUM_TRUSTED_PROXY_SECRET \
-p 127.0.0.1:8080:8080 \
ferrumedge/ferrum-foundry:v0.3.0Configure the proxy to send X-Ferrum-Auth-Secret,
X-Forwarded-User, X-Ferrum-Role, and exact
X-Ferrum-Namespaces grants. See
Production authentication.