Add same-origin MFE artifact delivery endpoint
What does this MR do and why?
Serves baked MFE assets at /-/mfe/:name/:version/*path as public immutable artifacts, so browsers never contact the upstream registry and the CSP needs no new origins:
Mfe::ArtifactsController— no auth (BaseActionController), Content-Type allow-list,nosniff, immutableCache-Control, X-Sendfile. No session, no database access on the serve path.
The dev-mode proxy for local development moved to its own MR: !245301 (closed).
How to verify
bin/rspec spec/requests/mfe/artifacts_spec.rbEnd-to-end with a real application (baked Duo Chat)
Bake the real Duo Chat MFE first, exactly as described in the bake MR (!245045 (closed), "Bake a real application"): pin it in config/mfe.yml and run the bake — no configuration needed, registry reads are anonymous:
apps:
- name: duo_chat
project: gitlab-org/frontend/gitlab-mfe
version: 0.2.0
manifest_sha256: 13a8f610c44190e6cbead9e7ba2b48316677479a1e682fc894ed1c1c669eb38dbin/rake gitlab:mfe:bakeThen enable delivery — unlike the bake, the serving endpoint is double-gated:
# gitlab.yml (GDK: gdk.yml → gitlab section, or edit config/gitlab.yml)
mfe:
enabled: true# rails console
Feature.enable(:mfe_enabled)And verify the delivery behavior:
# 200 with the delivery headers: immutable public Cache-Control,
# X-Content-Type-Options: nosniff, correct Content-Type from the allow-list
curl -sI http://gdk.test:3000/-/mfe/duo_chat/0.2.0/mf-manifest.json | grep -iE "^HTTP|cache-control|content-type|nosniff"
# a real JS chunk from the 211-file tree is served the same way
curl -sI http://gdk.test:3000/-/mfe/duo_chat/0.2.0/remoteEntry.js | grep -iE "^HTTP|content-type"
# unknown version, unknown app, traversal attempts: 404
curl -s -o /dev/null -w "%{http_code}\n" http://gdk.test:3000/-/mfe/duo_chat/9.9.9/mf-manifest.json
curl -s -o /dev/null -w "%{http_code}\n" http://gdk.test:3000/-/mfe/nope/0.2.0/mf-manifest.json
# the whole endpoint disappears behind the kill switch
# (disable the feature flag or set mfe.enabled: false -> 404)No session cookie is needed for any of these requests, and no SQL is executed on the serve path (spec/requests/mfe/artifacts_spec.rb asserts the zero-query property).
Stack
This is part of a stacked series extracted from a single 1700+ line MR for reviewability. Each part is independently verifiable and leaves master inert: nothing is user-reachable until an application is pinned.
| # | Scope | MR |
|---|---|---|
| 1 | Config plumbing + instance kill switch | !245043 (closed) |
| 2 | Sidecar manifest validation + pin-file catalog | !245044 (closed) |
| 3 | Verified bake task + baked manifest | !245045 (closed) |
| 4 | Same-origin delivery endpoint | !245046 (closed) |
| 5 | Dev-mode proxy for local development | !245301 (closed) |
Merging bottom-up; when a part merges, GitLab retargets the next one to master automatically.
A separate demonstration MR shows the whole stack working end to end with the real Duo Chat MFE (production bake + dev-mode HMR): !245014.
Related
- Phase 1 issue: #605798
- Epic: gitlab-org#22777
Related to #605798.