Draft: feat: Introduce the authentication and security model for headless draft preview

Closes #3591775. First building block of the Canvas Headless milestone.

Adds the canvas_headless sub-module: it embeds a headless frontend in the Canvas editor frame and gives it draft content access through user-bound preview tokens, minted via the standard OAuth 2.0 JWT assertion grant (RFC 7523). The token is bound to the editing user and capped to a view-only permission ceiling; sessions renew from the live Drupal session, so logging out ends the preview. No secrets in the frontend; the only site configuration is the frontend URL.

The design and its alternatives are recorded in the diff itself: ADRs 0014–0016 (docs/adr/), a concept-level walkthrough of the auth design (docs/headless-preview-auth.md), and the module README (setup, operations, browser support, known limitations). Reviewers may want to start there.

Where to start in the diff

  • modules/canvas_headless — the module: assertion factory, the jwt_bearer grant, the view-only scope granularity, the minting endpoints, kernel tests.
  • packages/headless-host — framework-agnostic host side of the postMessage renewal/recovery protocol.
  • ui/src/features/layout/preview — the editor frame embeds the frontend and drives its draft session; the same-origin overlay is disabled for the cross-origin iframe.
  • modules/canvas_headless/examples/nextjs-app — reference frontend: draft SDK, host-protocol client, CE-API-rendered pages.

How to test

  1. Install canvas_headless (requires simple_oauth >= 6 with its keypair configured).
  2. Run the example app: cd modules/canvas_headless/examples/nextjs-app && cp .env.example .env.local && npm install && npm run dev.
  3. Grant access canvas headless preview to an editorial role. The shipped frontend_url default already points at the example app's dev server.
  4. Open an entity in the Canvas editor: the frontend loads in the editor frame with an active draft session, and unpublished content renders. Use a Chromium-based browser for the embedded flow on plain-http localhost.

Authored with an AI coding agent.

Merge request reports

Loading