void 0.23.0 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/AGENTS_TEMPLATE.md +1 -1
  2. package/dist/{account-cmd-C84Ee8cO.mjs → account-cmd-vJhh5lrb.mjs} +5 -5
  3. package/dist/{auth-CSkdO2Bb.mjs → auth-CQkSDS50.mjs} +22 -49
  4. package/dist/auth-DX3JURcX.mjs +2 -0
  5. package/dist/{auth-link-CioEg6uY.mjs → auth-link-D75t9wO2.mjs} +5 -5
  6. package/dist/{auth-router-BsR981d4.mjs → auth-router-ClfhL1J7.mjs} +7 -7
  7. package/dist/{build-cmd-LzvNJORH.mjs → build-cmd-zMi1iFnS.mjs} +6 -6
  8. package/dist/{cache-C4MvnrMH.mjs → cache-ZtQmyxVV.mjs} +5 -5
  9. package/dist/{cancel-deploy-abUxpP2n.mjs → cancel-deploy-Box0kkEV.mjs} +5 -5
  10. package/dist/{cf-access-P0iZnu0q.mjs → cf-access-BGe5sWXF.mjs} +4 -48
  11. package/dist/{cf-access-DRsQRe6k.mjs → cf-access-TWNzXltp.mjs} +3 -11
  12. package/dist/cli/cli.mjs +47 -44
  13. package/dist/cli/cloudflare-operation-process.mjs +14 -5
  14. package/dist/cli/env-schema-probe.mjs +3 -3
  15. package/dist/client-B9UBI03V.mjs +2 -0
  16. package/dist/{client-RV8NVeB8.mjs → client-DKAsFA4X.mjs} +33 -15
  17. package/dist/{cloudflare-cmd-BcrVyTmJ.mjs → cloudflare-cmd-CmY8dGkd.mjs} +1 -1
  18. package/dist/{cloudflare-connect-B8uPZ4nx.mjs → cloudflare-connect-IiR3ZieC.mjs} +1 -1
  19. package/dist/{cloudflare-operations-AiWashgg.mjs → cloudflare-operations-BCdXSsmo.mjs} +1 -1
  20. package/dist/{cloudflare-operations-fxHb-byx.mjs → cloudflare-operations-DzH-A966.mjs} +1 -1
  21. package/dist/{connect-Bd4kJd9U.mjs → connect-B-usTnlF.mjs} +9 -9
  22. package/dist/{create-project-bMf6ffLZ.mjs → create-project-CYOOAYcn.mjs} +12 -12
  23. package/dist/{create-project-Boczwj5r.mjs → create-project-FWbf5Olo.mjs} +1 -1
  24. package/dist/{db-8uG64XLl.mjs → db-Ck2eZ2iB.mjs} +15 -15
  25. package/dist/{delete-NvbiyeJf.mjs → delete-sK56qtzZ.mjs} +5 -5
  26. package/dist/{deploy-DzAIwqNU.mjs → deploy-gCVaiJbS.mjs} +86 -44
  27. package/dist/{deploy-bjXdFCtn.mjs → deploy-irP5q0-x.mjs} +1 -1
  28. package/dist/{domain-y5Tvydvo.mjs → domain-DFfQE8jg.mjs} +6 -6
  29. package/dist/{email-B3umsW75.mjs → email-CdnhUHvJ.mjs} +7 -7
  30. package/dist/{env-BS6qYHDb.mjs → env-DmGdHi5i.mjs} +8 -8
  31. package/dist/{env-types-C2_bIk_b.mjs → env-types-D5kds_OZ.mjs} +1 -1
  32. package/dist/{env-validation-BPn7vk-V.mjs → env-validation-C_8tPdhs.mjs} +2 -2
  33. package/dist/{env-validation-DbTg7-ar.mjs → env-validation-zZOCcQVZ.mjs} +1 -1
  34. package/dist/{gen-B580--vC.mjs → gen-CshAkukR.mjs} +2 -2
  35. package/dist/gen-DvQTWzDU.mjs +2 -0
  36. package/dist/{github-cmd-v45BdfKX.mjs → github-cmd-DftuEvIt.mjs} +13 -13
  37. package/dist/{headers-DWi2IXWx.mjs → headers-2rKda9Y6.mjs} +1 -1
  38. package/dist/{help-daGKjXGk.mjs → help-Dotbf6iz.mjs} +8 -4
  39. package/dist/help-mabuIV98.mjs +2 -0
  40. package/dist/{inbound-aVHEUhKo.mjs → inbound-fRkqcXaC.mjs} +1 -1
  41. package/dist/index.mjs +16 -20
  42. package/dist/{init-Bvy7zrBo.mjs → init-BTQEZZGJ.mjs} +25 -22
  43. package/dist/{link-CDqqCjFl.mjs → link-B46sYH0K.mjs} +6 -6
  44. package/dist/{list-CZj0dzKY.mjs → list-BnPrIsU_.mjs} +6 -6
  45. package/dist/log-vqY3pqwI.mjs +29 -0
  46. package/dist/{login-UZKFM_u7.mjs → login-BuiMyUrx.mjs} +8 -8
  47. package/dist/login-DIy9Sb-U.mjs +2 -0
  48. package/dist/{logs-CUZ6t9t3.mjs → logs-CZG9d-ic.mjs} +10 -11
  49. package/dist/migrate-BCiJ8w0f.mjs +2 -0
  50. package/dist/{migrate-DHul7PRV.mjs → migrate-q4_njtaW.mjs} +2 -2
  51. package/dist/{operator-args-CLgKGlwU.mjs → operator-args-B3BTmSoi.mjs} +12 -5
  52. package/dist/{operator-auth-8KnOVXVd.mjs → operator-auth-7erYc6Lt.mjs} +2 -2
  53. package/dist/{operator-client-DUwumHpQ.mjs → operator-client-CpHjTd0t.mjs} +3 -3
  54. package/dist/{operator-cmd-DBA6dl0m.mjs → operator-cmd-DGqPJUD3.mjs} +6 -6
  55. package/dist/{output-Dm_A4Tbv.mjs → output-CbM85T4k.mjs} +18 -10
  56. package/dist/pages/index.mjs +1 -1
  57. package/dist/{platform-args-BJdRtlLq.mjs → platform-args-3k8X9-H_.mjs} +11 -3
  58. package/dist/platform-args-DdnM6WIf.mjs +2 -0
  59. package/dist/{platform-auth-config-B56E9YP1.mjs → platform-auth-config-DDrxUy4m.mjs} +6 -6
  60. package/dist/{platform-auth-protection-BDWO_aER.mjs → platform-auth-protection-BLadnnct.mjs} +8 -8
  61. package/dist/{platform-auth-recovery-1gg4CSRe.mjs → platform-auth-recovery-CmCzX2Fl.mjs} +6 -6
  62. package/dist/{platform-cmd-DMcQStSc.mjs → platform-cmd-DMDEc9uS.mjs} +10 -10
  63. package/dist/{platform-cmd-Bt-1w6pY.mjs → platform-cmd-pMTRhvYs.mjs} +1 -1
  64. package/dist/{platform-domain-BNkcz0OB.mjs → platform-domain-Di6EYrQl.mjs} +5 -5
  65. package/dist/{platform-lifecycle-9OyBALhH.mjs → platform-lifecycle-BBoNzojY.mjs} +1264 -407
  66. package/dist/{platform-lifecycle-BE6C_jxh.mjs → platform-lifecycle-BFdSi9Qt.mjs} +1 -1
  67. package/dist/{platform-management-CjwLVQwN.mjs → platform-management-CWOQOWXm.mjs} +5 -5
  68. package/dist/{platform-management-CnyTdcWX.mjs → platform-management-DG47jys8.mjs} +1 -1
  69. package/dist/{platform-plans-config-BNGKGr4P.mjs → platform-plans-config-Vl9BP3H4.mjs} +3 -3
  70. package/dist/{platform-recovery-D6KSpuFm.mjs → platform-recovery-BJnQJEtQ.mjs} +4 -4
  71. package/dist/{platform-registry-QBa4DK32.mjs → platform-registry-DkPPXfp_.mjs} +2 -2
  72. package/dist/{prepare-B5Mkic5u.mjs → prepare-CBLT3CHH.mjs} +3 -3
  73. package/dist/prepare-CnjcTV2s.mjs +2 -0
  74. package/dist/{prepare-DOsL0CC9.mjs → prepare-DnaKBi--.mjs} +1 -1
  75. package/dist/{project-C0Fqu05O.mjs → project-DKG5Ra8p.mjs} +15 -82
  76. package/dist/project-DsblYifa.mjs +2 -0
  77. package/dist/{project-cmd-CNzrqvBv.mjs → project-cmd-DxnXstAq.mjs} +19 -19
  78. package/dist/{project-team-DQOWPfQT.mjs → project-team-BmHcaALJ.mjs} +5 -5
  79. package/dist/{project-token-CTDYU0Cc.mjs → project-token-GionZlBI.mjs} +5 -5
  80. package/dist/{project-zero-trust-BNAkW-_0.mjs → project-zero-trust-JLCjVQA7.mjs} +5 -5
  81. package/dist/prompts-2TGE6oXx.mjs +2 -0
  82. package/dist/prompts-BNUoTiaf.mjs +2044 -0
  83. package/dist/{provision-C4ORE7G7.mjs → provision-CVku1JFU.mjs} +1 -1
  84. package/dist/{provision-CJFgTZY8.mjs → provision-CaoxO_U7.mjs} +1 -1
  85. package/dist/{requests-MhxYnau8.mjs → requests-BOjIVAeF.mjs} +5 -5
  86. package/dist/{rollback-CJ6iSDoU.mjs → rollback-CwR3pLj3.mjs} +6 -6
  87. package/dist/runtime/ai.mjs +3 -5
  88. package/dist/runtime/email/testing.mjs +1 -1
  89. package/dist/runtime/email.mjs +1 -1
  90. package/dist/runtime/remote/index.mjs +2 -2
  91. package/dist/{secret-Dli5fP0B.mjs → secret-ByWJWBUG.mjs} +7 -7
  92. package/dist/{skills-D1II1Juz.mjs → skills-C1PlclPt.mjs} +1 -1
  93. package/dist/{subcommand-prompt-CY1C4fvl.mjs → subcommand-prompt-klFCfcor.mjs} +40 -32
  94. package/package.json +8 -9
  95. package/skills/void/SKILL.md +6 -1
  96. package/skills/void/docs/guide/deployment.md +22 -0
  97. package/skills/void/docs/guide/edge/headers.md +1 -1
  98. package/skills/void/docs/guide/email/domains.md +5 -1
  99. package/skills/void/docs/guide/email/sending.md +1 -1
  100. package/skills/void/docs/guide/platform/administration/zero-trust.md +27 -9
  101. package/skills/void/docs/guide/platform/installation/ci.md +1 -1
  102. package/skills/void/docs/guide/platform/installation/credentials.md +10 -3
  103. package/skills/void/docs/guide/platform/installation/domains.md +8 -3
  104. package/skills/void/docs/guide/platform/installation/first-deployment.md +2 -2
  105. package/skills/void/docs/guide/platform/installation/maintenance.md +12 -0
  106. package/skills/void/docs/guide/platform/installation/prerequisites.md +8 -7
  107. package/skills/void/docs/guide/platform/installation/setup.md +80 -10
  108. package/skills/void/docs/guide/remote-dev.md +1 -1
  109. package/skills/void/docs/reference/cli/auth.md +4 -3
  110. package/skills/void/docs/reference/cli/database.md +1 -1
  111. package/skills/void/docs/reference/cli/deploy.md +20 -0
  112. package/skills/void/docs/reference/cli/platform-installation.md +42 -27
  113. package/skills/void/docs/reference/cli/platform-zero-trust.md +14 -0
  114. package/skills/void/docs/reference/config.md +1 -1
  115. package/dist/auth-CCjt0hcq.mjs +0 -2
  116. package/dist/client-Cu7jWiF1.mjs +0 -2
  117. package/dist/dist-BuDuKZJv.mjs +0 -2
  118. package/dist/dist-CTBk70IR.mjs +0 -1310
  119. package/dist/gen-BVaUUumi.mjs +0 -2
  120. package/dist/help-DofyZuY7.mjs +0 -2
  121. package/dist/log-ChfPKsVd.mjs +0 -26
  122. package/dist/login-DYt_An22.mjs +0 -2
  123. package/dist/migrate-8_2u55MD.mjs +0 -2
  124. package/dist/platform-args-D3RXyR6h.mjs +0 -2
  125. package/dist/prepare-cgvDMtSb.mjs +0 -2
  126. package/dist/project-BuUwfj6f.mjs +0 -2
