HTTP/HTML transport layer for Milpa Live: CSRF/HMAC/nonce security, the signed XHTML state-transfer codec, the wire-protocol LiveEndpoint controller, and the HTML/Alpine/Latte-subset renderers for the Milpa PHP framework.
HTTP/HTML transport layer for Milpa Live: CSRF/HMAC/nonce security, the signed XHTML state-transfer codec, the wire-protocol LiveEndpoint controller, and the HTML/Alpine/Latte-subset renderers for the Milpa PHP framework.
v0.2.0 2026-07-28 01:18 UTC
This package is auto-updated.
Last update: 2026-07-28 01:18:38 UTC
The web surface for
milpa/live— HTML renderers over the design system, XHTML state/interaction codecs, and a security-hardenedLiveEndpoint(HMAC-signed state, CSRF, single-use nonce/replay protection).
milpa/live defines the render-target-agnostic component lifecycle (mount / handle / render,
contracts, data sources). milpa/live-web is what makes that lifecycle reachable over HTTP and
renderable to a browser: HTML renderers for the form, dashboard, and autocomplete component
families, a dependency-free XHTML state/interaction transport codec, and the security package —
HMAC state signing, CSRF, and single-use nonce/replay protection — that LiveEndpoint composes
into one hardened HTTP entrypoint.
composer require milpa/live-webWhat it is
LiveEndpoint — the HTTP live-loop terminus. Verifies the request method, the CSRF token,
and the signed state envelope; authorizes the requested action against the component's own
contract; dispatches to the component's handle(); and returns freshly rendered HTML plus a
freshly signed state envelope for the client to hold onto. Every ordinary failure (bad method,
missing fields, invalid signature, replay, unauthorized action) returns a typed error response —
it never throws for expected bad input.AutocompleteHtmlRenderer, FormPrimitiveHtmlRenderer (input,
textarea, select, checkbox), and DashboardHtmlRenderer (shell, sidebar, topbar, grid,
panel, metric card, data table, …) each turn a component's state into Alpine-bound HTML over the
@milpa/design system. XhtmlComponentCompiler lets you author <milpa:*> component trees
directly in markup and compiles them through the same renderer pipeline.XhtmlStateTransferCodec encodes a component's state/interaction as a single
<milpa-state> / <milpa-interaction> XHTML element with a base64 JSON payload. It carries no
security guarantees on its own — it is the $inner codec SignedXhtmlStateTransferCodec wraps.HmacStateSigner, HmacCsrfGuard, FileNonceStore, SignedXhtmlStateTransferCodec,
ContractInteractionAuthorizer, and AllowListCorsPolicy are the concrete, production classes
LiveEndpoint is built to trust — see Security below.AlpineRuntimeAdapter — the Milpa\Live\Contracts\Client\ClientRuntimeAdapterInterface
implementation the shipped renderers target; it marks root elements with data-milpa-*
attributes and describes the boot payload/asset the Alpine runtime script consumes.Wiring the real security classes and issuing one interaction through LiveEndpoint — this is a
trimmed version of what tests/Http/LiveEndpointTest.php exercises, and runs as-is against this
package's own vendor/:
use Milpa\Live\Adapters\Alpine\AlpineRuntimeAdapter; use Milpa\Live\Components\Autocomplete\AutocompleteComponent; use Milpa\Live\DataSource\ArrayDataSource; use Milpa\Live\DataSource\InMemoryDataSourceRegistry; use Milpa\Live\Http\LiveEndpoint; use Milpa\Live\Http\LiveHttpRequest; use Milpa\Live\Rendering\AutocompleteHtmlRenderer; use Milpa\Live\Runtime\InMemoryComponentRegistry; use Milpa\Live\Security\ContractInteractionAuthorizer; use Milpa\Live\Security\FileNonceStore; use Milpa\Live\Security\HmacCsrfGuard; use Milpa\Live\Security\HmacStateSigner; use Milpa\Live\Security\SignedXhtmlStateTransferCodec; use Milpa\Live\Transport\XhtmlStateTransferCodec; use Milpa\Live\ValueObjects\ComponentContext; // A real component (milpa/live) over a real data source. $sources = new InMemoryDataSourceRegistry(); $sources->register(new ArrayDataSource('customers.search', [ ['value' => 'acme', 'label' => 'Acme Studio', 'search' => 'agency design'], ['value' => 'milpa', 'label' => 'Milpa Labs', 'search' => 'framework components'], ])); $components = new InMemoryComponentRegistry(); $components->register('autocomplete', new AutocompleteComponent($sources)); // The real security wiring: HMAC-signed state + single-use replay nonce + CSRF. $codec = new SignedXhtmlStateTransferCodec( new XhtmlStateTransferCodec(), new HmacStateSigner($_ENV['LIVE_STATE_SECRET']), new FileNonceStore(sys_get_temp_dir() . '/milpa-live-nonces.json'), ); $csrf = new HmacCsrfGuard($_ENV['LIVE_CSRF_SECRET']); $endpoint = new LiveEndpoint( components: $components, codec: $codec, authorizer: new ContractInteractionAuthorizer($components), csrf: $csrf, route: '/live/autocomplete', renderers: ['autocomplete' => new AutocompleteHtmlRenderer(new AlpineRuntimeAdapter(), $codec)], ); // Mount the initial state (server-rendered on the page) and issue a CSRF token for the session. $context = new ComponentContext('customer-picker', route: '/autocomplete-demo'); $state = $components->get('autocomplete')->mount(['name' => 'customer', 'source' => 'customers.search'], $context); $sessionId = 'demo-session'; // however your app tracks sessions (e.g. the PHP session id) $csrfToken = $csrf->issueToken($sessionId, '/live/autocomplete'); $envelope = $codec->encodeState($state); // embed both in the SSR'd page // The client echoes $envelope + $csrfToken back on every interaction. $response = $endpoint->handle(new LiveHttpRequest( method: 'POST', action: 'search', stateEnvelope: $envelope, payload: ['query' => 'mil'], sessionId: $sessionId, csrfToken: $csrfToken, )); $response->status; // 200 $response->body['data']; // ['items' => [['value' => 'milpa', ...]]] $response->body['html']; // freshly rendered <input x-data="milpaAutocomplete(...)">… $response->body['state']; // a freshly signed <milpa-state> envelope for the next round-tripSecurity
LiveEndpoint's trust model, in one line: the client cannot hold the signing secret, so it
never builds a state envelope itself — it only ever echoes back, byte for byte, the last
<milpa-state> envelope this server signed and handed it (first embedded in the SSR'd page, then
refreshed on every response). Verifying that envelope is what proves it hasn't been tampered with:
LiveEndpoint returns 400 invalid_signature
before the request ever reaches a component's handle().FileNonceStore (or another
NonceStoreInterface) is wired into SignedXhtmlStateTransferCodec, every signature carries a
single-use nonce; decoding the exact same signed envelope a second time throws
ReplayedNonceException and LiveEndpoint answers 409 replay_detected — a conflict with the
server's current state, not a permissions failure, because the request was genuinely authentic
the first time.HmacCsrfGuard binds a token to the exact
sessionId/route pair it was issued for; a token issued for one session or route never
verifies for another, and CSRF failure (403 csrf) is checked before the state envelope is even
decoded.ContractInteractionAuthorizer only allows an
action that the component's own contract declares, checks that the state's owning principal (if
any) matches the caller, and requires the derived milpa:component:{name}:{action} scope — an
attacker who forges a plausible-looking action name still gets 403 action_not_allowed.None of this is optional wiring you have to remember: LiveEndpoint::handle() runs method → CSRF →
signature/replay → authorization, in that order, and turns every failure into the matching HTTP
status instead of throwing.
The @milpa/design topology caveat. The HTML renderers' CSS comes from Milpa\Live\Support\MilpaDesign,
which resolves the @milpa/design npm package at node_modules/@milpa/design under your project
root. If your layout differs (a monorepo, a lab checkout without npm install), set
MILPA_DESIGN_PATH to the design package's directory — it takes priority over the npm-relative
lookup and is checked first by every method on MilpaDesign.
| Namespace | What it provides |
|---|---|
Milpa\Live\Http |
LiveEndpoint — the hardened HTTP live-loop entrypoint |
Milpa\Live\Security |
HmacStateSigner, HmacCsrfGuard, FileNonceStore, SignedXhtmlStateTransferCodec, ContractInteractionAuthorizer, AllowListCorsPolicy, StaticBearerTokenVerifier |
Milpa\Live\Transport |
XhtmlStateTransferCodec — the unsigned inner transport codec |
Milpa\Live\Rendering |
AutocompleteHtmlRenderer, FormPrimitiveHtmlRenderer, DashboardHtmlRenderer, LatteTemplateRenderer, XhtmlComponentCompiler |
Milpa\Live\Adapters\Alpine |
AlpineRuntimeAdapter — the shipped ClientRuntimeAdapterInterface |
Milpa\Live\Support |
Html (escaping helpers), MilpaDesign (design-system path resolution) |
Milpa\Live\Contracts\* |
Security, Rendering, and Transport seams — CsrfGuardInterface, StateSignerInterface, NonceStoreInterface, StateTransferCodecInterface, ComponentRendererInterface, MarkupCompilerInterface, TemplateRendererInterface, CorsPolicyInterface, InteractionAuthorizerInterface, TokenVerifierInterface |
Milpa\Live\ValueObjects |
StateSignature, AuthorizationResult, CorsDecision |
Every public symbol carries a DocBlock.
Requirementsext-dom extensionmilpa/core ^0.6milpa/live ^0.1Full API reference: getmilpa.github.io/live-web — generated straight from the source DocBlocks and dressed with the Milpa design system.
ContributingContributions are welcome — see CONTRIBUTING.md. Please report security issues via SECURITY.md, and note that this project follows a Code of Conduct.
LicenseApache-2.0 © Rodrigo Vicente - TeamX Agency.
Milpa is designed, built, and maintained by Rodrigo Vicente - TeamX Agency.
| # | Наименование новости | Тональность | Информативность | Дата публикации |
|---|---|---|---|---|
| 1 | milpa/live (v0.2.0) | 0 | 17.79 | 28-07-2026 |
| 2 | milpa/live-tui (v0.3.0) | 0 | 12.4 | 28-07-2026 |
| 3 | milpa/http-symfony (v0.1.0) | 0 | 12.31 | 28-07-2026 |
| 4 | milpa/auth (v0.3.0) | 0 | 10.94 | 28-07-2026 |
| 5 | milpa/admin (v0.1.0) | 0 | 11.16 | 28-07-2026 |
| 6 | milpa/orchestrator (v0.3.0) | 0 | 16.04 | 28-07-2026 |
| 7 | seip25/lila-php (v1.59) | 0 | 38 | 28-07-2026 |
| 8 | ivanharmat/crewgrid (v0.2.0) | 0 | 19.86 | 28-07-2026 |
| 9 | milpa/skeleton (v0.10.0) | 0 | 20.4 | 28-07-2026 |
| 10 | rimba/boleh (v1.2.2) | 0 | 10 | 28-07-2026 |