Architecture Note: Secure Draft Preview in Ghost CMS
Ghost's draft preview feature relies on a stateless, token-signed endpoint that validates short-lived tokens, fetches drafts via the Admin API, and renders them with the live theme—keeping unpublished content secure.
11 Feb 2026, 14:45 UTC

Problem and Takeaway
When Ghost editors save a draft, they expect a preview link to show how the post will appear publicly before publishing. Traditional approaches often embed draft content in URLs or rely on session cookies, which can leak unpublished material or create permission gaps. The practical solution is a stateless, token-signed preview endpoint that validates a short-lived token, retrieves the draft via the Admin API, and renders it using the live theme—keeping draft content off client requests and preventing unauthorized access.
Requirements for a Safe Preview Endpoint
- The Admin API key must be stored securely and never transmitted to the client.
- Preview links must carry a signed token that expires quickly, typically 30 minutes by default.
- The endpoint must validate the token signature before performing any server-side work.
- Rendered output should match the live site's theme, ensuring visual consistency.
Smallest Suitable Design
A single HTTP route, such as GET /preview/:token, performs the following steps:
- Extract and verify the token using a signing secret held in an environment variable.
- If validation passes, decode the token to obtain the draft post ID.
- Fetch the draft via the Ghost Admin API, using the stored API key.
- Render the post body through Ghost's theme engine, producing HTML that mirrors a published post.
- Return the HTML in the response body, with caching headers disabled.
For example, the endpoint verifies the token signature, decodes the draft post ID, and issues a request to the Ghost Admin API to fetch the draft content for rendering.
Trust and Data Boundaries
The preview endpoint sits between the editor's draft screen and the public rendering pipeline. The only data that leaves the server is the signed token (non-secret by design) and the fully rendered HTML. The Admin API key never appears in HTTP responses or browser logs. Raw draft content, including any unpublished fields, is never sent to the client; only the theme-rendered HTML is delivered. This keeps the trust boundary at the server process, not the client.
Operational Checks
- Log every preview request, including the client IP, a hash of the token, and the HTTP response status.
- Set a per-IP rate limit (e.g., 30 requests per minute) to reduce the risk of denial-of-service attacks against the Admin API.
- Monitor logs for repeated validation failures, which may signal token leakage or abuse, and trigger alerts if a single IP exceeds the threshold within a rolling window.
Failure Modes
- Invalid or expired token: Returns HTTP 403 with a user-friendly message such as Preview link expired or invalid. No stack trace or internal details are included in the response.
- Admin API timeout or unavailability: Returns HTTP 503, indicating the preview service is temporarily unable to fetch the draft.
- Missing or unknown post ID: Returns HTTP 404, suggesting the draft cannot be located.
Each failure path returns plain-text or simple HTML messages that do not reveal the signing secret, API key, or file paths.
Conditions That Would Change This Design
- If preview traffic consistently exceeds the configured rate-limit thresholds, moving the endpoint to a dedicated microservice with its own token store and scaling parameters may be warranted.
- If Ghost updates the Admin API authentication model (for example, shifting from a single secret to per-integration keys), the token validation logic must be updated to match the new flow.
- If the organization requires audit trails that include draft content metadata, the design would need to persist minimal, redacted draft information alongside the preview request log.
Limitations and Verification
- The approach assumes the Ghost instance's theme engine renders draft and published posts identically; custom helpers or theme versions that differ could cause visual mismatches.
- Token signing secrets should be rotated regularly; long-lived secrets increase risk if preview URLs are captured in referrer logs or browser history.
- The Admin API key must be scoped to the minimum permissions needed for draft retrieval; a super-admin key should not be used for preview rendering.
- To verify the endpoint: generate a valid preview token using Ghost's token generation utility, request the preview URL with a valid token, confirm HTML is returned and matches the live post rendering, then request the same URL with an expired or malformed token and confirm a 403 response without stack traces. Check deployment environment variables to ensure the Admin API key is not present in application logs.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.