@@ -28,6 +28,13 @@ existing gate, verify that its service policy admits the installation token and
28
28
  that the application covers the printed API and proxy origins. A Cloudflare
29
29
  management API token does not authenticate an Access-protected HTTP request.
30
30
 
31
+ For automatic setup, resuming also creates or verifies an Access exception
32
+ limited to `/health` on the reserved dispatch health hostname. Void still requires
33
+ its private probe token on that endpoint; requests without it cannot reach an
34
+ application. This lets installation check routing while employee protection and
35
+ account-wide Default-Deny remain enabled. It does not bypass Access for an entire
36
+ Worker or for deployed apps.
37
+
31
38
  For externally supplied credentials, set `VOID_ACCESS_CREDENTIALS` from your
32
39
  secret manager to an object keyed by each exact API/proxy origin, with
33
40
  `CF_ACCESS_CLIENT_ID` and `CF_ACCESS_CLIENT_SECRET` in each entry. Then rerun
@@ -35,6 +42,11 @@ secret manager to an object keyed by each exact API/proxy origin, with
35
42
  and stops if the gate still rejects its checks. Account-wide Default-Deny and
36
43
  deployed-application policies remain your responsibility.
37
44
 
45
+ If **System Status** reports `proxy HTTP 302 (redirect)` on an older Access-protected
46
+ installation, upgrade with `void platform upgrade <id>`. Current installations use
47
+ a private connection for the dashboard's proxy health check. Keep the proxy's
48
+ Access protection enabled.
49
+
38
50
  ### Expired administrator setup code
