Skip to content

Client Preview Environments

Long-Lived Client Preview Environments Runbook

1. Purpose & Lifecycle Overview

This runbook defines the operational procedures for provisioning, validating, sharing, and deprovisioning Long-Lived Client Preview Environments in SiteSwarm.

Long-Lived Client Previews serve prospective clients and sales engineers who require a live, high-taste, interactive website prototype (apps/proto-* or client applications) to evaluate before signing contracts or beginning production migration.

Unlike short-lived engineering previews, Client Previews satisfy two concurrent invariants:

  1. Unblocked Prospect Storefront: External prospective clients can load and navigate the website without requiring corporate Cloudflare Zero Trust (Access) single sign-on credentials.
  2. Protected Admin & Mutation Perimeter: Administrative consoles (/admin*, /_emdash/admin*), internal tools, and sensitive mutation endpoints remain strictly gated behind Cloudflare Zero Trust Access or Staff Gate authentication, preventing unauthorized data tampering.
  3. Automated Search Crawler Blocking: Every HTTP response automatically carries X-Robots-Tag: noindex, nofollow headers to eliminate the risk of search engine indexing.

2. Ingress & Access Perimeter Matrix

Surface / Route Target Audience Access Policy Fail-Closed Behavior HTTP Status
Public Storefront (/, /about, /contact, /services, /menu) External Prospects & Sales Leads Public Ingress: Bypasses corporate IdP wall; serves directly from Worker N/A (Always allowed) 200 OK (with X-Robots-Tag: noindex)
Static Assets (/_astro/*, /assets/*, /favicon.*) Browsers, Prospect Devices Public Ingress: Cacheable edge assets N/A (Always allowed) 200 OK
Synthetic Health Probes (/api/health) CI Blacksmith Runners, Monitoring Public Ingress: Edge health attestation N/A (Always allowed) 200 OK
Administrative Consoles (/admin, /admin/*, /_emdash/admin/*) SiteSwarm Staff & Authorized Admins Zero Trust Required: Requires Cf-Access-Jwt-Assertion or staff credentials Redirect to IdP: Redirects to https://siteswarm.cloudflareaccess.com 302 Found
Administrative APIs (POST /api/admin/*, /_emdash/api/*) SiteSwarm Staff & Authorized Admins Zero Trust Required: Requires Cf-Access-Jwt-Assertion or staff credentials Challenge: Returns JSON error challenge 401 Unauthorized
Internal Staging (*-staging.<platform-domain>) Internal Developers & QA Strict Zero Trust: 100% of all paths gated Redirect to IdP: Redirects to https://siteswarm.cloudflareaccess.com 302 Found

3. Hostname Conventions & Universal SSL Compliance

Per CLOUDFLARE_FOR_PLATFORMS_AND_DOMAIN_INGRESS.md, standard Universal SSL certificates cover only single-level wildcards (*.<platform-domain>).

To prevent SSL certificate validation failures and avoid paid add-ons:

  1. Platform Zone Subdomain: <app>-preview.jacobmiller22.com (single-level hyphenated subdomain matching *.jacobmiller22.com).
  2. Dedicated Preview Domain: <app>.preview.jacobmiller22.com (single-level subdomain under the dedicated preview zone).

4. Provisioning a Client Preview Environment

Option A: Via GitHub Pull Request (Agent / Developer Workflow)

  1. Add the label client-preview or proto-preview to the target Pull Request.
  2. The .github/workflows/client-preview-deploy.yml pipeline triggers automatically, builds the application, and deploys <app>-client-preview to Cloudflare.
  3. The preview persists indefinitely across PR updates and after PR close (it is ignored by .github/workflows/preview-teardown.yml).

Option B: Via GitHub Actions Workflow Dispatch (Sales / Ops Workflow)

  1. Navigate to Actions $\to$ Client Preview Deployment in GitHub.
  2. Click Run workflow:
    • apps: Specify the target app slug (e.g., bakery, software-agency, or proto-lumina).
    • domain: Leave default (jacobmiller22.com) or specify custom platform zone.
    • decommission: false.
  3. The deployment deploys the worker and outputs the active preview URL.

5. Verification Protocol (Behavioral Runtime Proof)

Before sharing a preview URL with prospective clients, execute the following runtime verification commands:

Step 1: Verify Public Storefront Accessibility & NoIndex Header

Execute curl -I against the public preview root:

Terminal window
curl -I https://bakery-preview.jacobmiller22.com/

Expected Response:

  • Status: HTTP/2 200 (or HTTP/1.1 200 OK)
  • Header: X-Robots-Tag: noindex, nofollow
  • No Location: ...cloudflareaccess.com header (must NOT redirect to Zero Trust login).

Step 2: Verify Administrative Perimeter Fail-Closed Gating

Execute curl -I against the administrative endpoint:

Terminal window
curl -I https://bakery-preview.jacobmiller22.com/admin

Expected Response:

  • Status: HTTP/2 302 (or HTTP/1.1 302 Found)
  • Header: Location: https://siteswarm.cloudflareaccess.com/cdn-cgi/access/login?...
  • Zero administrative content leaked unauthenticated.

Step 3: Verify Internal Staging Gating Invariant

Execute curl -I against internal staging to verify client preview routing has not weakened staging security:

Terminal window
curl -I https://bakery-staging.jacobmiller22.com/

Expected Response:

  • Status: HTTP/2 302
  • Header: Location: https://siteswarm.cloudflareaccess.com/cdn-cgi/access/login?...

6. Decommissioning & Cleanup

When client evaluation concludes, or when a prototype is successfully promoted into a client tenant workspace:

  1. Navigate to Actions $\to$ Client Preview Deployment.
  2. Run workflow with:
    • apps: <app-slug>
    • decommission: true
  3. The pipeline deletes the <app>-client-preview Cloudflare Worker and detaches its custom domain route.