ARCHITECTURE · THE WHOLE MACHINE

Every moving part, named.

How it works is the story of an edit. This is the wiring behind it: what each piece is, who runs it, which secrets it holds, and how long they live. Nothing here is a diagram of an ideal. It is what the code does.

The parts

Six pieces. You own four of them.

There is no application server anywhere in this list. Your site is compiled to files ahead of time, and the only thing that ever runs on a request is Cloudflare handing one over.

PieceWhat it actually isWho runs itHolds secrets
Your repositoryMarkdown and HTML files on GitHub. The source of truth for every word on your site.YouNo
Your siteAn Astro static build, served by Cloudflare Pages. Plain HTML by the time a visitor sees it.YouNo
Lanza, the CMSA Vue app at /admin. Static files, with no backend of its own.YouNo
lanza-siteThe npm package holding the render code and the site's server functions. You pin a version.YouNo
The brokerconnect.lanzacms.com, which handles onboarding, login, and minting short-lived tokens.LanzaYes, all of them
/api/mcpThe endpoint an AI agent connects to in order to edit your site.YouNo
Life of an edit

Save writes to a branch. Publish is a merge.

The CMS never writes to your live site. It writes to a staging branch, and publishing is an ordinary git merge, which is why every change is reversible and nothing is ever half-applied.

  1. 01

    You save

    PUT → staging

    The CMS commits to the staging branch through its own /admin/api/gh proxy. Your browser never holds a GitHub token: the proxy attaches one per request, scoped to this one repository, and it expires in about an hour.

  2. 02

    You review

    staging.<project>.pages.dev

    Cloudflare builds the staging branch too, so there is a real URL showing exactly what you just wrote, before anyone else can see it.

  3. 03

    You publish

    merge staging → main

    One merge. No separate deploy step and no copy of your content living anywhere else.

  4. 04

    Cloudflare rebuilds

    astro build → dist

    The push to main triggers a static build. Entries marked draft never render, whether or not they were merged.

  5. 05

    You change your mind

    git revert

    Every version is a commit. Rolling back is the same operation a developer would use, and the CMS keeps theme history for the same reason.

Signing in

Two checks, and both are required.

Your site holds no signing secret. It verifies with a public key baked into the package, which means the thing that proves who you are lives somewhere it cannot be stolen from you.

  1. You open /admin. It sends you to GitHub, asking for identity only, with no repository scopes at all.
  2. GitHub returns to the broker, not to your site. The broker is the only place that holds the private key.
  3. The broker signs a session (RS256) naming your GitHub login, your site's origin, a one-shot nonce, and an expiry.
  4. It posts that token back to your site in a form body, never in a URL, so it cannot land in history, a log, or a referrer header.
  5. Your site verifies the signature with the baked-in public key, then checks the audience is this site, the nonce matches the cookie it set, and the token has not expired.
  6. Then, separately, it checks your login against the site's owner list.
Blast radius

Nothing long-lived, nothing broadly scoped.

The useful question about a credential is not whether it is encrypted. It is what an attacker reaches if they hold it, and for how long.

CredentialReachesLifetime
Your session cookieYour site's /admin only. HttpOnly, Secure, and scoped so it is never sent on public pages7 days
The GitHub token behind a saveOne repository, contents only. Minted per request; never sent to the browser~1 hour
An agent's access tokenThe sites you ticked on the consent screen, and nothing else1 hour, refreshable
A token minted for one agent callExactly one site. The audience is pinned to it5 minutes
Your site's own key materialNothing. It holds a public key and can only verifynone
For agents

An agent edits your site the way you do.

Your site exposes an MCP endpoint. An agent that connects to it goes through the same OAuth round-trip you do: authorization code with PKCE, discovery over the standard well-known documents, and a GitHub login for identity. If you own several Lanza sites, one consent screen asks which of them this agent may touch, and that choice is carried on the token itself; a tampered response can only narrow the grant, never widen it. The agent is given a token bound to one site's endpoint. It never receives a GitHub token, and there is no personal access token to create, paste, or leak.

Read the agent contract
What it costs to run

Static sites are cheap because nothing is running.

Page views on Cloudflare Pages are unmetered, so there is no per-visit cost and no traffic level at which your bill starts moving. There is no database to pay for and no server sitting idle, because there is no server. The only recurring cost is your domain name, which you buy from whoever you like and point wherever you like.

$0to build, host and serve
~$12a year for a domain, the only bill
0databases, servers, and things to patch
Updates, and leaving

You pin the version. You keep the files.

Your site depends on a published package at a version you choose, so an improvement we ship does not change your site until you take it, from Settings, when it suits you. And the exit is not a feature we had to build: your content is already a folder of ordinary files in a repository you own. The broker is a convenience layered on top of a CMS that works without it: supply your own GitHub credentials and owner list and you can run the whole thing yourself, with us removed from the picture entirely.

Read the plain-language version.

Same machine, told as a story instead of a diagram.

How it works