Runbook de branding SSR
Owner: maintainers de LEMN UI y apps consumidoras
Revision: 2026-07-17
Patterns: PAT-UI-BRAND-CONTRACT-001, PAT-UI-SSR-BRANDING-001,
PAT-SEC-SECRETS-001, PAT-TEST-EVIDENCE-001
Invariante
Sección titulada «Invariante»Un browser de produccion nunca renderiza un componente sin branding ni el
default crudo del provider. Resuelve, autoriza, verifica e inyecta un mode de
una BrandingVersion publicada antes del primer byte HTML. Hydration confirma
el projectionHash, mode ID y mode hash exactos; no repara branding despues del
paint.
Inputs confiables
Sección titulada «Inputs confiables»El server deriva el Workspace desde identidad de workload o routing confiable.
Un Workspace ID del browser no es autoridad. El mode solo puede seleccionarse
si las proyecciones firmadas lo declaran permitido. Un host Cloudflare de la
misma cuenta usa un RPC Service Binding hacia un WorkerEntrypoint dedicado.
Sus ctx.props estaticos, definidos por deployment, autentican workspaceId,
consumerId y el permiso branding:resolve; la llamada RPC no lleva una
credencial ni un Workspace elegido por el browser. Un server externo usa HTTPS
autenticado con un WorkspaceRuntimeCredential least-privilege guardado solo
en server.
El browser nunca recibe MCP tokens, source definitions, credenciales runtime reusables ni credenciales R2.
Algoritmo
Sección titulada «Algoritmo»- Deriva Workspace y mode permitido.
- Resuelve con
@lemn-ltd/brand-runtimey deadline estricto. - Verifica envelope estricto,
projectionHashcanonico, firma, hashes de definition/compiled/mode, compatibilidad, identidad firmada de Workspace y publicacion, assets publicos y expiracion. - Lee CSS critico, preloads, assets seguros y bootstrap minimo solo desde esa proyeccion verificada.
- Emite preloads/style antes del markup y aplica todos los atributos de scope.
- Renderiza componentes y solo hidrata cuando
projectionHashe identidad del mode coinciden exactamente.
import { createServiceBindingBrandingRuntimeClient, resolveBranding,} from "@lemn-ltd/brand-runtime";import { assertBrandingHydrationIdentity, createBrandingSsrParts,} from "@lemn-ltd/brand-runtime/server";
const branding = await resolveBranding({ // Es configuracion confiable del host y se contrasta con el response. La // autoridad RPC viene de los ctx.props estaticos del binding. 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 });assertBrandingHydrationIdentity( ssr.hydrationIdentity, JSON.parse(clientBootstrapText),);El binding RPC solo expone resolveBranding, exchangeBrandingPreview y
resolveBrandingPreview. No es un Fetcher anonimo, no llama las rutas HTTP y
no recibe una credencial runtime reusable. Usa
createHttpsBrandingRuntimeClient solo desde un server externo y carga su
WorkspaceRuntimeCredential desde secrets/configuracion server-side.
Instala versiones exactas:
pnpm add @lemn-ltd/brand-contract@1.0.0 @lemn-ltd/brand-runtime@0.1.1 @lemn-ltd/ui@0.4.0Fallback activo
Sección titulada «Fallback activo»Cada release incluye un mapa exacto de proyecciones minimas por mode, firmadas independientemente, compatibles y ligadas al Workspace. No incluye el objeto compilado completo privado. Antes de resolver active, runtime verifica todos los modes y exige la misma identidad de publicacion, hashes, default mode y set de modes permitidos. El orden es:
- objeto activo actual verificado;
- fallback branded embedded verificado;
- respuesta unavailable explicitamente branded.
No existe una segunda autoridad ni cache mutable de recovery. Nunca uses source JSON, KV generico, defaults del provider ni tokens fallback del package como recovery de produccion.
Fonts, assets y CSP
Sección titulada «Fonts, assets y CSP»Emite solo los preloads de fonts del mode verificado. Agrega a CSP los origins exactos de fonts y assets publicos firmados; exige URLs inmutables, SHA-256/SRI, CORS correcto y caching durable. Los storage keys privados y credenciales nunca son referencias runtime. SSR no evita que el browser descargue una managed font.
Preview
Sección titulada «Preview»Preview esta pinneado a un definition hash exacto y usa handoff one-use,
short-lived y ligado a session. La URL limpia y browser storage no contienen
secrets reusables. Resolution es no-store; expiry/revoke/mismatch muestran
preview unavailable y nunca caen silenciosamente al branding activo.
Evidencia
Sección titulada «Evidencia»Prueba active, preview y fallback en ambos modes:
- contenido branded con JavaScript deshabilitado;
- CSS, atributos, projection hash e identidad del mode correctos en el primer response;
- bootstrap y server resolution con identidad igual;
- cross-Workspace y mode no permitido fallan seguro;
- proyecciones, hashes canonicos, firmas, identidades o assets tampered se rechazan;
- el envelope runtime serializado no contiene source definition, storage key, objeto compilado completo ni configuracion de otro mode;
- timeout usa solo el fallback embedded verificado;
- preview expirado es explicito; y
- hydration, a11y, contrast, CSP, fonts y assets pasan.
Registra versiones, commit, comandos, URLs y resultados exactos.