Architecture · Static delivery + explicit runtime
Static WordPress with Dynamic Runtime on AWS
Keep public WordPress page delivery on S3 and CloudFront, then give each interactive feature its own browser-to-service runtime instead of returning the whole site to PHP and MySQL.
WordPress CMS ↓ Static Publisher S3 + CloudFront ├→ Gatey → Amazon Cognito ├→ Flow → workflow backend ├→ AI-Kit → configured AI / knowledge backend ├→ protected paths → signed access └→ application actions → protected APIs
Runtime boundary
Classify runtime per feature, not per site
Static describes how the page is delivered. It does not require login, forms, discussions, AI or application actions to disappear. Each capability can cross a separate runtime boundary only when the visitor uses it.
Public page request → CloudFront → static HTML/assets Login → browser → Cognito Protected static path → identity → signed access → CloudFront Form / draft / discussion → browser → Flow backend AI / DocSearch → browser → local mode or configured backend Application write → browser → authorized API
Trust boundary Frontend visibility is not authorization. Identity, protected-file access, form validation, AI access and API writes must each be enforced by the service that owns that responsibility.
Control plane versus runtime plane
This matrix separates editorial ownership from execution responsibility. It shows which concerns stay in WordPress and which move to browser or AWS runtime services once public page delivery is static.
| Responsibility | WordPress role | AWS/runtime role | Why this split matters |
|---|---|---|---|
| Content and layout | Editors build pages in Gutenberg and publish CPT content | Static delivery serves the rendered result | Editorial workflow remains familiar while public traffic avoids PHP. |
| Authentication UI | Page contains a Gatey block, shortcode or widget | Cognito handles sign-in, MFA, SSO and tokens | Login survives static export because it runs in the browser against Cognito. |
| Protected content | WordPress defines where protected sections live | CloudFront signed cookies enforce object access | Private static pages do not require WordPress sessions. |
| Forms and workflows | Form layout and workflow intent are edited in WordPress | Backend validates, stores, routes and triggers actions | Submission handling can scale separately from page delivery. |
| AI features | Blocks, chatbot placement, KB source selection and feature settings live in WP Admin | Model calls, RAG, guardrails and logging run in the AI backend | Content intelligence becomes a governed backend capability, not a PHP proxy. |
| Custom app features | WordPress renders buttons, containers and account-aware UI | API Gateway and Lambda enforce authorization and write state | The frontend can be static while the application stays interactive. |
Flow runtime boundary after the backend template
This table zooms in on Flow only. It separates visitor-facing routes, administrative routes and asynchronous workflow execution so teams can see why each responsibility sits outside the WordPress page request.
| Surface | Example routes | Runtime responsibility | Why it belongs outside PHP |
|---|---|---|---|
| Frontend forms | /frontend/forms/{formId}/submit, /drafts, /upload-url | Validate visitor input, accept drafts, receive payload references and trigger downstream processing. | The browser can submit from a static page while the backend owns validation, abuse controls and durability. |
| Admin operations | /admin/forms, /admin/submissions, /admin/templates, /admin/workflows, /admin/webhook-endpoints | Let WP Admin configure definitions, templates and workflows through protected management routes. | Administrative write operations can require Cognito/IAM, scopes and IP restrictions independently of public page delivery. |
| Workflow execution | EventBridge-triggered dispatchers for submissions, status changes, email and webhooks | Process work asynchronously and record events without holding open a page request. | Forms become reliable workflows, not one fragile synchronous WordPress POST. |
Runtime surface map
Use this matrix as a security and operations checklist after the feature boundaries are chosen. It maps each runtime surface to its typical authorization mode, primary risk and recommended enforcing boundary.
| Runtime surface | Typical auth mode | Example WP Suite component | Primary risk | Recommended boundary |
|---|---|---|---|---|
| Anonymous page view | None | Static Publisher output | Stale pages, listings or assets after a content change | Verified baseline, manifest ownership, completed CloudFront invalidation and public target verification. |
| Login/profile UI | Cognito public client | Gatey Authenticator and Account Attribute blocks | Misconfigured callback URLs or token assumptions | Cognito App Client, callback domain, token handling. |
| Protected static path | Cognito before cookie issuance | Static Site Guardian flow | Cookie scope, expiry, key rotation | CloudFront signed cookies and signer service. |
| Public form or AI call | NONE + reCAPTCHA/WAF or Cognito | AI-Kit frontend routes, Flow frontend form, draft and upload endpoints | Endpoint abuse and model/submission cost | Rate limits, validation, reCAPTCHA, WAF and quotas. |
| Member API call | Cognito JWT or IAM | Gatey-secured API access | Frontend visibility mistaken for authorization | API Gateway authorizer, scopes or IAM signatures. |
| Admin/backend operation | IAM or admin-only Cognito scopes | AI-Kit admin routes, KB operations | Leaking privileged operations to public users | Separate /admin route, stricter auth, IP allow list. |
API and cache design
The runtime split also changes delivery rules. This table turns the architecture into concrete choices for caching, API separation, CORS, state and user-visible failure handling.
| Design area | Good pattern | Bad pattern | Why it matters |
|---|---|---|---|
| Static HTML caching | Long-lived cache with deterministic invalidation after publish | Short cache everywhere because one component is dynamic | One dynamic widget should not force the whole page back into server mode. |
| API routes | Separate /frontend and /admin surfaces with different auth and throttling | One generic endpoint that does every action | Public widgets and privileged operations have different risk profiles. |
| CORS | Allow the exact static domains and environments that need browser access | Wildcard CORS plus credentialed requests | Static sites often have multiple hostnames; CORS must be deliberate. |
| Stateful widgets | Store session state in Cognito, DynamoDB, S3 temp objects or purpose-built backend state | Assume WordPress session state exists after export | The exported page has no PHP session on public requests. |
| Error handling | Components show actionable “auth required,” “try again,” or “not available” states | Static page silently fails when an API is blocked | The frontend becomes the user-visible runtime boundary. |
Implementation path
Separate delivery first, then add only the runtimes the site needs
The architecture is easier to operate when every dynamic requirement has an explicit owner and failure path.
- Keep WordPress as the editorial source — Build and review pages in WordPress, then publish cacheable page output through Static Publisher to S3 and CloudFront.
- Map interactive features to their service boundary — Use Cognito for identity, Flow for form and workflow state, AI-Kit for local or configured AI paths, signed access for protected static content, and dedicated APIs for application writes.
- Protect each runtime independently — Apply the appropriate authorization, validation, CORS, WAF, throttling or abuse controls at the service boundary instead of relying on a WordPress session or hidden frontend state.
- Test production as a browser application — Verify exported assets, callback URLs, CORS, authenticated and anonymous states, API failures and expired access after the site is served from its production domain.
When this architecture is the right boundary
Good fit
Mostly cacheable sites with selected live features
- The public site is primarily content, but users still need login, forms, discussions, AI or protected resources.
- You want WordPress to remain the familiar CMS without keeping PHP and MySQL in every public page request.
- Different runtime features need different security, scaling or ownership boundaries.
Choose another model
A different runtime may be simpler when
- Most pages require server-side personalization before they can be rendered.
- A separate frontend application is already a product requirement, making a headless architecture intentional rather than incidental.
- Traditional dynamic WordPress already solves the workload cleanly and separating runtime services adds no useful operational boundary.
Problem guides
Where to go from the architecture
How do I make WordPress static without losing dynamic features?
Start with Make WordPress Static Without Losing Dynamic Features. It maps login, forms, discussions, ratings, AI and protected content to explicit runtimes instead of treating static publishing as a feature ceiling.
How do I keep WordPress for editing without exposing it publicly?
See Keep WordPress for Editing Without Exposing WordPress Publicly for the editorial-origin and public-delivery split, then use this architecture to decide which browser runtimes remain live after publishing.
How can long forms and review workflows work after static publishing?
See Let Users Save a Long WordPress Form and Continue Later, Replace Email and Spreadsheet Approvals with a WordPress Workflow, and Build a WordPress Review Workflow with Forms, Discussion and Ratings for the Flow-specific problem paths backed by the event-driven workflow architecture.
How can login and protected content work without PHP sessions?
See Add Login to Static WordPress Without Bringing PHP Sessions Back for browser-side Cognito identity and the protected-static boundary, then use Secure Static WordPress with CloudFront Signed Cookies for the delivery mechanism.
Start from the buyer problem
Choose the runtime boundary from the feature you need to preserve
Use the problem guides to identify the required interaction first, then return to the architecture layer for the implementation and trust boundaries.