39
51
 
40
52
  Resume an unfinished installation with `void platform install --resume --name <id>`.
@@ -8,7 +8,7 @@ To run a Void platform, you need:
8
8
 
9
9
  - A Cloudflare account with Workers for Platforms and R2 enabled.
10
10
  - An empty hosted PostgreSQL database.
11
- - An account with your chosen login provider. GitHub is the default; Google, OIDC, and Cloudflare Access are also supported.
11
+ - An account with your chosen login provider: GitHub, Google, OIDC, or Cloudflare Access.
12
12
  - A domain for your apps, or `workers.dev` for testing. You can [add a domain later](/guide/platform/installation/domains#adding-a-domain).
13
13
 
14
14
  Void creates the Workers, storage, queues, routing, and database tables through the CLI.
@@ -19,9 +19,10 @@ Workers for Platforms requires a paid plan. Your database and Cloudflare usage a
19
19
 
20
20
  In the [Cloudflare dashboard](https://dash.cloudflare.com/), select the account where you want the platform to live:
21
21
 
22
- 1. Open **Workers for Platforms** and enable its plan. Review [Workers for Platforms pricing](https://developers.cloudflare.com/cloudflare-for-platforms/workers-for-platforms/platform/pricing/) before confirming.
23
- 2. Open **R2 Object Storage** and complete its activation. Void creates the bucket later.
24
- 3. For a domain installation, choose a domain you own, such as `example.app`. If you need one, register it with your preferred registrar. Use a spare domain's root: apps will be served at `my-app.example.app`. For workers.dev testing, skip this step and the DNS setup below.
22
+ 1. Open **Workers & Pages** once to let Cloudflare provision Workers for the account.
23
+ 2. Open **Workers for Platforms** and enable its plan. Review [Workers for Platforms pricing](https://developers.cloudflare.com/cloudflare-for-platforms/workers-for-platforms/platform/pricing/) before confirming.
24
+ 3. Open **R2 Object Storage** and complete its activation. Void creates the bucket later.
25
+ 4. For a domain installation, choose a domain you own, such as `example.app`. If you need one, register it with your preferred registrar. Use a spare domain's root: apps will be served at `my-app.example.app`. For workers.dev testing, skip this step and the DNS setup below.
25
26
 
26
27
  If that domain is already in this Cloudflare account, use its existing zone. Otherwise, [add the domain to Cloudflare](https://developers.cloudflare.com/dns/zone-setups/full-setup/setup/) and follow the nameserver instructions until the zone is active. A zone is Cloudflare's DNS configuration for a domain; creating one does not buy the domain.
27
28
 
@@ -36,7 +37,7 @@ pnpm add --global void
36
37
  void platform install --plan
37
38
  ```
38
39
 
39
- Sign in to Cloudflare when prompted, then choose an installation name and account. `--plan` previews the resources without changing them or requiring runtime secrets.
40
+ Sign in to Cloudflare when prompted, then choose an installation name and account. `--plan` previews the resources without changing them or requiring runtime secrets. Completed plans save your choices locally. Run `void platform install` again to select a saved plan; Void checks the current Cloudflare state before asking you to apply it.
40
41
 
41
42
  For a domain installation, use these answers. Testing mode skips the application domain, zone, and catch-all questions:
42
43
 
@@ -51,7 +52,7 @@ For a domain installation, use these answers. Testing mode skips the application
51
52
 
52
53
  Choose an unused installation name in your account. For example, `team` creates resources such as `void-team-api` and `void-team-proxy`.
53
54
 
54
- The preview includes your login callback URL and links for creating credentials. Keep it open while following [Credentials](/guide/platform/installation/credentials), then run the install command printed at the end.
55
+ The preview lists the credentials you will need. Review [Credentials](/guide/platform/installation/credentials), then run the install command printed at the end. The guided installation provides setup links and the login callback when needed.
55
56
 
56
57
  You can select either path directly:
57
58
 
@@ -87,7 +88,7 @@ Once installation claims the database, continue using that same database for res
87
88
  The installer can create Hyperdrive for you or use one you manage separately. For an existing configuration:
88
89
 
89
90
  1. Point it at the dedicated platform database using a runtime user, and disable SQL result caching.
90
- 2. Select it in the installer and confirm the database, host, port, and runtime user.
91
+ 2. Select it in the installer and review the database, host, port, and runtime user.
91
92
  3. Supply a database owner connection at the PostgreSQL URL prompt so Void can apply migrations.
92
93
 
93
94
  To create one first, choose **Set up a separately managed Hyperdrive** and follow the printed instructions or [Cloudflare’s setup guide](https://developers.cloudflare.com/hyperdrive/get-started/). Rerun the installer once it is ready. Void leaves its configuration under your control. For unattended setup, use the Hyperdrive variables in [Install from CI](/guide/platform/installation/ci).
@@ -4,13 +4,19 @@ outline: deep
4
4
 
5
5
  # Install and Configure Login
6
6
 
7
+ Press Enter to accept a suggested zone or display name, or type to replace it. Enter your own installation name and application domain; examples such as `company` and `example.com` are placeholders.
8
+
7
9
  For workers.dev testing, start the interactive install and choose your login method below:
8
10
 
9
11
  ```sh
10
12
  void platform install --workers-dev
11
13
  ```
12
14
 
13
- For a domain installation, the management token is the one value the interactive installer needs in the shell. Browser login cannot create the application's DNS record. In Bash or zsh, read the token without displaying it or putting its value in command history:
15
+ For a domain installation or Access setup, Void guides you to create a management API token and paste it into a masked prompt. Browser login can preview DNS, but cannot change it or configure Access. The token-creation link preselects the permissions for your choices; scope the token to your account and, when using a domain, its zone. No shell environment variable is needed for interactive installation.
16
+
17
+ ::: details Use an existing management token from the shell
18
+
19
+ Set `CLOUDFLARE_API_TOKEN` to use an existing token instead of the prompt. In Bash or zsh, read it without displaying it or putting its value in command history:
14
20
 
15
21
  ```sh
16
22
  printf 'Cloudflare management API token: '
@@ -20,7 +26,7 @@ export CLOUDFLARE_API_TOKEN
20
26
  void platform install
21
27
  ```
22
28
 
23
- ::: details PowerShell equivalent
29
+ In PowerShell:
24
30
 
25
31
  ```powershell
26
32
  $env:CLOUDFLARE_API_TOKEN = [System.Net.NetworkCredential]::new('', (Read-Host 'Cloudflare management API token' -AsSecureString)).Password
@@ -29,14 +35,66 @@ void platform install
29
35
 
30
36
  :::
31
37
 
32
- After reviewing `--plan`, run the command printed under **Next step: run this command to install**. It carries your choices into installation. Confirm the plan, then follow the credential prompts. Void opens the relevant setup pages and provides fallback links in the terminal. It reuses values you have already supplied.
38
+ After reviewing `--plan`, run `void platform install` and select your saved plan, or run the command printed under **Next, run this command to install the platform**. Both carry your choices into installation and check the current Cloudflare state. Review the refreshed plan. At **Apply this plan?**, **Yes** is selected; press Enter to continue to the credential prompts, or choose **No** to stop. Void opens the relevant setup pages and provides fallback links in the terminal. It reuses values you have already supplied.
39
+
40
+ Saved plans contain your installation choices, including paths to any authentication configuration or custom runtime. They contain no secrets or approval to install. Declining the plan or cancelling management-token setup keeps those choices for your next attempt.
33
41
 
34
42
  ## Choose login methods
35
43
 
36
- The installer offers GitHub, Google, generic OIDC, and Cloudflare Access login.
44
+ The installer offers GitHub, Google, generic OIDC, and Cloudflare Access login. Select all methods you want to enable; none are selected initially.
37
45
  Cloudflare Access protection is a separate choice from Access login. The
38
46
  GitHub OAuth steps below apply when you select GitHub login.
39
47
 
48
+ ## Choose who can access apps
49
+
50
+ The installer asks **Who should be able to access deployed apps?**
51
+
52
+ - **Same people allowed by the platform’s Access policy** reuses your selected company identities and policies. This is recommended when platform Access protection is enabled.
53
+ - **Anyone — public apps** allows public visits.
54
+ - **Choose a different Access policy** selects separate company rules for apps. Without platform protection, this option is **Set up Cloudflare Access protection**.
55
+
56
+ The plan shows the default app access. Void finishes and verifies app access before
57
+ opening application traffic; new projects inherit the selected default automatically.
58
+ If setup stops, use the printed resume command. Existing installations retain their
59
+ administrator settings during upgrades.
60
+
61
+ App protection uses the account hosting your platform. If platform login or
62
+ protection uses another account, select equivalent identity providers and policies
63
+ in the hosting account when prompted. Use the app domain’s apex or a workers.dev
64
+ hostname for the API so it stays outside the app wildcard.
65
+
66
+ Void checks account-wide Default-Deny during setup. For public apps in an account
67
+ that requires Access rules, it creates rules for each app and its verified custom
68
+ domains. Other subdomains keep their existing access rules. It leaves account-wide
69
+ Default-Deny enabled and does not bypass the platform API or proxy.
70
+
71
+ App rules need **Access: Apps and Policies Edit** and **Organizations, Identity
72
+ Providers, and Groups Read**. Void stores this management token encrypted for future
73
+ apps and domain changes. The installer asks before retaining a setup-only token for
74
+ that purpose, or guides you to create a dedicated token. Public apps without
75
+ Default-Deny need no ongoing Access-management credential.
76
+
77
+ For scripts, use `--app-access public|platform|custom`. Supply
78
+ `VOID_PLATFORM_APP_ACCESS_TOKEN` when app rules are needed, or add an `appAccess`
79
+ section to your `--auth-config` file:
80
+
81
+ ```json
82
+ {
83
+ "appAccess": {
84
+ "mode": "custom",
85
+ "identityProviderIds": ["hosting-account-identity-provider-id"],
86
+ "policyIds": ["hosting-account-company-policy-id"],
87
+ "tokenEnv": "APP_ACCESS_API_TOKEN"
88
+ }
89
+ }
90
+ ```
91
+
92
+ Keep the file’s existing `connections` configuration. For `mode: "platform"`,
93
+ same-account identity and policy selections are reused. Headless setup requires an
94
+ explicit app-management token; it never silently retains an installer-only token.
95
+
96
+ ## Finish login configuration
97
+
40
98
  For Google, create an OAuth client and register the printed callback URL. You
41
99
  can restrict it to named Google Workspace domains. For OIDC or Access login,
42
100
  provide the issuer URL, client ID, and client secret. Select **Company-approved
@@ -86,6 +144,10 @@ with GitHub or another login method. With company-approved signup, a colleague
86
144
  who passes the company gate can create an ordinary account using GitHub even
87
145
  when their GitHub email differs from their company email.
88
146
 
147
+ Your identity provider determines how employees sign in, such as through Okta or
148
+ Google Workspace. Your Access policies determine who can reach the platform and
149
+ which MFA or device requirements apply.
150
+
89
151
  Automatic setup uses an existing Zero Trust organization, selected identity
90
152
  providers, and existing company policies. Void creates dedicated applications
91
153
  and a scoped service token for protected installation checks. It preserves your
@@ -94,9 +156,13 @@ company policies, including device and MFA requirements.
94
156
  The setup credential needs **Access: Apps and Policies Write** and
95
157
  **Access: Organizations, Identity Providers, and Groups Read** in the identity
96
158
  account. Creating protection also needs **Access: Service Tokens Write**.
97
- Provide a separate setup token through `VOID_PLATFORM_ACCESS_SETUP_TOKEN` if
98
- your Cloudflare management credential lacks these permissions. These permissions
99
- are not required by the platform's runtime token. See Cloudflare's
159
+ For setup in the installation account, the initial management-token link includes
160
+ these permissions. Void checks Access reads before provisioning and reuses that
161
+ management token during Access setup, so you do not need a second API token.
162
+ For applications in another account, provide a token scoped to that identity
163
+ account when asked. Scripts can supply an explicit override through
164
+ `VOID_PLATFORM_ACCESS_SETUP_TOKEN`. The platform's runtime token does not need
165
+ Access management permissions. See Cloudflare's
100
166
  [Access API](https://developers.cloudflare.com/api/resources/zero_trust/subresources/access/subresources/applications/)
101
167
  and [service-token permissions](https://developers.cloudflare.com/api/resources/zero_trust/subresources/access/subresources/service_tokens/methods/create/).
102
168
 
@@ -117,7 +183,9 @@ Keep the file's `connections` list from the example above, or use a connection
117
183
  with `{"id":"access","kind":"cloudflare-access","label":"Company Access"}`
118
184
  to create Access login as well. Omit `protection` for login-only setup.
119
185
 
120
- To connect applications managed elsewhere, select **Connect existing applications**.
186
+ To connect applications managed elsewhere, select **Use Access applications your company already manages**.
187
+ Enter the account that owns the Access applications; it can differ from the
188
+ account hosting Void.
121
189
  Scripts use `mode: "existing"`, optional `accountId`, and `loginApplicationId`
122
190
  and/or `protectionApplicationId`. For login, set `loginClientSecretEnv`. For
123
191
  protection, supply `serviceToken` with `id`, `clientIdEnv`, and `clientSecretEnv`
@@ -148,7 +216,7 @@ The installer collects your runtime token, PostgreSQL URL, login-provider creden
148
216
 
149
217
  Once installation finishes, open the printed admin dashboard link. For GitHub-only setup, sign in as the administrator selected during installation. For configurable login, use the one-time `/setup` code to confirm the administrator’s identity. Use the printed API URL to [connect and deploy an app](/guide/platform/installation/first-deployment).
150
218
 
151
- Remove the management token from the shell when finished:
219
+ If you supplied a management token through the shell, remove it when finished:
152
220
 
153
221
  ```sh
154
222
  unset CLOUDFLARE_API_TOKEN
@@ -164,10 +232,12 @@ If Void created a zone, it stops in `waiting-for-dns` and prints nameservers. Se
164
232
  void platform install --resume --name <installation-id>
165
233
  ```
166
234
 
167
- Keep the management token available for any remaining DNS changes. When using a source build, also pass the same `--runtime` directory. Resume uses the saved checkpoint and original secrets; do not start a second installation or generate replacement keys. If setup failed before a checkpoint was saved, rerun the original command.
235
+ Resume reuses the saved management token and asks for one if it is missing or rejected by Cloudflare. You can override it through `CLOUDFLARE_API_TOKEN`. When using a source build, also pass the same `--runtime` directory. Resume uses the saved checkpoint and original secrets; do not start a second installation or generate replacement keys. If setup stopped before a checkpoint was saved, rerun `void platform install` and select your saved plan, or rerun the original command.
168
236
 
169
237
  You can also rerun `void platform install` and choose **Continue setup** for an unfinished installation. For non-interactive recovery, use `--resume --name <id>`. Manage completed platforms with `platform status`, `repair`, or `upgrade`.
170
238
 
239
+ Resume restores your selected Hyperdrive. If that selection is missing from the saved checkpoint, add `--hyperdrive <existing-id>` when resuming, using the same configuration you originally selected.
240
+
171
241
  If Cloudflare rejects a saved runtime token during continued credential setup, Void opens the token page and asks for a replacement in the same run. Network or service failures do not discard saved tokens. Tokens supplied through the environment must be corrected there instead.
172
242
 
173
243
  :::
@@ -49,7 +49,7 @@ AI requests use your platform’s account and allowance in both local and remote
49
49
  When the dev server starts with remote mode active, it prints:
50
50
 
51
51
  ```
52
- ⚡ Remote bindings active (my-project.void.app)
52
+ ⚡ Remote bindings active (my-project.apps.example.com)
53
53
  DB → remote D1
54
54
  KV → remote KV
55
55
  STORAGE → remote R2
@@ -41,11 +41,12 @@ are Void account operations. Prefer `void auth status`, `void account link`, and
41
41
 
42
42
  Browser login through one of the platform's currently enabled methods. The token is saved in the operating-system keychain, scoped to the platform origin. Login fails closed when no keychain is available instead of writing the token to a plaintext file; headless environments use `VOID_TOKEN` from their secret manager.
43
43
 
44
- If an older CLI login is no longer recognized after updating Void, run `void account login` again. Your saved platform and project links remain unchanged.
44
+ Connect to a platform with `void connect <url>` before logging in. If an older project link has no platform URL, connect and run `void project link` to select its project again.
45
45
 
46
46
  Set `VOID_API_URL` alongside `VOID_TOKEN` to identify the platform that issued it.
47
- A token without an API URL is only used for Void Cloud's production API; a saved
48
- connection or project cannot forward it to another platform. To use a platform's
47
+ Both the URL and token are required for environment-based authentication, and the
48
+ URL must already be connected. In a fresh CI environment, run
49
+ `void connect "$VOID_API_URL" --no-login` before deploying. To use a platform's
49
50
  saved login instead, unset `VOID_TOKEN`.
50
51
 
51
52
  This is optional if you already completed auth during `void connect` or the interactive `void init` flow.
@@ -52,7 +52,7 @@ Run ad-hoc SQL against the database. Provide SQL inline or from a file. SELECT q
52
52
 
53
53
  By default, targets the local database. Pass `--remote` to run against the deployed database selected in `.void/project.json`:
54
54
 
55
- - **Void platform D1 projects**: routes the query through the selected platform's registered proxy using your auth token. Void Cloud's proxy is `proxy.void.cloud`; a self-hosted platform uses its own proxy URL.
55
+ - **Void platform D1 projects**: routes the query through the selected platform's registered proxy using your auth token.
56
56
  - **Direct Cloudflare D1 projects**: invokes Cloudflare against the pinned D1 binding from `void.config.ts` or `void.lock.json`.
57
57
  - **Hosted PostgreSQL and MySQL projects**: fetches the stored connection string from the platform and connects directly.
58
58
  - **Direct Cloudflare PostgreSQL and MySQL projects**: uses `DATABASE_URL` from the current shell; Cloudflare cannot return the password from Hyperdrive.
@@ -14,8 +14,14 @@ void deploy --platform cloudflare --atomic
14
14
 
15
15
  Auto-detects your project type and chooses the right pipeline. See [Supported App Types](../../guide/app-types.md) and [Deployment](../../guide/deployment.md) for details.
16
16
 
17
+ Deploying to a Void platform requires an explicit connection with `void connect <url>`.
18
+ A saved project URL or `VOID_API_URL` alone does not establish a connection.
19
+ In fresh CI environments, run `void connect "$VOID_API_URL" --no-login` first.
20
+
17
21
  On an upgraded Void platform, an accepted deployment continues if the CLI disconnects. The CLI automatically reconnects to its progress. Pressing Ctrl+C stops observation; use `void project cancel` to request cancellation and `void project status` to inspect the result. If interrupted execution requires recovery, wait for its result before deploying again.
18
22
 
23
+ The CLI reports stalled progress and automatic recovery, and waits up to 30 minutes after acceptance. If it times out, the deployment can continue; check `void project status` before trying another deployment.
24
+
19
25
  For an existing Void Worker, `void deploy` can link the Worker and migrate its root Cloudflare config. Keep the first deployment focused on the existing app. See [Deploy an existing Worker](../../integrations/cloudflare.md#deploy-an-existing-worker) for requirements and the ISR cache choice.
20
26
 
21
27
  For Drizzle projects, deploy performs a read-only schema drift check. If a new migration would be generated, deploy stops and tells you to run `void db generate`, review the migration, commit it yourself, and rerun `void deploy`.
@@ -53,6 +59,20 @@ For the Void platform, project resolution precedence is:
53
59
 
54
60
  If no project is linked and no override is provided, CLI prompts to link or create one. In CI (non-TTY), `void deploy` errors out instead — set `VOID_PROJECT` or pass `--project <slug>`.
55
61
 
62
+ To deploy to another connected Void platform for one invocation:
63
+
64
+ ```sh
65
+ void connect https://second.example.com
66
+ VOID_API_URL=https://second.example.com void deploy --platform void --project my-app
67
+ ```
68
+
69
+ `VOID_API_URL` selects the platform and `--project` selects its project. You must
70
+ name the project when overriding a different platform's saved link. Existing
71
+ project links and deployment preferences remain unchanged, even when the target
72
+ project is created. The same applies to `VOID_PROJECT` and to another project on
73
+ the current platform. A first deployment still links the project when no destination
74
+ is configured. See [Deploy to another Void platform](../../guide/deployment.md#deploy-to-another-void-platform).
75
+
56
76
  ## `void deploy --platform cloudflare` {#void-deploy-platform-cloudflare}
57
77
 
58
78
  Build and deploy to your Cloudflare account using `void.config.ts`:
@@ -8,32 +8,33 @@ outline: deep
8
8
  void platform install [options] [--yes]
9
9
  ```
10
10
 
11
- | Option | Purpose |
12
- | --------------------------------- | ------------------------------------------------------------------------------------ |
13
- | `--name <slug>` | Installation name used in `void-<name>-<role>` resource names; choose an unused name |
14
- | `--display-name <name>` | Human-readable platform name |
15
- | `--account <id>` | Cloudflare account id |
16
- | `--auth-config <path>` | Login methods, signup policy, and environment references for provider secrets |
17
- | `--login-methods <methods>` | Comma-separated `github`, `google`, `oidc`, or `cloudflare-access` login methods |
18
- | `--access-protection` | Protect the platform UI and APIs with Cloudflare Access |
19
- | `--no-access-protection` | Skip Cloudflare Access protection |
20
- | `--hyperdrive <create\|id>` | Create Hyperdrive or use the specified existing configuration |
21
- | `--application-domain <domain>` | Base domain for deployed apps |
22
- | `--workers-dev` | Explicit testing mode; add an application domain later |
23
- | `--zone <domain>` | Cloudflare zone containing the application domain |
24
- | `--dedicated-zone` | Add zone-wide catch-all routes; valid only when the app domain is the whole zone |
25
- | `--no-dedicated-zone` | Skip zone-wide application catch-all routes |
26
- | `--control-plane-domain <domain>` | Optional API custom hostname; defaults to `workers.dev` |
27
- | `--no-control-plane-domain` | Use the default `workers.dev` API hostname |
28
- | `--dashboard-url <origin>` | HTTPS origin of an optional dashboard deployed separately |
29
- | `--plan` | Resolve and print a read-only plan |
30
- | `--resume` | Continue the matching checkpointed installation |
31
- | `--runtime <path>` | Deploy a locally built, integrity-checked runtime directory |
32
- | `--yes` | Acknowledge Cloudflare changes in non-interactive use |
33
-
34
- For a first installation, follow [Install a Void Platform](../../guide/self-hosted-platform.md). The interactive installer recommends using a domain and offers **Use workers.dev for testing** as a visible alternative. Void creates the platform infrastructure and tables. External PostgreSQL and a configured login method are required in either mode; GitHub OAuth is the default login choice, not a requirement. `--workers-dev` skips zone/DNS/certificate operations and cannot be combined with `--application-domain`, `--zone`, or `--dedicated-zone`.
35
-
36
- Read-only plans, workers.dev installations with the default API hostname, and supported lifecycle operations can use Cloudflare browser login and the system keychain. Installation that writes DNS or creates a zone needs an explicit management token through `CLOUDFLARE_API_TOKEN` or `CF_API_TOKEN`.
11
+ | Option | Purpose |
12
+ | ----------------------------------------- | ------------------------------------------------------------------------------------ |
13
+ | `--name <slug>` | Installation name used in `void-<name>-<role>` resource names; choose an unused name |
14
+ | `--display-name <name>` | Human-readable platform name |
15
+ | `--account <id>` | Cloudflare account id |
16
+ | `--auth-config <path>` | Login methods, signup policy, and environment references for provider secrets |
17
+ | `--login-methods <methods>` | Comma-separated `github`, `google`, `oidc`, or `cloudflare-access` login methods |
18
+ | `--access-protection` | Protect the platform UI and APIs with Cloudflare Access |
19
+ | `--no-access-protection` | Skip Cloudflare Access protection |
20
+ | `--app-access <public\|platform\|custom>` | Public apps, the platform's Access policy, or separately selected app policies |
21
+ | `--hyperdrive <create\|id>` | Create Hyperdrive or use the specified existing configuration |
22
+ | `--application-domain <domain>` | Base domain for deployed apps |
23
+ | `--workers-dev` | Explicit testing mode; add an application domain later |
24
+ | `--zone <domain>` | Cloudflare zone containing the application domain |
25
+ | `--dedicated-zone` | Add zone-wide catch-all routes; valid only when the app domain is the whole zone |
26
+ | `--no-dedicated-zone` | Skip zone-wide application catch-all routes |
27
+ | `--control-plane-domain <domain>` | Optional API custom hostname; defaults to `workers.dev` |
28
+ | `--no-control-plane-domain` | Use the default `workers.dev` API hostname |
29
+ | `--dashboard-url <origin>` | HTTPS origin of an optional dashboard deployed separately |
30
+ | `--plan` | Preview Cloudflare changes and save installation choices locally |
31
+ | `--resume` | Continue the matching checkpointed installation |
32
+ | `--runtime <path>` | Deploy a locally built, integrity-checked runtime directory |
33
+ | `--yes` | Acknowledge Cloudflare changes in non-interactive use |
34
+
35
+ For a first installation, follow [Install a Void Platform](../../guide/self-hosted-platform.md). The interactive installer recommends using a domain and offers **Use workers.dev for testing** as a visible alternative. Void creates the platform infrastructure and tables. External PostgreSQL and a configured login method are required in either mode. Select all login methods you want to enable; none are selected initially. Non-interactive installation defaults to GitHub when no login configuration is supplied. `--workers-dev` skips zone/DNS/certificate operations and cannot be combined with `--application-domain`, `--zone`, or `--dedicated-zone`.
36
+
37
+ Read-only plans, workers.dev installations with the default API hostname, and supported lifecycle operations can use Cloudflare browser login and the system keychain. Installation that writes DNS or creates a zone needs a management API token. The interactive installer guides you to create one and paste it into a masked prompt; scripts use `CLOUDFLARE_API_TOKEN` or `CF_API_TOKEN`.
37
38
 
38
39
  The installed platform needs a separate runtime token to provision resources for apps. The interactive installer prompts for it and the other setup values. For non-interactive installs, inject the variables listed in [Install from CI](../../guide/platform/installation/ci.md).
39
40
 
@@ -45,10 +46,24 @@ path, query, or fragment. Void permits that origin's login callbacks and saves
45
46
  it for later maintenance; it does not deploy a dashboard Worker. Omission keeps
46
47
  an existing installation's saved dashboard origin.
47
48
 
48
- `--plan` previews resource names, login methods, callback URLs, and credential requirements. Run the install or resume command printed at the end to continue. For login configuration, use either `--auth-config` or `--login-methods` with the Access protection flags.
49
+ `--plan` previews resource names, login methods, default app access, the login callback URL, database configuration, and credential requirements. An existing Hyperdrive shows its database and configuration name. Setup links are shown during guided credential setup. Completed previews save nonsecret installation choices locally. Rerun `void platform install` to choose a saved plan and review a fresh check of Cloudflare state, or run the install or resume command printed at the end. Started installations use their saved checkpoints; completed installations are excluded from the chooser. For login configuration, use either `--auth-config` or `--login-methods` with the Access protection flags.
50
+
51
+ App access is configured before traffic opens. With platform protection enabled,
52
+ the installer recommends reusing its company policy; otherwise it defaults to
53
+ public apps. Use `--app-access custom` to select separate hosting-account policies.
54
+ Public apps in a Default-Deny account receive scoped public Access rules. The
55
+ installer explains and collects the encrypted management credential when needed;
56
+ scripts supply `VOID_PLATFORM_APP_ACCESS_TOKEN` or `appAccess.tokenEnv` in the
57
+ authentication file. Upgrades preserve administrator settings.
49
58
 
50
59
  New resources use `void-<name>-<role>` names; choose an unused installation name. The installer opens setup pages for missing credentials and reuses values already supplied.
51
60
 
61
+ During Access setup, choose existing company policies or **Create new** for manual
62
+ setup instructions and an account dashboard link. After you save the policy and
63
+ confirm completion, Void reloads the list so you can select it and continue in the
64
+ same run. **Refresh list** reloads policies created in another window. Your
65
+ identity-provider choice and still-available policy selections are retained.
66
+
52
67
  Installation progress and partial credentials are saved encrypted locally. Rerun the installer to continue unfinished setup, or pass `--resume --name <id>`. Use lifecycle commands for completed installations.
53
68
 
54
69
  Use an empty PostgreSQL database dedicated to the installation. You can correct a failed initial connection, but after the database is claimed or Hyperdrive is provisioned, commands reject a different URL.
@@ -26,6 +26,20 @@ void platform zero-trust project-public <project-id>
26
26
  void platform zero-trust project-reconcile <project-id>
27
27
  ```
28
28
 
29
+ New installations configure app access in `void platform install`. Use these
30
+ commands to inspect or change it later. To configure or renew public-only rules
31
+ for a Default-Deny account, omit identity policies and use `--public-apps`:
32
+
33
+ ```sh
34
+ printf '%s' "$ACCESS_API_TOKEN" | void platform zero-trust configure \
35
+ --public-apps --token-stdin --yes
36
+ ```
37
+
38
+ Add `--existing-projects public` when enabling from a disabled configuration.
39
+ Public-only rules cannot be combined with protected project choices. To switch an
40
+ already protected configuration to public-only rules, first disable it; Access may
41
+ block traffic during that transition in a Default-Deny account.
42
+
29
43
  Mutations support `--plan`, `--yes`, and `--timeout`; use `--plan` instead of
30
44
  `--yes` to inspect this change without applying it. The Access management token
31
45
  is accepted only on standard input. Zero Trust uses the Cloudflare account that
@@ -156,7 +156,7 @@ Configuration for the [email integration](../guide/email.md).
156
156
 
157
157
  During development, `email.from` is the default sender in the local inbox. On a Void platform, use your project's shared sender or registered domain.
158
158
 
159
- For direct Cloudflare deployment, this address selects the mail domain and default sender. Use a zone or subdomain in your account; an existing mail provider's MX records are preserved. See [Email setup](../guide/email/domains.md#your-own-cloudflare-account).
159
+ For direct Cloudflare deployment, this address selects the mail domain and default sender. Use a zone or subdomain in your account; an existing mail provider's MX records are preserved. Without `email.from`, Void skips automatic setup and preserves authored `cloudflare.send_email` bindings and `cloudflare.addresses`; check their readiness yourself. `--require-email` still refuses deployment when automatic setup cannot be verified. See [Email setup](../guide/email/domains.md#your-own-cloudflare-account).
160
160
 
161
161
  ### `head`
162
162
 
@@ -1,2 +0,0 @@
1
- import { a as getApiUrl, h as runPlatformLogin, s as getSiteDomain } from "./auth-CSkdO2Bb.mjs";
2
- export { getApiUrl, getSiteDomain, runPlatformLogin };
@@ -1,2 +0,0 @@
1
- import { n as PlatformClient } from "./client-RV8NVeB8.mjs";
2
- export { PlatformClient };
@@ -1,2 +0,0 @@
1
- import { B as text, I as select, W as isCancel, j as log } from "./dist-CTBk70IR.mjs";
2
- export { isCancel, log, select, text };