Skip to content

Ferrum Foundry v0.2.0

Choose a tag to compare

@github-actions github-actions released this 25 Sep 10:51
· 90 commits to main since this release
c028c23

Ferrum Foundry v0.2.0

This is the first Foundry release qualified against an explicit Ferrum Edge
release: Ferrum Edge v0.9.7. It is intended for a supervised early-access
deployment
: one gateway, a small number of administrators, the documented
identity-proxy topology. It makes no compatibility promise for other Edge
releases or for earlier Foundry development builds. Changes since
v0.1.0:
git log v0.1.0..v0.2.0.

Supported pairing

Foundry v0.2.0 — ferrumedge/ferrum-foundry:v0.2.0, linux/amd64 and linux/arm64. Deploy it by the multi-architecture digest this release's run publishes
Ferrum Edge Ferrum Edge v0.9.7 — ferrumedge/ferrum-edge@sha256:4c9530e09443649526dc4fbbec0720ba7b47ceb91b0dd5cb06db85430908874a, commit 8fed1346ce2e267eb69c03683cb89ea44d785e0b; linux/amd64 sha256:e4d4367e815e86f510c28d8f831ca3502b7c9d5f21fd0eeabeb609a8c8e6f47f, linux/arm64 sha256:7d3d28d2529dfb6a303b734fad0bf35ebec07caa95f5632e81d92170baf15fab
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 #439, which moved the pin to v0.9.7, 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. 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.7-ebpf variants. The full envelope, including
tested scale, is in
docs/compatibility.md.

Highlights since v0.1.0

Safer writes

  • Full-replacement saves of proxies, upstreams, upstream targets, consumers,
    and plugin configurations, and deletes from their detail pages, are refused
    when the resource changed since the editor opened, instead of silently
    reverting another administrator's change. The draft is kept and shown against
    the current gateway content, with secrets redacted at every depth. There is
    no "save anyway" and nothing is re-sent automatically (#381).
  • Against Ferrum Edge v0.9.7 those writes are atomic: the guard sends the
    ETag of its verification read as If-Match (ferrum-edge#5661), so a writer
    that commits between that read and the write is refused with 412 and
    nothing is written.
  • A write whose outcome Foundry could not observe (a lost response, a timeout,
    a dropped connection) is reported as an unknown outcome and never replayed;
    reads are retried only when safe. A 503 Edge returns for a write it
    committed but has not yet applied is reported as saved, not as a failure.
  • A proxy-scoped plugin created through the UI is verified to be attached to
    its proxy, and attached when the gateway left it unattached. Ferrum Edge
    0.9.x attaches it on create; the proxy write that does so is never mistaken
    for a concurrent edit.
  • The upstream form refuses an active health-check path that does not start
    with / and a UDP probe payload that is not whole hex bytes, which Ferrum
    Edge v0.9.7 no longer accepts.

Truthful reads

  • A failed or unavailable read is distinguishable from an empty collection
    across policy, trust, mesh, dashboard, audit, and API-spec views, and editors
    keep unsaved fields through failed background reads.
  • A read the gateway refuses to the session's role (for example TLS inventory
    for a viewer) is shown as a denial, never as an empty store.
  • Ordinary navigation is bounded: the proxy list fetches one page instead of
    whole collections, and TLS and ACME collections fetch one server page (#382).
  • A proxy's Plugins tab shows the proxy-scoped plugins that name it but do not
    run on it — disabled, or not attached — from Ferrum Edge v0.9.7's
    GET /plugins/config?proxy_id= filter (ferrum-edge#5726), which costs that
    proxy's configurations rather than the namespace.

Access and tenancy

  • A client-side capability model presents surfaces a role or a read-only
    gateway cannot write as read-only, with the reason visible before anything
    is edited. CI checks that model against the pinned gateway as every role,
    writable and read-only.
  • Every gateway request is bound to the namespace its operation started in;
    editors are bound to namespace and resource so a tenant switch cannot submit
    stale fields.

Operating Foundry

  • A maintained deployment starter (deploy/starter/) with a production and a
    disposable demo profile, a preflight that reports unknowns honestly, and a
    first-success walkthrough (#384).
  • A critical-journey release gate: a real browser against the production image,
    the identity proxy, and the pinned gateway, finishing with data-plane
    requests (#380).
  • Guided configuration for key_auth, rate_limiting, cors, and
    prometheus_metrics, lossless against the raw JSON editor (#383).
  • Proxied uploads are bounded by an absolute deadline
    (FERRUM_UPLOAD_TIMEOUT) and a global in-flight cap
    (FERRUM_MAX_ACTIVE_UPLOADS).

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 no ETag, so a
    write verified against it is sent without If-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.7, 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:4c9530e09443649526dc4fbbec0720ba7b47ceb91b0dd5cb06db85430908874a
docker pull ferrumedge/ferrum-foundry:v0.2.0   # then pin the digest it resolves to
  • New deployment: follow Getting started
    with the starter, then Deployment
    for the production checklist. Set FOUNDRY_IMAGE to the Foundry digest; the
    starter's default (:main) is the development channel.
  • FERRUM_JWT_SECRET must equal the gateway's FERRUM_ADMIN_JWT_SECRET, and
    FERRUM_JWT_AUDIENCE its FERRUM_ADMIN_JWT_AUDIENCE.

Upgrading from v0.1.0

Foundry keeps no persistent state of its own, so an upgrade is an image
replacement. v0.1.0 was published during buildout and is not supported; there
is no migration and no compatibility promise between the two.

  1. Move the gateway to Ferrum Edge v0.9.7 first, following Ferrum Edge's own
    upgrade guide
    ("Upgrading to 0.9.7"): run ferrum-edge validate against the production
    configuration, because several settings v0.9.5 accepted now refuse to start.
    Foundry is not qualified against the gateway you ran with v0.1.0.
  2. Review new BFF settings in docs/deployment.md (FERRUM_UPLOAD_TIMEOUT,
    FERRUM_MAX_ACTIVE_UPLOADS); their defaults are safe.
  3. Replace the Foundry image with the release digest and confirm
    GET /api/health/ready reports version 0.2.0 and a reachable gateway.
  4. Reload open browser tabs so they run the new SPA bundle.

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.1.0 is not qualified against Ferrum Edge v0.9.7.
  • 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_SECRET and FERRUM_JWT_AUDIENCE still match the gateway
    after any rollback.

Docker

docker pull ferrumedge/ferrum-foundry:v0.2.0
docker pull ghcr.io/ferrum-edge/ferrum-foundry:v0.2.0

Production 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.2.0

Configure the proxy to send X-Ferrum-Auth-Secret,
X-Forwarded-User, X-Ferrum-Role, and exact
X-Ferrum-Namespaces grants. See
Production authentication.