Deployment And Access
This page defines the default GoingNinja surface split, default subdomains, and the Cloudflare Access boundary.
If you need the shared reader registration, approval, group sync, and access-registry model on rascher.online, read Identity And Access next.
1. Default Deployment Split
<platform-domain> means the platform-owned apex.
<product-domain> means the apex of one generated product project.
Current live surface:
wiki.rascher.online
Target platform apex:
goingninja.dev
| Meaning | Current live | Target |
|---|---|---|
| platform manual invite layer | wiki.rascher.online/ |
manual.goingninja.dev/ |
| platform manual protected surface | wiki.rascher.online/manual/ |
manual.goingninja.dev/manual/ |
| platform OS docs | not live yet | os.goingninja.dev |
| platform hub | not live yet | hub.goingninja.dev |
| platform status | not live yet | status.goingninja.dev |
| Surface | Default hostname | Default provider | Default posture |
|---|---|---|---|
| manual invite layer | manual.<platform-domain>/ |
static site, currently Cloudflare Pages | public |
| manual protected surface | manual.<platform-domain>/manual/ |
static site, currently Cloudflare Pages | protected |
| OS docs | os.<platform-domain> |
static docs or lightweight operator surface | protected |
| portfolio hub | hub.<platform-domain> |
shared operator surface | protected |
| status | status.<platform-domain> |
shared health surface | protected |
| product app | apex or www.<product-domain> |
Vercel | public unless the whole product is internal |
| project preview | www.preview.<product-domain> |
Vercel behind a Cloudflare-managed custom domain | protected |
| project ops surface | ops.<product-domain> |
optional, only if the project needs a separate operator UI | protected |
2. Standard Subdomains
Default rule: use literal names, not clever names.
| Subdomain | Use it for | Create by default? |
|---|---|---|
manual |
public or semi-public documentation surface | yes, for the manual |
os |
operator-facing OS docs or future control-plane entrypoint | yes, once the OS surface is live |
hub |
future multi-project portfolio hub | no, only when the portfolio surface exists |
status |
future platform health surface | no, only when there is something worth exposing |
preview |
protected preview label inside the hostname www.preview.<product-domain> |
yes, for generated web MVPs |
ops |
protected project-specific operator UI | optional |
No default api subdomain is created. Add it only when the product actually has a separate API surface.
3. Access Boundary
flowchart LR
User["Reader or operator"]
Edge["Cloudflare DNS + Access"]
Invite["manual.<platform-domain>/"]
Manual["manual.<platform-domain>/manual/"]
OS["os.<platform-domain>"]
Preview["www.preview.<product-domain>"]
Public["apex / www.<product-domain>"]
Pages["Cloudflare Pages"]
Vercel["Vercel project"]
User --> Edge
Edge --> Invite
Edge --> Manual
Edge --> OS
Edge --> Preview
Edge --> Public
Invite --> Pages
Manual --> Pages
OS --> Pages
Preview --> Vercel
Public --> VercelShow diagram source
flowchart LR
User["Reader or operator"]
Edge["Cloudflare DNS + Access"]
Invite["manual.<platform-domain>/"]
Manual["manual.<platform-domain>/manual/"]
OS["os.<platform-domain>"]
Preview["www.preview.<product-domain>"]
Public["apex / www.<product-domain>"]
Pages["Cloudflare Pages"]
Vercel["Vercel project"]
User --> Edge
Edge --> Invite
Edge --> Manual
Edge --> OS
Edge --> Preview
Edge --> Public
Invite --> Pages
Manual --> Pages
OS --> Pages
Preview --> Vercel
Public --> Vercel4. Default Cloudflare Protection
GoingNinja treats Cloudflare Access as the default protection layer for:
- the protected manual surface under
/manual/ - OS/operator surfaces
- preview subdomains
- optional project operator subdomains
The lean default is:
- one Access application per protected hostname or protected hostname path
- explicit allow policies based on exact emails, email domains, or IdP groups
- the standard Cloudflare Access login page first; no custom login screen is required for v1
For generated product previews, the default posture is narrower:
- the hosted pre-launch preview lives on
www.preview.<product-domain> - that hostname stays behind one Cloudflare Access application
- the allow policy is explicit and versioned as repo truth before the preview goes live
- the repo must state which emails or identity groups are allowed to sign in to that preview
Do not use these as defaults:
Include everyoneInclude all valid emails
GoingNinja avoids both because they remove the allow-by-identity boundary. Cloudflare's policy model makes the allow list explicit; broad includes defeat that contract.
5. Local, Branch, Preview, And Live
GoingNinja treats these as different boundaries, not as one blurred deploy story.
| Boundary | What happens there | Default hostname posture |
|---|---|---|
local clone with local .git |
implementation, local preview, local tests, branch commits | no public hostname |
| pushed branch and PR | deterministic checks and review lanes | raw provider previews may exist, but are not canonical |
pre-launch continuity preview on main |
hosted integration proof before public launch | www.preview.<product-domain> behind Cloudflare Access |
| explicit launch | public production cutover | apex or www.<product-domain> |
The practical rule is:
- develop locally in a cloned repo with local Git history
- commit on a feature branch
- push the branch and open or update the PR
- let the pipelines run
- merge into
main - before public launch, publish the continuity state on
www.preview.<product-domain> - only cut over to the public host when the product is explicitly ready to launch
6. Generated URLs And Canonical URLs
Generated provider URLs are useful for debugging, not as the final surface.
- Cloudflare Pages gives a
*.pages.devhostname. - Vercel gives a
*.vercel.apphostname.
GoingNinja does not treat them as canonical user-facing URLs.
The preferred shape is:
- attach the custom domain first
- then protect the custom domain
- then redirect or otherwise de-emphasize the raw provider hostname where the provider supports it
If a protected preview host points at Vercel while Vercel Deployment Protection is also enabled, the request path needs an explicit handoff. In practice that means either:
- Cloudflare Access injects the Vercel protection bypass header, or
- Vercel Deployment Protection is disabled for that protected preview host
Without that handoff, the preview host is still blocked by Vercel.
Cloudflare documents one important Pages caveat: you cannot add a custom domain while Cloudflare Access is already enabled on that domain. Attach the domain first and enable Access second.
7. Preview Access Allowlist
The preview host is not protected by vague intent. The repo must make the Access rule explicit.
The minimum contract is:
- which Cloudflare Access application protects
www.preview.<product-domain> - which emails or identity groups are allowed
- who owns that allowlist
- where the machine reads that list from when preview deploy automation is introduced
Do not treat this as chat memory or as a dashboard-only setting with no repo trace.
8. Current Implementation Boundary
Live today:
- the public invite layer is reachable on
wiki.rascher.online/ - the protected manual is reachable on
wiki.rascher.online/manual/ - Cloudflare Access currently protects the
/manual/*path, not the host root
Target but not yet complete:
manual.goingninja.dev/as the canonical public invite layermanual.goingninja.dev/manual/as the canonical protected manual path- generated project bootstrap that also provisions or at least requires Cloudflare DNS and Access entries for
www.preview.<product-domain> - end-to-end proof that every generated project receives the same deploy-and-protect sequence automatically
9. Sources
Notes
- Implementation.
workers/rascher-online-www/index.js,workers/rascher-online-www/wrangler.jsonc, and the live manual hostwiki.rascher.online/manual/.