wisewigdocs

Hosted-service control plane

The open-source framework does not depend on WiseWig’s managed service. @wise-wig/runtime defines HostedProvider and HostedStateStore; an installation can implement them for Cloudflare, another host, or an agency’s existing deployment system. The Cloudflare adapter persists control state in D1 and crosses a private HOSTING_DEPLOYER service binding for provider mutations. That adapter belongs in an operator/platform application or a self-hosted installation; the managed customer Astro profile strips both capabilities and hides the legacy panel.

Onboarding and provisioning

The provisioning API creates the tenant, site, verified initial hostname, owner identity/roles, tenant Durable Object content, and default resources idempotently. Managed installations also create one hosted_onboarding record per site and mark it ready only after Durable Object initialization completes. A hosted signup UI can collect the existing SiteProvisioningInput and call this authenticated server-side endpoint; the provisioning bearer secret must never be shipped to the browser.

Domains and deployments

Custom domains begin with a random DNS TXT challenge under _wise-wig.{hostname}. Verification performs a fixed DNS-over-HTTPS TXT lookup and compares the exact challenge after reloading the domain from D1 and confirming tenant/site ownership. A verified domain is activated only against a ready deployment for the same tenant and site.

Deployments are immutable requests identified by environment (preview, staging, or production) and source revision. HostedOrchestrator loads provider secret references, calls the host adapter, and records either the returned provider deployment ID/HTTPS URL or a bounded failure. The reference Cloudflare adapter sends deployment and hostname activation to a non-public service binding. Managed operators supply that Worker for their account/deployment system; self-hosters can replace the adapter without changing the CMS.

For the managed multi-tenant profile, TenantWorkerProvisioner claims an immutable tenant-to-script mapping, loads only a trusted release artifact, uploads it through the operator-only Workers for Platforms API client, verifies the exact returned script identity, and then marks the route ready. The upload declaratively exports TenantWorkspaceDO with SQLite storage. Each tenant receives a unique R2 bucket and queue named from its unique Worker identity; sharing either binding would weaken the Worker isolation boundary.

Secrets

WiseWig stores only a provider reference such as a Cloudflare Secrets Store identifier. The database schema and provider contract contain no secret-value field. The deployer resolves references inside its own privileged boundary. UI, audit, exports, MCP tools, public Workers, and tenant Durable Objects never receive hosted secret values.

Support access

Support access is additive, explicit, and time limited. The target identity must already hold the tenant’s support role; the approver must be an agency-owner; the grant requires a reason and lasts 5–480 minutes. Support browser sessions are denied by the production request gate unless an unrevoked grant is active. Grants remain visible in the management surface and never create a hidden impersonation bypass.

Security invariants

  • Every hosted record carries tenant/site scope, and API inputs are rechecked against the host-derived route.
  • Domain verification and activation fail closed on cross-tenant or cross-site IDs.
  • Deployments cross a private service binding; no Cloudflare account credential is available to the customer site Worker.
  • Secret references are identifiers, not values.
  • All mutations use the shared confirmation, permission, durable idempotency, and audit path.
  • Product, go-to-market, and monetization planning belongs in Notion, not this repository.

The Morning Bell management panel is an intentionally plain alpha client for these APIs. A future self-serve website builder can wrap the same onboarding, theme, editor, domain, and deployment contracts with a guided product experience.