Skip to content

390: Allow same-origin iframe embedding for admin previews - #418

Merged
turegjorup merged 1 commit into
feature/update-infrastructure-for-mono-repofrom
feature/390-iframe-preview
Apr 30, 2026
Merged

390: Allow same-origin iframe embedding for admin previews#418
turegjorup merged 1 commit into
feature/update-infrastructure-for-mono-repofrom
feature/390-iframe-preview

Conversation

@turegjorup

Copy link
Copy Markdown
Contributor

Closes #390.

Summary

The admin embeds the client via iframe to render screen/playlist previews and the fullscreen slide view. The nginx template was sending X-Frame-Options: DENY, so browsers refused to render the embedded iframe — exactly the failure shown in the issue's screenshot.

Fix

Two-header approach in infrastructure/nginx/etc/templates/default.conf.template:

add_header Content-Security-Policy "frame-ancestors 'self'" always;
add_header X-Frame-Options "SAMEORIGIN" always;
  • Content-Security-Policy: frame-ancestors 'self' — the modern primary control. CSP Level 2+ is honored by every current browser and supersedes X-Frame-Options when both are present.
  • X-Frame-Options: SAMEORIGIN — defense-in-depth for any pre-CSP-2 browser.

Both restrict iframe embedding to the same origin, which matches the docker-server compose layout where admin and client are served by the same nginx on the same hostname.

The Content-Security-Policy header here only sets frame-ancestors; it does not activate any other CSP rules and so doesn't risk breaking inline scripts or eval. Future CSP work can extend this header with additional directives without disturbing the iframe rule.

Local validation

Built the nginx image from this branch and confirmed both headers are present in the rendered config:

$ docker run --rm --entrypoint sh local/display-api-service-nginx:390-test \
    -c '/docker-entrypoint.sh nginx -V >/dev/null 2>&1; grep -E "frame-ancestors|X-Frame-Options" /etc/nginx/conf.d/default.conf'
    add_header Content-Security-Policy "frame-ancestors 'self'" always;
    add_header X-Frame-Options "SAMEORIGIN" always;

Test plan

  • Rebuild nginx image; deploy or run locally.
  • Open admin → screen detail → confirm preview iframe renders without "refused to display in a frame" browser console error.
  • Open admin → playlist preview → same check.
  • Open a slide → fullscreen view → same check.
  • curl -I against any page response shows both Content-Security-Policy: frame-ancestors 'self' and X-Frame-Options: SAMEORIGIN.

🤖 Generated with Claude Code

The admin embeds the client via iframe to render screen/playlist
previews and the fullscreen slide view. With X-Frame-Options: DENY,
the browser refused to render the iframe.

Switch to frame-ancestors 'self' (CSP Level 2+, the modern control)
and SAMEORIGIN as defense-in-depth for older browsers.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@turegjorup
turegjorup requested a review from tuj April 30, 2026 08:50
@turegjorup turegjorup self-assigned this Apr 30, 2026
@turegjorup turegjorup added this to the 3.0.0 milestone Apr 30, 2026
@turegjorup turegjorup added the bug Something isn't working label Apr 30, 2026
@turegjorup
turegjorup merged commit 21ba755 into feature/update-infrastructure-for-mono-repo Apr 30, 2026
18 checks passed
@turegjorup
turegjorup deleted the feature/390-iframe-preview branch April 30, 2026 11:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants