First-Time Cloudflare Setup — Every Click
This is the long version on purpose. Start with a clean deployment and follow every numbered action in order.
RESET FIRST — if you are restarting after a failed setup
Do not delete persistent data blindly
Cloudflare DashboardA clean restart does not mean deleting D1, R2, your DNS zone, or the repaired Zero Trust organization. Those can contain persistent data or account-level configuration.
Keep the current Zero Trust team domain
Zero Trust → Settings → Team name and domainFor this deployment the intended team domain is iridesceux.cloudflareaccess.com. Open https://iridesceux.cloudflareaccess.com in a private window. If Cloudflare shows a valid Access/App Launcher/Welcome page, keep the organization. Do not rename or delete it.
Remove only the stale Command Access application if you are rebuilding Access
Zero Trust → Access controls → ApplicationsIf an old Iridesceux Command application was created while the team domain was broken, delete that application only. Do not delete the entire Zero Trust organization.
Preserve or inventory D1 and R2
Storage & DatabasesIf iridesceux-command and iridesceux-command-assets already exist, keep them unless you are absolutely certain they contain only disposable test data. The later steps show how to verify/rebind them instead of recreating them unnecessarily.
Decide whether to keep or recreate the Command Pages project
Workers & PagesIf the existing Command *.pages.dev deployment loads correctly and Functions are deployed, you may keep the project. If you want a completely fresh Pages project, first note its project name, custom domain, bindings, and variables, then remove command.iridesceux.com from Custom domains before deleting the old Pages project.
Remove stale manual DNS for command only if it conflicts
iridesceux.com → DNS → RecordsLook specifically for a manually created command A/AAAA/CNAME that points somewhere other than the Pages project. Do not touch unrelated DNS records. When the domain is attached through Pages, Cloudflare can manage the correct record.
Revoke temporary team-repair API tokens
Manage Account → API TokensIf you created a temporary token only to repair auth_domain, revoke it now unless you still need document 19. A one-time repair credential should not remain active indefinitely.
Start the numbered build from Step 1
This documentFrom this point forward, make one change at a time and verify the expected result before continuing.
Before touching Cloudflare
Make a clean working folder
FinderExtract the full release ZIP into a normal folder. Do not run deployment from inside the ZIP viewer.
command-app, public-site, hvn-site, and DOCUMENTATION as real folders.Install/confirm Git
Terminalgit --versionIf the command is missing, install Apple Command Line Tools when macOS prompts you.
Install/confirm Node and npm
Terminalnode --version
npm --versionNode/npm are needed for Wrangler and the Broadcast Agent.
Decide your bootstrap email
Your inboxPick the exact email that will be your first Command Super Admin and that can receive Cloudflare OTP email. Write it down exactly; no aliases unless you intend to use that alias everywhere.
A. Create the private GitHub repository
Create a PRIVATE repository
GitHub → New repositoryName it something like iridesceux-hvn. Set visibility to Private. If you are pushing an existing folder, do not initialize it with a README that will create an unrelated first commit.
Initialize Git in the extracted package
Terminal in the package rootcd "/path/to/Iridesceux-HVN-v20.6-Exhaustive-Documentation"
git init
git branch -M main
git statusCheck that secrets are not about to be committed
Same Terminalfind . -maxdepth 3 \( -name ".env" -o -name ".dev.vars" -o -name "wrangler.toml" \) -printReview any results. Real secrets must not be committed. Example/template files are okay if they contain placeholders only.
Commit the monorepo
Same Terminalgit add .
git commit -m "Initial Iridesceux HVN deployment package"Attach the GitHub remote and push
Same Terminalgit remote add origin https://github.com/YOUR-OWNER/YOUR-REPO.git
git push -u origin mainIf origin already exists, use git remote -v and correct it with git remote set-url origin ....
B. Create Command in Cloudflare Pages
Open Workers & Pages
Cloudflare Dashboard → Workers & PagesSelect Create / Create application and choose Pages with Git integration. Connect GitHub if Cloudflare asks.
Select the repository
Workers & Pages → Pages → Connect to GitChoose the Iridesceux/HVN private repository and production branch main.
Set the Command root directory
Build configurationOpen the advanced/root-directory control and enter exactly:
command-appcommand-app.Set the framework/build settings
Build configurationUse:
exit 0publicThe code does not require a framework build. Cloudflare documents exit 0 as a valid no-op build command when not using a preset.
command-app; output = public.., repository root, or command-app/public while root is already command-app.Deploy Command
Build configuration → Save and DeployWait for the deployment to finish. Copy the generated *.pages.dev URL somewhere.
Prove Pages Functions deployed
Open the Pages URLOpen https://YOUR-PROJECT.pages.dev/api/command/me.
At this point it may return a JSON error such as missing D1/authentication. That is okay. The key test is that it is a Function response — not your HTML homepage and not a Pages 404.
command-app/functions exists at the project root.C. Create D1, load the schema, and bind it
Create the D1 database
Cloudflare → Storage & databases → D1Select Create database. Recommended name:
iridesceux-commandLog Wrangler into Cloudflare
Terminalcd "/path/to/repo/command-app"
npx wrangler loginApprove the browser authorization using the same Cloudflare account that owns the project.
Load the entire schema into REMOTE D1
Terminal insidecommand-appnpx wrangler d1 execute iridesceux-command --remote --file=command-schema.sqlVerify tables exist
Same Terminalnpx wrangler d1 execute iridesceux-command --remote --command="SELECT name FROM sqlite_schema WHERE type='table' ORDER BY name;"Bind D1 to Command
Workers & Pages → Command project → Settings → Bindings → Add → D1 databaseSet Variable name exactly:
COMMAND_DBSelect the iridesceux-command database.
COMMAND_DB.Redeploy after adding the binding
Command project → DeploymentsTrigger a new production deployment, or push a harmless commit. A binding added after a deployment does not retroactively change that already-running deployment.
Test D1 through Command
Open newest deploymentOpen /setup-doctor.html and /api/command/me. Authentication may still fail, but D1 should no longer show “COMMAND_DB binding is not configured.”
D. Create R2 and bind uploads
Create the R2 bucket
Cloudflare → Storage & databases → R2If Cloudflare asks you to enable R2 billing/subscription, complete that account setup first. Then create a bucket named:
iridesceux-command-assetsKeep it private; R2 buckets are private by default.
Bind R2 to Command
Workers & Pages → Command project → Settings → Bindings → Add → R2 bucketVariable name must be exactly:
COMMAND_ASSETSSelect iridesceux-command-assets.
COMMAND_ASSETS.Redeploy again
Command project → DeploymentsCreate a deployment after the R2 binding was added.
Do not test uploads yet if Access is not complete
CommandThe upload UI requires Command authentication. Continue to custom domain + Access first, then return to the R2 persistence test in Step 49.
E. Attach the Command custom domain BEFORE Access
Check for a conflicting manual DNS record
Cloudflare → iridesceux.com → DNS → RecordsSearch for a record whose name/hostname is command. If you previously created a manual A/AAAA/CNAME for Command and it is not the current Pages-managed record, remove the conflicting record before attaching the Pages custom domain.
command.iridesceux.com.Attach the domain from the Pages project
Workers & Pages → Command project → Custom domains → Set up a domainEnter exactly:
command.iridesceux.comContinue/activate. Because the zone is already in the same Cloudflare account, Pages should manage the required DNS record.
Wait for Active
Command project → Custom domainsDo not proceed while the domain says Pending/Verifying/Initializing.
command.iridesceux.com is Active.Test the hostname before Access
BrowserOpen https://command.iridesceux.com. It may be temporarily unprotected for this short test. Verify it resolves to Command and not a 522.
F. Verify the Zero Trust team itself BEFORE protecting Command
Open Zero Trust
Cloudflare Dashboard → Zero TrustIf Cloudflare asks you to initialize a Zero Trust organization, complete the organization setup. The intended team domain for this deployment is:
iridesceux.cloudflareaccess.comConfirm the team name/domain in Settings
Zero Trust → Settings → Team name and domainCopy the exact current team domain from Cloudflare. For this deployment it should be:
iridesceux.cloudflareaccess.comDo not confuse this with command.iridesceux.com. The first is the Access organization domain; the second is the protected application.
Directly test the team domain
New private/incognito windowOpen:
https://iridesceux.cloudflareaccess.comA valid organization may show an App Launcher, login page, or “Welcome — enable App Launcher” message.
G. Configure One-Time PIN
Open Identity providers
Zero Trust → Integrations → Identity providersCheck whether One-time PIN already exists.
Add One-time PIN if missing
Identity providers → Add new identity providerSelect One-time PIN and save. New Zero Trust organizations may use Cloudflare as the default provider; OTP is not necessarily added automatically.
H. Protect the raw Command pages.dev domain and previews
Enable the Pages Access policy
Workers & Pages → Command project → SettingsFind Enable access policy and enable it for the Command Pages project. Cloudflare documents this as the supported way to secure the project *.pages.dev address and preview deployments.
This matters because the package mirrors internal documentation under command-app/public/docs; protecting only command.iridesceux.com would otherwise leave the raw Pages hostname as an alternate path.
Verify both the project pages.dev URL and preview URLs are protected
Zero Trust → Access controls → Applications, then a fresh Incognito windowFollow Cloudflare's Pages procedure: manage the Pages-created Access application, ensure the non-wildcard project hostname is protected, then re-enable preview protection so both the main PROJECT.pages.dev and preview pattern *.PROJECT.pages.dev are covered. Configure the policies so only intended identities can enter; for this setup use One-Time PIN with the same exact bootstrap email while testing.
Then open the raw https://PROJECT.pages.dev URL in Incognito. You should see Access before Command.
I. Create the Command Access application for the custom hostname
Create a new Access application
Zero Trust → Access controls → Applications → Create new applicationSelect:
Self-hosted and privateThen choose:
Add public hostnameName the application
Application configurationIridesceux CommandSet the protected public hostname
Application configuration → Public hostnameUse:
commandiridesceux.comBlank path means protect the entire hostname.
command.iridesceux.com.Create the Allow policy
Access policies → Create new policyUse:
Command Admin AccessAllowEmailsDo not use Include → Everyone. Do not use “Emails ending in” unless you deliberately want the whole domain allowed.
Select One-Time PIN
Identity providers / Login methodsSelect One-time PIN. If it is the only login method, instant authentication may be on or off; either can work. For troubleshooting, leaving it off gives you the normal Access login screen.
Set session duration
Application settings24 hoursCloudflare documents 24 hours as the default application session duration. This is reasonable for initial Command setup.
Leave private-network/clientless isolation settings alone
Additional settingsDo not enable Browser Isolation/clientless private-destination options. Command is a public-hostname self-hosted app, not a private-network destination. Leave custom CORS/cookie/block-page settings at defaults unless you have a separate requirement.
Create/save the application
Bottom of Access application formSave the application. If Cloudflare errors about clientless isolation/private destinations, go back to Additional settings and turn that feature off.
J. Get the AUD and configure Command JWT validation
Copy the Application Audience (AUD) Tag
Zero Trust → Access controls → Applications → Iridesceux Command → Configure / Additional settingsFind Application Audience (AUD) Tag. Copy the exact value. Treat it as configuration, not a password, but do not casually publish internal identifiers.
Set Command variables
Workers & Pages → Command project → Settings → Variables and SecretsAdd these as normal plaintext variables:
BOOTSTRAP_ADMIN_EMAIL=YOUR-EXACT-LOGIN-EMAIL
CF_ACCESS_TEAM_DOMAIN=https://iridesceux.cloudflareaccess.com
CF_ACCESS_AUD=PASTE_CURRENT_APPLICATION_AUD
COMMAND_REQUIRE_ACCESS_JWT=trueKeep COMMAND_ALLOW_HEADER_AUTH unset or false in production.
Redeploy after variables change
Command project → DeploymentsTrigger a new production deployment after changing the variables. Do not test an older deployment.
K. First real login and bootstrap Super Admin
Start with a fresh Incognito window
BrowserOpen https://command.iridesceux.com. You should hit Cloudflare Access before the Command app.
Request and enter a new OTP
Cloudflare AccessEnter the exact email allowed in the policy. Request the code. Use the newest code Cloudflare sends.
Verify the backend identity
Same authenticated browserOpen:
https://command.iridesceux.com/api/command/meThe first successful login with the bootstrap email should create/recognize the Command user as Super Admin.
super_admin.Authentication required. — use document 13 section “401 after Access login.”Run Setup Doctor
CommandOpen:
https://command.iridesceux.com/setup-doctor.htmlCore checks should identify Functions, D1, Access JWT, and R2 configuration. Optional workers/OBS can still be unconfigured.
Test R2 persistence now
Command → Assets or a harmless upload surfaceUpload one small disposable image/file under the app upload limit, refresh the page, and verify the asset still exists. The generic Command asset route currently enforces a 25 MB limit; use your video/storage workflow for large program masters.
L. Only after Command is healthy: create Iridesceux and HVN Pages projects
Create Iridesceux Pages project
Workers & PagesConnect the same private Git repo. Root public-site, framework None, build exit 0, output public.
*.pages.dev URL loads.Do not attach the production apex until launch rehearsal
Iridesceux projectKeep the production domain unchanged if the public site is still coming soon/offline. Use the Pages staging URL for testing.
Create HVN Pages project
Workers & PagesSame repo. Root hvn-site, framework None, build exit 0, output public.
Bind shared D1/R2 to HVN if required by the deployed functions
HVN project → Settings → BindingsUse exact binding names COMMAND_DB and COMMAND_ASSETS where HVN Functions depend on the shared presentation/account/media state. Optional binding: HVN_ANALYTICS. Optional variable: HVN_REALTIME_URL.
What NOT to do during first setup
- Do not protect
command.iridesceux.comwith Access before Pages has successfully attached that custom domain; Cloudflare currently documents this as a Pages known issue. - Do not manually create a Pages CNAME and skip the Pages “Set up a domain” workflow; Cloudflare documents that this can cause a 522.
- Do not enable
COMMAND_ALLOW_HEADER_AUTHin production. - Do not put API tokens, OBS passwords, or stream keys into Git.
- Do not use the offline Command demo as proof that Functions/D1/R2 work.
- Do not delete the Zero Trust organization as a routine troubleshooting step.
- Do not rename the team domain in the middle of Access setup. If you must rename it, use document 19 and update every dependent configuration afterward.