SSR branding runbook
Owner: LEMN UI and consuming-app maintainers
Last reviewed: 2026-07-17
Patterns: PAT-UI-BRAND-CONTRACT-001, PAT-UI-SSR-BRANDING-001,
PAT-SEC-SECRETS-001, PAT-TEST-EVIDENCE-001
Invariant
Section titled “Invariant”A production browser must never render an unbranded component or raw provider
default. Resolve, authorize, verify, and inject one published
BrandingVersion mode before emitting the first HTML byte. Hydration confirms
the exact signed projectionHash, mode ID, and mode hash; it never repairs
branding after paint.
Trusted inputs
Section titled “Trusted inputs”The server derives the Workspace from authenticated workload configuration or
routing owned by the application. A browser-supplied Workspace ID is not
authority. Mode selection is allowed only when the signed mode projections
declare it selectable. A same-account Cloudflare host uses an RPC Service
Binding to a dedicated WorkerEntrypoint. Deployment-owned static ctx.props
authenticate the exact workspaceId, consumerId, and branding:resolve
permission; no credential or browser-selected Workspace travels in the RPC
call. An external server instead uses authenticated HTTPS with a
least-privilege WorkspaceRuntimeCredential kept only on the server.
MCP credentials, source definitions, reusable runtime credentials, and R2 credentials never reach the browser.
Response algorithm
Section titled “Response algorithm”- Derive the trusted Workspace and requested allowed mode.
- Resolve through
@lemn-ltd/brand-runtimewith a strict deadline. - Verify the strict envelope, canonical
projectionHash, signature, definition/compiled/mode hashes, schema/compiler, signed Workspace and publication identity, public asset references, and expiry where applicable. - Read critical CSS, preloads, safe assets, and the minimal bootstrap only from that verified mode projection.
- Emit preloads and critical style in
<head>before branded markup. - Apply every compiled HTML attribute to the branded scope.
- Embed the escaped non-executable bootstrap.
- Render components inside that scope and hydrate only when the projection hash and mode identity match exactly.
import { createServiceBindingBrandingRuntimeClient, resolveBranding,} from "@lemn-ltd/brand-runtime";import { assertBrandingHydrationIdentity, createBrandingSsrParts,} from "@lemn-ltd/brand-runtime/server";
const branding = await resolveBranding({ // This identity is trusted host configuration and is also verified against // the response. The RPC binding derives authority from its static ctx.props. workspaceId: WORKSPACE_ID, modeId: requestedMode, client: createServiceBindingBrandingRuntimeClient({ binding: env.BRANDING_RUNTIME, }), verifier: verifyWithPinnedPublicKey, embeddedFallback, allowedAssetOrigins: ["https://assets.ui.le-mn.com"], timeoutMs: 1500,});
const ssr = createBrandingSsrParts(branding, { nonce });// Apply ssr.htmlAttributes, append ssr.headMarkup before app markup,// and emit ssr.bootstrapMarkup as non-executable JSON.assertBrandingHydrationIdentity( ssr.hydrationIdentity, JSON.parse(clientBootstrapText),);The RPC binding exposes only resolveBranding, exchangeBrandingPreview, and
resolveBrandingPreview. It is not an anonymous Fetcher, does not call the
HTTP routes, and does not receive a reusable runtime credential. Use
createHttpsBrandingRuntimeClient only for an external server and provide its
WorkspaceRuntimeCredential from server secret/configuration storage.
Use exact releases:
pnpm add @lemn-ltd/brand-contract@1.0.0 @lemn-ltd/brand-runtime@0.1.1 @lemn-ltd/ui@0.4.0Active fallback
Section titled “Active fallback”Every release embeds an exact map of compatible, Workspace-bound, independently signed minimal mode projections exported by AgentOps. The complete private compiled object is not embedded. Before resolving active branding, the runtime verifies every fallback projection and requires identical publication identity, hashes, default mode, and allowed mode set. Active resolution order is deliberately bounded:
- current verified active runtime object;
- verified embedded branded fallback;
- fail closed with an explicitly branded unavailable response.
There is no second mutable cache or recovery authority. A timeout, invalid response, incompatible compiler, failed signature, or hash mismatch must emit sanitized fallback telemetry. Never use source JSON, generic KV, provider defaults, or package fallback tokens as production recovery.
Preview
Section titled “Preview”A hosted/local preview is pinned to an exact definition hash and uses a
short-lived, session-bound, one-use handoff. The clean browser URL contains no
credential and browser storage contains no reusable secret. Preview resolution
is no-store; expiry, revocation, or mismatch renders an explicit preview
unavailable state. It never silently falls back to active branding.
Fonts, assets, and CSP
Section titled “Fonts, assets, and CSP”Emit only the verified selected mode’s managed font preloads. Add exact font and public asset origins from its signed projection to CSP; require immutable URLs, signed SHA-256/SRI metadata, correct CORS, and long-lived caching. Private storage keys and credentials are never runtime asset references. System fonts require no network. A managed font download still happens in the browser even when HTML is server-rendered.
Empirical acceptance
Section titled “Empirical acceptance”For active, preview, and fallback paths in both supported modes, capture that:
- JavaScript disabled returns branded content with critical scoped CSS;
- the first response already contains exact attributes, projection hash, and mode identity;
- bootstrap and server resolution identities match;
- no provider-default frame appears;
- cross-Workspace and disallowed-mode requests fail safely;
- tampered projections, canonical hashes, signatures, identities, or assets are rejected;
- serialized runtime envelopes contain no source definition, storage key, full compiled artifact, or unselected-mode configuration;
- timeout uses only the verified embedded fallback;
- preview expiry is explicit and never becomes active branding; and
- hydration, accessibility, contrast, CSP, font, and asset checks pass.
Record the exact package versions, commit, commands, URLs, and results. Do not reuse evidence from another revision.