Skip to content

feat(csp): allow chat UI to be embedded in iframes#3643

Merged
waleedlatif1 merged 2 commits intostagingfrom
waleedlatif1/chat-iframe-csp
Mar 18, 2026
Merged

feat(csp): allow chat UI to be embedded in iframes#3643
waleedlatif1 merged 2 commits intostagingfrom
waleedlatif1/chat-iframe-csp

Conversation

@waleedlatif1
Copy link
Collaborator

@waleedlatif1 waleedlatif1 commented Mar 18, 2026

Summary

  • Adds getChatEmbedCSPPolicy() in csp.ts mirroring the existing form embed pattern, setting frame-ancestors: * to allow cross-origin iframe embedding
  • Adds /chat/:path* headers block in next.config.ts with no X-Frame-Options, permissive COEP/COOP, matching the form embed configuration
  • Updates proxy.ts to early-return for /chat/ routes (CSP applied via next.config.ts headers, not middleware)
  • Fixes catch-all CSP regex to properly exclude /chat/* routes (was chat$ which only matched /chat exactly)

Context

Users reported that embedding the built-in chat UI within an iframe is not possible due to CSP restrictions (frame-ancestors: 'self' and X-Frame-Options: SAMEORIGIN). Form embeds already support this — this PR applies the same pattern to chat.

Test plan

  • Verify chat pages load normally at /chat/<id>
  • Verify chat pages can be embedded in an iframe from a different origin
  • Verify form embeds still work as before
  • Verify workspace/login pages still have strict CSP (frame-ancestors: 'self')

Mirror the existing form embed CSP pattern for chat pages: add
getChatEmbedCSPPolicy() with frame-ancestors *, configure /chat/:path*
headers in next.config.ts without X-Frame-Options, and early-return in
proxy.ts so chat routes skip the strict runtime CSP.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@cursor
Copy link

cursor bot commented Mar 18, 2026

You have used all Bugbot PR reviews included in your free trial for your GitHub account on this workspace.

To continue using Bugbot reviews, enable Bugbot for your team in the Cursor dashboard.

@vercel
Copy link

vercel bot commented Mar 18, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Mar 18, 2026 0:11am

Request Review

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Mar 18, 2026

Greptile Summary

This PR enables the built-in chat UI (/chat/:id) to be embedded in cross-origin iframes by applying the same CSP relaxation pattern already used for form embeds. It adds getChatEmbedCSPPolicy(), a dedicated next.config.ts header block for /chat/:path* (omitting X-Frame-Options, setting frame-ancestors: *, and using permissive COEP/COOP), updates the middleware to early-return for chat routes without re-applying a stricter CSP, and fixes a pre-existing regex bug (chat$chat) in the catch-all header rule that was incorrectly applying strict framing headers to all /chat/* sub-paths.

Key changes:

  • getChatEmbedCSPPolicy() added in csp.ts — mirrors getFormEmbedCSPPolicy() exactly; both functions are identical and could be unified into a shared helper
  • /chat/:path* header block in next.config.ts correctly omits X-Frame-Options and sets frame-ancestors: *; headers are ordered so the later chat-specific COEP/COOP (unsafe-none) override the earlier general rule (credentialless / same-origin)
  • Catch-all regex fix (chat$chat) is correct and closes a real bug where /chat/anything was receiving X-Frame-Options: SAMEORIGIN before this PR
  • Bare /chat (no trailing slash or sub-path) falls into a header gap: it is excluded from the strict catch-all by the new regex but is not matched by /chat/:path* — if /chat is a real route it will have no Content-Security-Policy from next.config.ts or middleware

Confidence Score: 4/5

  • Safe to merge — mirrors a proven pattern and fixes a real CSP bug; two minor style/coverage issues but no regressions
  • The implementation faithfully replicates the existing form-embed approach, the catch-all regex fix is correct, and the middleware change is clean. The two items worth watching are: (1) getChatEmbedCSPPolicy being a duplicate of getFormEmbedCSPPolicy, which is a code quality concern but not a runtime bug; and (2) the bare /chat path receiving no CSP header — negligible in practice if /chat isn't a real page, but worth confirming.
  • apps/sim/next.config.ts — verify whether a bare /chat route exists and whether the header gap matters; also note header ordering between the general COEP rule and the new /chat/:path* block.

Important Files Changed

Filename Overview
apps/sim/lib/core/security/csp.ts Adds getChatEmbedCSPPolicy(), mirroring getFormEmbedCSPPolicy() exactly — same buildTimeCSPDirectives spread with frame-ancestors: ['*']. Functionally correct but duplicated; could share a private helper.
apps/sim/next.config.ts Adds a /chat/:path* header block (no X-Frame-Options, permissive COEP/COOP, embed CSP) and fixes the catch-all regex from chat$ to chat, correctly excluding all /chat/* paths from the strict fallback policy. Bare /chat (no sub-path) is now in a header gap — not covered by either the embed block or the catch-all.
apps/sim/proxy.ts Adds a clarifying comment to the existing /chat/ early-return and removes /chat from the middleware CSP-injection block, correctly deferring CSP responsibility to next.config.ts headers. Clean change with no logic issues.

Sequence Diagram

sequenceDiagram
    participant Browser as Browser (3rd-party origin)
    participant Middleware as Next.js Middleware (proxy.ts)
    participant Config as next.config.ts Headers
    participant ChatPage as /chat/:id Page

    Browser->>Config: GET /chat/abc123
    Config-->>Browser: Content-Security-Policy: frame-ancestors *<br/>Cross-Origin-Embedder-Policy: unsafe-none<br/>Cross-Origin-Opener-Policy: unsafe-none<br/>(no X-Frame-Options)
    Browser->>Middleware: request reaches proxy()
    Middleware-->>Browser: NextResponse.next() — no CSP override
    Middleware->>ChatPage: render chat UI
    ChatPage-->>Browser: HTML response (embeddable in iframe)

    Note over Browser,ChatPage: Before this PR: catch-all added X-Frame-Options: SAMEORIGIN<br/>and middleware set frame-ancestors 'self' → embedding blocked<br/>After this PR: both restrictions lifted for /chat/* routes
Loading

Last reviewed commit: "feat(csp): allow cha..."

Deduplicate getChatEmbedCSPPolicy and getFormEmbedCSPPolicy into a
shared private helper to prevent future divergence.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@waleedlatif1 waleedlatif1 merged commit c9f082d into staging Mar 18, 2026
6 checks passed
@waleedlatif1 waleedlatif1 deleted the waleedlatif1/chat-iframe-csp branch March 18, 2026 00:12
waleedlatif1 added a commit that referenced this pull request Mar 18, 2026
* fix(mothership): fix mothership file uploads (#3640)

* Fix files

* Fix

* Fix

* fix(workspace): prevent stale placeholder data from corrupting workflow registry on switch

* feat(csp): allow chat UI to be embedded in iframes (#3643)

* feat(csp): allow chat UI to be embedded in iframes

Mirror the existing form embed CSP pattern for chat pages: add
getChatEmbedCSPPolicy() with frame-ancestors *, configure /chat/:path*
headers in next.config.ts without X-Frame-Options, and early-return in
proxy.ts so chat routes skip the strict runtime CSP.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(csp): extract shared getEmbedCSPPolicy helper

Deduplicate getChatEmbedCSPPolicy and getFormEmbedCSPPolicy into a
shared private helper to prevent future divergence.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* fix(logs): add durable execution diagnostics foundation (#3564)

* fix(logs): persist execution diagnostics markers

Store last-started and last-completed block markers with finalization metadata so later read surfaces can explain how a run ended without reconstructing executor state.

* fix(executor): preserve durable diagnostics ordering

Await only the persistence needed to keep diagnostics durable before terminal completion while keeping callback failures from changing execution behavior.

* fix(logs): preserve fallback diagnostics semantics

Keep successful fallback output and accumulated cost intact while tightening progress-write draining and deduplicating trace span counting for diagnostics helpers.

* fix(api): restore async execute route test mock

Add the missing AuthType export to the hybrid auth mock so the async execution route test exercises the 202 queueing path instead of crashing with a 500 in CI.

* fix(executor): align async block error handling

* fix(logs): tighten marker ordering scope

Allow same-millisecond marker writes to replace prior markers and drop the unused diagnostics read helper so this PR stays focused on persistence rather than unread foundation code.

* fix(logs): remove unused finalization type guard

Drop the unused  helper so this PR only ships the persistence-side status types it actually uses.

* fix(executor): await subflow diagnostics callbacks

Ensure empty-subflow and subflow-error lifecycle callbacks participate in progress-write draining before terminal finalization while still swallowing callback failures.

---------

Co-authored-by: test <test@example.com>
Co-authored-by: Vikhyath Mondreti <vikhyath@simstudio.ai>

* feat(admin): add user search by email and ID, remove table border

- Replace Load Users button with a live search input; query fires on any input
- Email search uses listUsers with contains operator
- User ID search (UUID format) uses admin.getUser directly for exact lookup
- Remove outer border on user table that rendered white in dark mode
- Reset pagination to page 0 on new search

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(admin): replace live search with explicit search button

- Split searchInput (controlled input) from searchQuery (committed value)
  so the hook only fires on Search click or Enter, not every keystroke
- Gate table render on searchQuery.length > 0 to prevent stale results
  showing after input is cleared

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Siddharth Ganesan <33737564+Sg312@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: PlaneInABottle <y.mirza.altay@gmail.com>
Co-authored-by: test <test@example.com>
Co-authored-by: Vikhyath Mondreti <vikhyath@simstudio.ai>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant