MFE monolith-side: verified delivery foundation (registry pin, bake, same-origin serving)
Everyone can contribute. Help move this issue forward while earning points, leveling up and collecting rewards.
Context
Phase 1 of gitlab-org#22777 (runtime UI composition platform): the verified delivery foundation — everything required for a composable UI application to travel from a package registry into the monolith as versioned, integrity-verified, same-origin assets. Nothing is user-reachable until an app is pinned and the flags are enabled; every piece is independently verifiable.
What Phase 1 delivers
Operator control
MFE delivery is off by default and requires two switches to be on: a static instance setting (the operator's kill switch, immune to runtime state) and a feature flag (gradual rollout). The registry source — which GitLab instance and group publish the applications — is instance configuration; an access token is only needed for private sources, and secrets never appear in request logs.
Integrity contract
Every published application version carries a manifest describing itself completely: its name and version, the runtime it was built with, the host capabilities it requires, and a digest of every file it ships. Incomplete or malformed manifests are rejected outright — an application that cannot fully describe itself cannot be delivered.
Why a sidecar format
Module Federation builds already emit a manifest (mf-manifest.json), but that file belongs to the toolchain: its schema is owned by the bundler ecosystem, changes with toolchain versions, and is consumed by the federation runtime — and it carries no integrity information at all. We deliberately never touch it. Instead every application publishes a small GitLab-owned sidecar (gitlab-mfe-manifest.json, with its own schema version) alongside it, carrying exactly what the toolchain manifest cannot:
- Integrity — a digest of every shipped file, so the import step can prove that what a release serves is byte-for-byte what was published. The release pin stores a single digest — the sidecar's own — which transitively covers the whole file tree: one hash committed to git vouches for every byte an application ships.
- Compatibility — which federation runtime the application was built with and which host capabilities it requires, validated before activation instead of discovered in production.
- Stability — a schema we own and evolve deliberately, decoupled from bundler upgrades.
Prior art: Zephyr Cloud, a deployment platform from the Module Federation ecosystem, uses the same technique — its deploy metadata hashes every asset. The goals it achieves with that are the ones we care about too: verifiable integrity of served assets, immutable versioned deploys with instant rollback, and content-addressed storage (only changed files need re-uploading — an optimization our per-file digests keep open for later). We didn't adopt Zephyr's format itself because it is coupled to their platform's deploy and edge model; the sidecar pursues the same goals in a minimal schema under our control.
Release pinning
Each monolith release declares, in a committed lockfile, the exact application versions it ships. The pin includes the manifest digest, so what was published is provably what gets delivered. An empty pin list is a clean no-op everywhere — the platform stays inert until someone pins an app.
Verified import ("bake")
A release-build step downloads every pinned application from the registry and verifies every file against its pinned digest before anything is written. Any mismatch — one byte, one file — fails the entire step loudly; there is no partial success, so browsers can never observe partially- or un-verified assets. The step needs no database, so it runs during CI asset builds.
Same-origin serving
Browsers receive MFE assets from GitLab's own origin at versioned, immutable, publicly cacheable URLs. They never contact the upstream registry, the CSP needs no new origins, and the behavior is identical on GitLab.com, self-managed, and air-gapped installs. Anything not baked — unknown app, unknown version, unexpected file type — is simply not found.
Local development
In GDK a developer can route any application to a local dev server with hot reload — several applications simultaneously — using a magic dev version, without touching the production delivery path.
Merge order (stacked, bottom-up)
| # | MR | Scope |
|---|---|---|
| 1 | !245043 (closed) | Instance configuration + kill switch |
| 2 | !245044 (closed) | Application manifest validation + release pin file |
| 3 | !245045 (closed) | Verified import (bake) |
| 4 | !245046 (closed) | Same-origin serving |
| 5 | !245301 (closed) | Local development mode (dev proxy, HMR) |
When a part merges, GitLab retargets the next one to master automatically.
A separate demonstration MR (excluded from the mergeable stack) pins the real Duo Chat MFE and shows both the production path (bake + same-origin serving) and the development path (dev proxy + HMR): !245014.
Verification
- Each MR carries its own test suite and a "How to verify" section.
- End to end (with MR 5): the bake step downloads and digest-verifies a real published application; the browser receives it same-origin with immutable caching; tampering with the pinned digest makes the bake fail loudly; unknown versions are not served; a locally-served app hot-reloads in GDK.
Out of scope (follow-ups within the epic)
- The host-side loading of delivered applications and the mount-contract developer documentation — separate MRs.
- Publishing a new version without a monolith release (caching, admin activation, verified prefetch) — Phase 2.