void 0.20.0 → 0.20.2
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.
- package/README.md +5 -1
- package/dist/{auth-W9WII-mN.mjs → auth-DPl6kck4.mjs} +46 -26
- package/dist/{auth-cmd-CYVhSNFy.mjs → auth-cmd-gniL2fNt.mjs} +5 -4
- package/dist/auth-link-NZdjCmSc.mjs +28 -0
- package/dist/{build-cmd-CkVD1uOh.mjs → build-cmd-sI18tX_O.mjs} +3 -3
- package/dist/{cache-QcUfR-ff.mjs → cache-IHn5MwBC.mjs} +3 -3
- package/dist/{cancel-deploy-DsvWKFTe.mjs → cancel-deploy-C5qTOdLi.mjs} +3 -3
- package/dist/cf-access-DRsQRe6k.mjs +75 -0
- package/dist/cli/cli.mjs +364 -1883
- package/dist/cli/env-schema-probe.mjs +11 -2
- package/dist/{client-CyCHWSO_.mjs → client-dHfSJvAN.mjs} +336 -58
- package/dist/{cloudflare-auth-DRkGe7-s.mjs → cloudflare-auth-6M5llVPC.mjs} +53 -6
- package/dist/{cloudflare-cmd-D3ME2GAe.mjs → cloudflare-cmd-4RPGN3KB.mjs} +2 -2
- package/dist/{cloudflare-connect-BivMefMA.mjs → cloudflare-connect-t1UU5svD.mjs} +2 -2
- package/dist/{cloudflare-operations-CPTpRW6d.mjs → cloudflare-operations-BzWnlC1_.mjs} +1 -1
- package/dist/{config-BQFq7QvD.mjs → config-uNGuFsI2.mjs} +1 -1
- package/dist/{connect-D9Yr-T5f.mjs → connect-Bfk31O_8.mjs} +6 -6
- package/dist/{create-project-DMV-csEm.mjs → create-project-Bk9Z0-Jg.mjs} +6 -5
- package/dist/{db-BxoUWL0F.mjs → db-BkRoptAt.mjs} +75 -48
- package/dist/{delete-iJOqxBz1.mjs → delete-DouASY9P.mjs} +3 -3
- package/dist/{deploy-CcDoeBIf.mjs → deploy-DTaWUS1S.mjs} +137 -128
- package/dist/{dev-inbox-DkgRWLkW.mjs → dev-inbox-P0u4tM8Y.mjs} +1 -1
- package/dist/{domain-gu_iaHmn.mjs → domain-1RhhOVrC.mjs} +4 -4
- package/dist/email-C-lGh51B.mjs +795 -0
- package/dist/{env-D4Emu-M_.mjs → env-DBKmK4vc.mjs} +1 -0
- package/dist/{env-DmU2To0C.mjs → env-DJHsPE7Z.mjs} +5 -5
- package/dist/{env-validation-ENpMy6Ez.mjs → env-validation-CF6KvTRf.mjs} +3 -1
- package/dist/{gen-BKw6qHIg.mjs → gen-B_wPnVTK.mjs} +3 -3
- package/dist/generate-RTK8_kK1.mjs +47 -0
- package/dist/{github-cmd-DJS5Ab-H.mjs → github-cmd-PW7ZnWTp.mjs} +3 -3
- package/dist/{headers-D8QfRX9Y.mjs → headers-BAHwgHdW.mjs} +1 -1
- package/dist/help-CwOX-zmI.mjs +2216 -0
- package/dist/{inbound-BJ70in1n.d.mts → inbound-CH5Mksyy.d.mts} +37 -42
- package/dist/{inbound-CNKxb3FY.mjs → inbound-aVHEUhKo.mjs} +143 -101
- package/dist/index.mjs +69 -30
- package/dist/{init-Dx5cgKqK.mjs → init-BWZ7q5Z4.mjs} +11 -11
- package/dist/{link-D_rm5sRH.mjs → link-Rmvu2Wl_.mjs} +4 -4
- package/dist/{list-M8XShti7.mjs → list-DEE2S6mY.mjs} +4 -4
- package/dist/{local-d1-BE8KBbMy.mjs → local-d1-D2I6Ox5F.mjs} +1 -1
- package/dist/{login-C8-UuLnp.mjs → login-Uvferzmm.mjs} +28 -10
- package/dist/{logs-DwFU7dMW.mjs → logs-27FenuiC.mjs} +4 -4
- package/dist/{mime-BJD7d_qL.mjs → mime-D5Nmdzf7.mjs} +23 -9
- package/dist/{node-BkaXcpAc.mjs → node-Ez5KW5rn.mjs} +3 -3
- package/dist/operator-auth-B3e08unv.mjs +52 -0
- package/dist/operator-client-LUZnlnYk.mjs +82 -0
- package/dist/{operator-cmd-DYWRbWUA.mjs → operator-cmd-CjOTmAYE.mjs} +35 -55
- package/dist/{output-tFQLLj26.mjs → output-B0cfNSx5.mjs} +316 -2
- package/dist/pages/index.mjs +2 -2
- package/dist/platform-auth-config-DrbQXXiW.mjs +368 -0
- package/dist/platform-auth-protection-Bhtvp0B_.mjs +219 -0
- package/dist/platform-auth-recovery-CeOKGVeJ.mjs +310 -0
- package/dist/{platform-cmd-BEOVv1PN.mjs → platform-cmd-BFhieCdV.mjs} +16 -6
- package/dist/{platform-domain-BszUfiS8.mjs → platform-domain-C74PULqV.mjs} +4 -4
- package/dist/{platform-lifecycle-CjSr6xf0.mjs → platform-lifecycle-BwAIgz-t.mjs} +1667 -191
- package/dist/{platform-management-W30iCaTL.mjs → platform-management-COogu_Se.mjs} +33 -7
- package/dist/{platform-recovery-pHHv4ZSg.mjs → platform-recovery-ewqLefp1.mjs} +6 -5
- package/dist/{prepare-CBetXvsN.mjs → prepare-CtDJjoOj.mjs} +2 -2
- package/dist/{prepare-BfJvFUtJ.mjs → prepare-blNRQvQl.mjs} +2 -2
- package/dist/prerender-render.d.mts +11 -0
- package/dist/prerender-render.mjs +111 -0
- package/dist/{project-cmd-DCpk1cDt.mjs → project-cmd-DmZK9Hxf.mjs} +32 -14
- package/dist/project-team-D8jOJMUJ.mjs +130 -0
- package/dist/project-token-DA34bf-C.mjs +75 -0
- package/dist/{provision-Blnstcm2.mjs → provision-CSJOjjQk.mjs} +2 -0
- package/dist/{requests-Dn8Vheh1.mjs → requests-CUExwGQQ.mjs} +3 -3
- package/dist/{rollback-CtlPXEBi.mjs → rollback-CDNGU1gr.mjs} +4 -4
- package/dist/{runner-mysql-CgRFl3s6.mjs → runner-mysql-7BPUNGmL.mjs} +1 -1
- package/dist/{runner-pg-DCkWPsWS.mjs → runner-pg-BkEza-dX.mjs} +1 -1
- package/dist/runtime/ai.mjs +3 -2
- package/dist/runtime/email/testing.d.mts +1 -1
- package/dist/runtime/email/testing.mjs +3 -3
- package/dist/runtime/email-protocol.d.mts +15 -0
- package/dist/runtime/email-protocol.mjs +70 -0
- package/dist/runtime/email.d.mts +2 -2
- package/dist/runtime/email.mjs +189 -96
- package/dist/runtime/remote/index.mjs +5 -3
- package/dist/{secret-BqTxGqki.mjs → secret-Bzzi2e9E.mjs} +5 -5
- package/dist/{skills-Q46GZMO-.mjs → skills-C0RvGjeE.mjs} +1 -1
- package/dist/sqlite-validation-BzKMWnO4.mjs +25 -0
- package/dist/{subcommand-prompt-WfySCQ7S.mjs → subcommand-prompt-Bmyn5Rlc.mjs} +1 -1
- package/dist/{validate-Bihr8WBi.mjs → validate-tBBN_dXH.mjs} +1 -0
- package/package.json +12 -7
- package/skills/void/SKILL.md +35 -4
- package/skills/void/docs/guide/deployment.md +2 -0
- package/skills/void/docs/guide/email.md +121 -98
- package/skills/void/docs/guide/platform-administration.md +214 -2
- package/skills/void/docs/guide/platform-development.md +93 -2
- package/skills/void/docs/guide/project-collaboration.md +94 -0
- package/skills/void/docs/guide/self-hosted-platform.md +184 -30
- package/skills/void/docs/reference/cli.md +294 -15
- package/dist/cf-access-AJ1ehiFR.mjs +0 -42
- package/dist/cf-access-DsSsZUPr.mjs +0 -67
- package/dist/email-r6DHJyAB.mjs +0 -262
|
@@ -4,17 +4,17 @@ outline: deep
|
|
|
4
4
|
|
|
5
5
|
# Install a Void Platform
|
|
6
6
|
|
|
7
|
-
A Void platform lets your team deploy apps into a shared Cloudflare account. As an administrator, you install and maintain the platform. Developers connect the Void CLI to its URL, sign in
|
|
7
|
+
A Void platform lets your team deploy apps into a shared Cloudflare account. As an administrator, you install and maintain the platform. Developers connect the Void CLI to its URL, sign in through an enabled login method, and deploy their apps.
|
|
8
8
|
|
|
9
9
|
If you're deploying an app for yourself, [deploy directly to Cloudflare](../integrations/cloudflare.md#deploy-to-your-own-cloudflare-account). You don't need to install a platform first.
|
|
10
10
|
|
|
11
|
-
The core platform supports GitHub login, CLI deploys, D1, KV, R2, Queues, cron jobs, Workers AI, WebSockets, SSE, ISR, routing, logs, and rollback.
|
|
11
|
+
The core platform supports GitHub, Google, generic OIDC, and Cloudflare Access login, CLI deploys, D1, KV, R2, Queues, cron jobs, Workers AI, WebSockets, SSE, ISR, routing, logs, and rollback.
|
|
12
12
|
|
|
13
|
-
The user dashboard, GitHub builds and webhooks, build Containers,
|
|
13
|
+
The core installation includes an email gateway; email is enabled when you configure a shared mail domain and zone. The user dashboard, GitHub builds and webhooks, build Containers, custom project domains, and sandbox orchestration aren't part of the core installation. Source-built platforms that add the optional GitHub services should follow the [isolated webhook ingress setup](./platform-development.md#optional-github-webhook-ingress-for-access-protected-apis) when Access protects the API.
|
|
14
14
|
|
|
15
15
|
## Before You Start {#prerequisites}
|
|
16
16
|
|
|
17
|
-
Start with a Cloudflare account you can administer,
|
|
17
|
+
Start with a Cloudflare account you can administer, an account with your chosen login provider, and an empty hosted PostgreSQL database. GitHub is the default and is optional when another method is selected. A domain is recommended. If yours is not ready, choose **Use workers.dev for testing** during installation and [add a domain later](#add-a-domain-later). The steps below explain how to get the credentials the installer asks for.
|
|
18
18
|
|
|
19
19
|
Void creates the Workers, storage, queues, routing, and database tables through the CLI.
|
|
20
20
|
|
|
@@ -134,6 +134,12 @@ Use the following permissions for the core platform. Cloudflare may label write
|
|
|
134
134
|
|
|
135
135
|
The management token also needs **Zone Edit** with authority to create zones if you ask Void to create the zone. If it already exists, use the selected zone with Zone Read and DNS Edit. Nested application domains additionally need **SSL and Certificates: Read** on the management token. A custom runtime that enables custom project domains needs **SSL and Certificates: Edit** on the runtime token; the core runtime does not enable that feature.
|
|
136
136
|
|
|
137
|
+
Enabling email lets administrators [register email domains for projects](./platform-administration.md#registering-email-domains-for-projects) and lets projects register destination addresses through the runtime token. That needs **Email Routing Addresses: Edit** and **Email Sending: Edit** on the account, plus **Zone: Read**, **Zone Settings: Edit** and **Email Routing Rules: Edit** on the zones that will carry mail; the token link preselects them when email is enabled. Email Sending onboarding itself needs Workers Paid on the account.
|
|
138
|
+
|
|
139
|
+
To enable email, set `VOID_EMAIL_SENDER_DOMAIN` to the shared sender domain and `VOID_EMAIL_SHARED_ZONE_ID` to its Cloudflare zone ID when installing or upgrading. Void records both values for later upgrades and rejects attempts to replace them during an ordinary upgrade. The mail zone can differ from the application zone, but it must belong to the selected platform Cloudflare account; without an explicit mail-zone identity, shared inbound delivery stays unavailable. The dedicated email gateway is deployed in the platform account. Each customer zone uses its own ingress Worker to forward mail to that gateway.
|
|
140
|
+
|
|
141
|
+
The installer prepares the shared mail route and verifies inbound readiness before it opens platform traffic. If that setup fails, the installation remains disabled. Correct the reported Cloudflare permission, mail-zone configuration, or routing conflict, then rerun the same install or upgrade command; a fresh install resumes with `void platform install --resume --name <installation-id>`.
|
|
142
|
+
|
|
137
143
|
Void checks access before provisioning. If it reports a missing permission, update the token's permissions for the selected account or zone and retry.
|
|
138
144
|
|
|
139
145
|
:::
|
|
@@ -164,6 +170,8 @@ Paste it into your password manager as **JWT signing key**. Run the command agai
|
|
|
164
170
|
|
|
165
171
|
:::
|
|
166
172
|
|
|
173
|
+
When email is enabled, Void also creates an independent **Email signing key** for confirmation links and service-to-service email requests. The installer keeps it in encrypted recovery state. Set `VOID_PLATFORM_EMAIL_SIGNING_SECRET` to a separate value of at least 32 random bytes when you need an externally custodied copy, including a headless installation whose local recovery files will not persist.
|
|
174
|
+
|
|
167
175
|
## 5. Install and Connect GitHub {#install}
|
|
168
176
|
|
|
169
177
|
For workers.dev testing, start the interactive install and continue to the GitHub setup below:
|
|
@@ -193,7 +201,107 @@ void platform install
|
|
|
193
201
|
|
|
194
202
|
Use the same name, account, and domain as the preview, then confirm the installation plan. Void saves a local setup draft and opens the runtime-token page when that token is missing. Paste the token into the masked prompt. As you continue, it opens GitHub and R2 at their respective steps. Each page has a short checklist and a clickable fallback link in the terminal. Values already supplied through the environment or saved setup are reused without opening their pages again.
|
|
195
203
|
|
|
196
|
-
###
|
|
204
|
+
### Choose login methods {#configure-github-oauth}
|
|
205
|
+
|
|
206
|
+
The installer offers GitHub, Google, generic OIDC, and Cloudflare Access login.
|
|
207
|
+
Cloudflare Access protection is a separate choice from Access login. The
|
|
208
|
+
GitHub-only setup below retains the existing workflow.
|
|
209
|
+
|
|
210
|
+
For Google, create an OAuth client and register the printed callback URL. You
|
|
211
|
+
can restrict it to named Google Workspace domains. For OIDC or Access login,
|
|
212
|
+
provide the issuer URL, client ID, and client secret. Select **Company-approved
|
|
213
|
+
users** when the configured company policy should allow colleagues to create
|
|
214
|
+
accounts automatically without individual invitations.
|
|
215
|
+
|
|
216
|
+
When using the configurable setup, installation prints a one-time setup code
|
|
217
|
+
and a `/setup` URL. Enter the code, authenticate with the chosen administrator
|
|
218
|
+
method, and review the identity before confirming its administrator role. That
|
|
219
|
+
method becomes enabled; additional selected methods are saved as pending
|
|
220
|
+
configurations to test and enable in Settings. No GitHub account is required
|
|
221
|
+
for a Google-only or OIDC-only installation.
|
|
222
|
+
|
|
223
|
+
For scripts, pass `--auth-config <path>` with nonsecret configuration and
|
|
224
|
+
environment-variable references for secrets. For example:
|
|
225
|
+
|
|
226
|
+
```json
|
|
227
|
+
{
|
|
228
|
+
"connections": [
|
|
229
|
+
{
|
|
230
|
+
"configuration": {
|
|
231
|
+
"id": "google",
|
|
232
|
+
"kind": "google",
|
|
233
|
+
"label": "Company Google",
|
|
234
|
+
"clientId": "your-google-client-id",
|
|
235
|
+
"allowedDomains": ["example.com"]
|
|
236
|
+
},
|
|
237
|
+
"clientSecretEnv": "GOOGLE_CLIENT_SECRET"
|
|
238
|
+
}
|
|
239
|
+
],
|
|
240
|
+
"administratorConnectionId": "google",
|
|
241
|
+
"admission": {
|
|
242
|
+
"mode": "company",
|
|
243
|
+
"connections": ["google"],
|
|
244
|
+
"access": false
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
`--plan` reads this configuration without requiring the referenced secret.
|
|
250
|
+
Supply the secret through your secret manager when applying the installation.
|
|
251
|
+
|
|
252
|
+
#### Cloudflare Access {#cloudflare-access-setup}
|
|
253
|
+
|
|
254
|
+
Choose Access login, platform protection, or both. Protection can also be used
|
|
255
|
+
with GitHub or another login method. With company-approved signup, a colleague
|
|
256
|
+
who passes the company gate can create an ordinary account using GitHub even
|
|
257
|
+
when their GitHub email differs from their company email.
|
|
258
|
+
|
|
259
|
+
Automatic setup uses an existing Zero Trust organization, selected identity
|
|
260
|
+
providers, and existing company policies. Void creates dedicated applications
|
|
261
|
+
and a scoped service token for protected installation checks. It preserves your
|
|
262
|
+
company policies, including device and MFA requirements.
|
|
263
|
+
|
|
264
|
+
The setup credential needs **Access: Apps and Policies Write** and
|
|
265
|
+
**Access: Organizations, Identity Providers, and Groups Read** in the identity
|
|
266
|
+
account. Creating protection also needs **Access: Service Tokens Write**.
|
|
267
|
+
Provide a separate setup token through `VOID_PLATFORM_ACCESS_SETUP_TOKEN` if
|
|
268
|
+
your Cloudflare management credential lacks these permissions. These permissions
|
|
269
|
+
are not required by the platform's runtime token. See Cloudflare's
|
|
270
|
+
[Access API](https://developers.cloudflare.com/api/resources/zero_trust/subresources/access/subresources/applications/)
|
|
271
|
+
and [service-token permissions](https://developers.cloudflare.com/api/resources/zero_trust/subresources/access/subresources/service_tokens/methods/create/).
|
|
272
|
+
|
|
273
|
+
To automate Access setup, add this to the authentication configuration file:
|
|
274
|
+
|
|
275
|
+
```json
|
|
276
|
+
{
|
|
277
|
+
"protection": true,
|
|
278
|
+
"cloudflareAccess": {
|
|
279
|
+
"mode": "create",
|
|
280
|
+
"identityProviderIds": ["your-company-identity-provider-id"],
|
|
281
|
+
"policyIds": ["your-company-allow-policy-id"]
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
Keep the file's `connections` list from the example above, or use a connection
|
|
287
|
+
with `{"id":"access","kind":"cloudflare-access","label":"Company Access"}`
|
|
288
|
+
to create Access login as well. Omit `protection` for login-only setup.
|
|
289
|
+
|
|
290
|
+
To connect applications managed elsewhere, select **Connect existing applications**.
|
|
291
|
+
Scripts use `mode: "existing"`, optional `accountId`, and `loginApplicationId`
|
|
292
|
+
and/or `protectionApplicationId`. For login, set `loginClientSecretEnv`. For
|
|
293
|
+
protection, supply `serviceToken` with `id`, `clientIdEnv`, and `clientSecretEnv`
|
|
294
|
+
for a token already admitted by the application. The selected policies must
|
|
295
|
+
cover both printed API and proxy origins. Connecting existing resources needs
|
|
296
|
+
read access to their applications, policies, organization, identity providers,
|
|
297
|
+
groups, and service tokens; Void leaves their policies unchanged.
|
|
298
|
+
|
|
299
|
+
Access login alone can connect to another account using only its issuer, client
|
|
300
|
+
ID, and secret, without a `cloudflareAccess` block or Cloudflare management token.
|
|
301
|
+
Follow Cloudflare's [OIDC application guide](https://developers.cloudflare.com/cloudflare-one/access-controls/applications/http-apps/saas-apps/generic-oidc-saas/)
|
|
302
|
+
and register the exact callback printed by Void.
|
|
303
|
+
|
|
304
|
+
For the default GitHub-only setup:
|
|
197
305
|
|
|
198
306
|
1. The installer opens [GitHub's new OAuth App form](https://github.com/settings/applications/new) when it needs OAuth credentials. Sign in as the account that will own the login integration.
|
|
199
307
|
2. Set **Application name** to your platform's display name and **Homepage URL** to the API URL Void just printed.
|
|
@@ -251,7 +359,40 @@ void deploy --platform void --project my-first-app
|
|
|
251
359
|
|
|
252
360
|
The CLI stores login credentials in your system keychain, separately for each platform URL. With no URL, `void connect` offers Cloudflare or a Void platform; `void connect --platform void` offers saved platforms and an option to enter another URL.
|
|
253
361
|
|
|
254
|
-
|
|
362
|
+
For CI, create a bounded, project-scoped deploy credential while signed in as
|
|
363
|
+
the project owner:
|
|
364
|
+
|
|
365
|
+
```sh
|
|
366
|
+
void project token create --name ci --expires-in 30
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
Store the printed `VOID_TOKEN` and `VOID_API_URL` in the CI secret manager, then
|
|
370
|
+
use `void connect <url> --no-login` in a fresh checkout if connection metadata
|
|
371
|
+
is not committed. Rotate with `void project token renew <id>` and revoke with
|
|
372
|
+
`void project token revoke <id>`. A human login token is not a CI credential.
|
|
373
|
+
|
|
374
|
+
If Cloudflare Access protects the platform, Access proof and the project
|
|
375
|
+
credential are both required; the service token does not grant Void user or
|
|
376
|
+
operator authority. A deploy that uses prerendering or remote bindings calls
|
|
377
|
+
both the API and proxy, so store `VOID_ACCESS_CREDENTIALS` in the CI secret
|
|
378
|
+
manager with entries for both exact HTTPS origins. Include both entries even
|
|
379
|
+
when the same admitted service-token pair is used for both origins:
|
|
380
|
+
|
|
381
|
+
```json
|
|
382
|
+
{
|
|
383
|
+
"https://void-company-api.example.workers.dev": {
|
|
384
|
+
"CF_ACCESS_CLIENT_ID": "<service-token client ID>",
|
|
385
|
+
"CF_ACCESS_CLIENT_SECRET": "<service-token client secret>"
|
|
386
|
+
},
|
|
387
|
+
"https://void-company-proxy.example.workers.dev": {
|
|
388
|
+
"CF_ACCESS_CLIENT_ID": "<service-token client ID>",
|
|
389
|
+
"CF_ACCESS_CLIENT_SECRET": "<service-token client secret>"
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
`VOID_ACCESS_ORIGIN` can scope credentials to one origin only; setting it to
|
|
395
|
+
the API origin does not authorize proxy requests.
|
|
255
396
|
|
|
256
397
|
Use these commands to inspect connections and installations:
|
|
257
398
|
|
|
@@ -272,7 +413,7 @@ void platform signup allow github teammate
|
|
|
272
413
|
|
|
273
414
|
Void shows the proposed access change and asks you to confirm it. Once approved, `teammate` can connect to the platform's API URL and sign in with GitHub.
|
|
274
415
|
|
|
275
|
-
To see who can join, run `void platform signup show`. You can also allow an email address or a domain such as `*@example.com`. `void platform signup open` permits public signup; `void platform signup restrict` requires an allowlist match again.
|
|
416
|
+
To see who can join, run `void platform signup show`. You can also allow an email address or a domain such as `*@example.com`. For an OIDC user without verified email, use `void platform signup allow identity <connection-id> <subject>`; the subject match is exact and the provider's domain or group restrictions still apply. Remove that grant with `void platform signup disallow identity <connection-id> <subject>`. `void platform signup open` permits public signup; `void platform signup restrict` requires an allowlist match again.
|
|
276
417
|
|
|
277
418
|
Your administrator session lasts for one hour. Use it to inspect users, projects, logs, and platform health. The [Platform Administration guide](./platform-administration.md) walks through those workflows, previews, and automation. You can also open `<API origin>/admin/login` to use the browser admin UI.
|
|
278
419
|
|
|
@@ -325,17 +466,17 @@ The management token needs **SSL and Certificates: Read** (or Edit) on that zone
|
|
|
325
466
|
|
|
326
467
|
Resources use a `void-<installation-name>-<random-suffix>-*` prefix where Cloudflare allows names. This keeps installations recognizable and avoids predictable Worker names colliding during setup.
|
|
327
468
|
|
|
328
|
-
| Resource | Count | Purpose
|
|
329
|
-
| ----------------------------------------- | ------------------------------------: |
|
|
330
|
-
| Workers |
|
|
331
|
-
| KV namespaces | 3 | Routing, ISR cache, and static asset storage
|
|
332
|
-
| R2 buckets | 1 | Static and deployment assets
|
|
333
|
-
| Queues | 2 | Usage events and cron firing
|
|
334
|
-
| Workers for Platforms dispatch namespaces | 1 | User application Workers
|
|
335
|
-
| Hyperdrive configurations | 1 | External platform PostgreSQL
|
|
336
|
-
| AI Gateways | 1 | Installation-isolated AI routing and metering
|
|
337
|
-
| Proxied wildcard DNS records | 0 or 1 | Created only when an application domain is configured
|
|
338
|
-
| Zones | 0 or 1 | Created only when the requested application zone is absent
|
|
469
|
+
| Resource | Count | Purpose |
|
|
470
|
+
| ----------------------------------------- | ------------------------------------: | --------------------------------------------------------------------------------------------- |
|
|
471
|
+
| Workers | 5, plus one per app using workers.dev | API/control plane, proxy, tail ingestion, dispatch, email gateway, and test-origin forwarders |
|
|
472
|
+
| KV namespaces | 3 | Routing, ISR cache, and static asset storage |
|
|
473
|
+
| R2 buckets | 1 | Static and deployment assets |
|
|
474
|
+
| Queues | 2 | Usage events and cron firing |
|
|
475
|
+
| Workers for Platforms dispatch namespaces | 1 | User application Workers |
|
|
476
|
+
| Hyperdrive configurations | 1 | External platform PostgreSQL |
|
|
477
|
+
| AI Gateways | 1 | Installation-isolated AI routing and metering |
|
|
478
|
+
| Proxied wildcard DNS records | 0 or 1 | Created only when an application domain is configured |
|
|
479
|
+
| Zones | 0 or 1 | Created only when the requested application zone is absent |
|
|
339
480
|
|
|
340
481
|
The API Worker uses four Durable Object classes for usage, cron scheduling, error monitoring, and concurrency. Worker bindings create the request and log datasets in Analytics Engine. The core installation doesn't create Container applications, a GitHub App, a dashboard Worker, or build Workers.
|
|
341
482
|
|
|
@@ -357,18 +498,26 @@ You can correct the database URL if the initial connection failed. Once Void has
|
|
|
357
498
|
|
|
358
499
|
If installation reports **Default-Deny (error 1050)**, Cloudflare blocked the HTTP health check before it reached Void. This is separate from the API token used to deploy the Workers.
|
|
359
500
|
|
|
360
|
-
|
|
501
|
+
Keep the company protection in place. Automatic Access setup saves its scoped
|
|
502
|
+
service credentials with the installation's encrypted recovery material. For an
|
|
503
|
+
existing gate, verify that its service policy admits the installation token and
|
|
504
|
+
that the application covers the printed API and proxy origins. A Cloudflare
|
|
505
|
+
management API token does not authenticate an Access-protected HTTP request.
|
|
361
506
|
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
507
|
+
For externally supplied credentials, set `VOID_ACCESS_CREDENTIALS` from your
|
|
508
|
+
secret manager to an object keyed by each exact API/proxy origin, with
|
|
509
|
+
`CF_ACCESS_CLIENT_ID` and `CF_ACCESS_CLIENT_SECRET` in each entry. Then rerun
|
|
510
|
+
`void platform install --resume --name <id>`. Void retains the saved resources
|
|
511
|
+
and stops if the gate still rejects its checks. Account-wide Default-Deny and
|
|
512
|
+
deployed-application policies remain your responsibility.
|
|
366
513
|
|
|
367
|
-
|
|
514
|
+
### Expired administrator setup code
|
|
368
515
|
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
516
|
+
Resume an unfinished installation with `void platform install --resume --name <id>`.
|
|
517
|
+
For completed provisioning whose administrator setup is still pending, run
|
|
518
|
+
`void platform repair <id>`. Void prints a fresh setup code if the earlier code
|
|
519
|
+
expired. Enter it at `/setup`, sign in, and confirm the displayed identity.
|
|
520
|
+
An installation that already has an administrator does not reopen setup.
|
|
372
521
|
|
|
373
522
|
### Repair missing resources
|
|
374
523
|
|
|
@@ -428,7 +577,7 @@ void platform discover --account <account-id> --installation <id-or-name>
|
|
|
428
577
|
|
|
429
578
|
Discovery restores local installation records after verifying the resources belong to your platform. It also works for interrupted or disabled installations. If infrastructure is missing, run `void platform repair [id]` after discovery. If ownership cannot be verified, the command stops without changing resources.
|
|
430
579
|
|
|
431
|
-
After discovery, provide `VOID_PLATFORM_DATABASE_URL` for migrations and to coordinate administrator commands. You don't need to re-enter the other secrets for
|
|
580
|
+
After discovery, provide `VOID_PLATFORM_DATABASE_URL` for migrations and to coordinate administrator commands. You don't need to re-enter the other secrets for an upgrade that preserves every deployed Worker. For an email-enabled installation without its encrypted recovery file, restore `VOID_PLATFORM_EMAIL_SIGNING_SECRET`; recreating only the email gateway needs that key and no Cloudflare runtime token or JWT signing key. Recreating the API or proxy also requires the email key when email is enabled, in addition to their normal secrets. Recreating the API requires its original runtime token (`VOID_PLATFORM_RUNTIME_CLOUDFLARE_API_TOKEN`), GitHub, R2, JWT, and project-encryption values through the `VOID_PLATFORM_*` variables; recreating the proxy requires the runtime token and JWT signing key. Cloudflare can't return these values, so keep them in your organization's secret manager.
|
|
432
581
|
|
|
433
582
|
If you have not rotated the project-encryption key, restore it with `VOID_PLATFORM_PROJECT_SECRET_KEY`. After rotation, supply `VOID_PLATFORM_PROJECT_SECRET_KEYS_JSON` with all retained keys and `VOID_PLATFORM_PROJECT_SECRET_ACTIVE_KEY_VERSION` with the active key's name. Keep older keys needed to decrypt existing project secrets. These values are used to recreate a missing API Worker; they do not replace the live keys during an ordinary upgrade. Supply them from your secret manager.
|
|
434
583
|
|
|
@@ -439,7 +588,7 @@ If you have not rotated the project-encryption key, restore it with `VOID_PLATFO
|
|
|
439
588
|
Keep a coordinated recovery set for each installation:
|
|
440
589
|
|
|
441
590
|
- a PostgreSQL backup;
|
|
442
|
-
- the installation identity—the JWT signing secret and complete project-encryption keyring—in a secret manager;
|
|
591
|
+
- the installation identity—the JWT signing secret, the email signing secret when email is enabled, and the complete project-encryption keyring—in a secret manager;
|
|
443
592
|
- provider-supported backups or exports for every data-bearing provider resource;
|
|
444
593
|
- the immutable runtime artifacts and manifest for the installed version or custom source revision.
|
|
445
594
|
|
|
@@ -451,7 +600,7 @@ During a restore, keep platform and application traffic disabled before changing
|
|
|
451
600
|
|
|
452
601
|
Installation records live in `~/.void/platforms/`. Credentials are stored separately in encrypted recovery files, with the encryption key in your operating system's keychain. Keep your original secrets in a password manager for recovery on another machine.
|
|
453
602
|
|
|
454
|
-
If the keychain isn't available, Void stops before writing secrets. Headless environments can supply `VOID_PLATFORM_RECOVERY_KEY`: a canonical base64-encoded 32-byte key from a secret manager. A temporary CI runner can use a new recovery-encryption key for each run only when every original credential remains available in protected CI secrets, including `VOID_PLATFORM_JWT_SECRET` and either the original `VOID_PLATFORM_PROJECT_SECRET_KEY` or the complete rotated keyring and active-version pair.
|
|
603
|
+
If the keychain isn't available, Void stops before writing secrets. Headless environments can supply `VOID_PLATFORM_RECOVERY_KEY`: a canonical base64-encoded 32-byte key from a secret manager. A temporary CI runner can use a new recovery-encryption key for each run only when every original credential remains available in protected CI secrets, including `VOID_PLATFORM_JWT_SECRET`, `VOID_PLATFORM_EMAIL_SIGNING_SECRET` for an email-enabled installation, and either the original `VOID_PLATFORM_PROJECT_SECRET_KEY` or the complete rotated keyring and active-version pair.
|
|
455
604
|
|
|
456
605
|
::: details Ownership and interrupted maintenance
|
|
457
606
|
|
|
@@ -480,11 +629,16 @@ Inject the following values from protected CI secrets. Do not commit them in a w
|
|
|
480
629
|
| `VOID_PLATFORM_R2_ACCESS_KEY_ID` | R2 Access Key ID |
|
|
481
630
|
| `VOID_PLATFORM_R2_SECRET_ACCESS_KEY` | R2 Secret Access Key |
|
|
482
631
|
| `VOID_PLATFORM_JWT_SECRET` | Original JWT signing secret |
|
|
632
|
+
| `VOID_PLATFORM_EMAIL_SIGNING_SECRET` | Dedicated email signing secret when email is enabled |
|
|
483
633
|
| `VOID_PLATFORM_PROJECT_SECRET_KEY` | Original base64-encoded project-encryption key |
|
|
484
634
|
| `VOID_PLATFORM_RECOVERY_KEY` | Base64-encoded 32-byte key for local encrypted recovery state when no keychain is available |
|
|
635
|
+
| `VOID_EMAIL_SENDER_DOMAIN` | Optional shared mail domain; requires `VOID_EMAIL_SHARED_ZONE_ID` |
|
|
636
|
+
| `VOID_EMAIL_SHARED_ZONE_ID` | Cloudflare zone ID for that mail domain; requires `VOID_EMAIL_SENDER_DOMAIN` |
|
|
485
637
|
|
|
486
638
|
Use that installation's saved signing and encryption keys on every resume or repair that needs them. After a keyring rotation, use the [complete keyring recovery inputs](#manage-an-installation-from-another-machine). The database claim and tables remain after uninstall; use a fresh database for a different installation.
|
|
487
639
|
|
|
640
|
+
Set both email values to enable email during install or upgrade. Later upgrades reuse the recorded values. If an email-enabled installation has no recorded values, supply both before upgrading.
|
|
641
|
+
|
|
488
642
|
```sh
|
|
489
643
|
void platform install \
|
|
490
644
|
--name team \
|