void 0.20.2 → 0.20.3

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 (68) hide show
  1. package/dist/{auth-cmd-gniL2fNt.mjs → auth-cmd-CzwquNiP.mjs} +3 -3
  2. package/dist/{auth-link-NZdjCmSc.mjs → auth-link-ElDTgF7j.mjs} +3 -3
  3. package/dist/{build-cmd-sI18tX_O.mjs → build-cmd-BpJe6boP.mjs} +1 -1
  4. package/dist/{cache-IHn5MwBC.mjs → cache-D98YTqeE.mjs} +1 -1
  5. package/dist/{cancel-deploy-C5qTOdLi.mjs → cancel-deploy-CPbEQLMG.mjs} +1 -1
  6. package/dist/cli/cli.mjs +27 -26
  7. package/dist/{client-dHfSJvAN.mjs → client-BQBrZoCX.mjs} +143 -78
  8. package/dist/{connect-Bfk31O_8.mjs → connect-WCQZ_u3m.mjs} +3 -3
  9. package/dist/{create-project-Bk9Z0-Jg.mjs → create-project-D0oXA090.mjs} +2 -3
  10. package/dist/{db-BkRoptAt.mjs → db-DJ-9qs3S.mjs} +2 -2
  11. package/dist/{delete-DouASY9P.mjs → delete-BZ4-WaGm.mjs} +1 -1
  12. package/dist/{deploy-DTaWUS1S.mjs → deploy-BAhhcg5q.mjs} +17 -10
  13. package/dist/{domain-1RhhOVrC.mjs → domain-BxAyhxXN.mjs} +1 -1
  14. package/dist/{email-C-lGh51B.mjs → email-Bj7Cvdwp.mjs} +2 -2
  15. package/dist/{env-DJHsPE7Z.mjs → env-DP_EErve.mjs} +1 -1
  16. package/dist/{github-cmd-PW7ZnWTp.mjs → github-cmd-C-z_xRrQ.mjs} +13 -19
  17. package/dist/index.mjs +4 -4
  18. package/dist/{init-BWZ7q5Z4.mjs → init-BGktCXgA.mjs} +4 -4
  19. package/dist/{link-Rmvu2Wl_.mjs → link-D2kbqhWb.mjs} +2 -2
  20. package/dist/{list-DEE2S6mY.mjs → list-CvkK_G7k.mjs} +1 -1
  21. package/dist/{login-Uvferzmm.mjs → login-WIjNc77c.mjs} +2 -2
  22. package/dist/{logs-27FenuiC.mjs → logs-dLUFCapG.mjs} +1 -1
  23. package/dist/{operator-cmd-CjOTmAYE.mjs → operator-cmd-CKJ7xIRs.mjs} +2 -2
  24. package/dist/{platform-auth-config-DrbQXXiW.mjs → platform-auth-config-CdVWRRJr.mjs} +2 -2
  25. package/dist/{platform-auth-protection-Bhtvp0B_.mjs → platform-auth-protection-Drl0qhrn.mjs} +2 -2
  26. package/dist/{platform-auth-recovery-CeOKGVeJ.mjs → platform-auth-recovery-CmKEWpDo.mjs} +2 -2
  27. package/dist/{platform-cmd-BFhieCdV.mjs → platform-cmd-5q_k56xS.mjs} +3 -3
  28. package/dist/{platform-domain-C74PULqV.mjs → platform-domain-4GiDlcqx.mjs} +2 -2
  29. package/dist/{platform-lifecycle-BwAIgz-t.mjs → platform-lifecycle-R9xAxvtG.mjs} +61 -25
  30. package/dist/{platform-management-COogu_Se.mjs → platform-management-BfWsXHEW.mjs} +5 -3
  31. package/dist/{platform-recovery-ewqLefp1.mjs → platform-recovery-CbK-I1FB.mjs} +2 -2
  32. package/dist/{project-cmd-DmZK9Hxf.mjs → project-cmd-CTdmnzvc.mjs} +12 -12
  33. package/dist/{project-team-D8jOJMUJ.mjs → project-team-CGxsQe3_.mjs} +4 -2
  34. package/dist/{project-token-DA34bf-C.mjs → project-token-Cirx7uwZ.mjs} +1 -1
  35. package/dist/{requests-CUExwGQQ.mjs → requests-4Nq59hOr.mjs} +1 -1
  36. package/dist/{rollback-CDNGU1gr.mjs → rollback-Dr7u0Ljx.mjs} +1 -1
  37. package/dist/runtime/remote/index.mjs +49 -8
  38. package/dist/runtime/sandbox.d.mts +4 -56
  39. package/dist/runtime/sandbox.mjs +81 -220
  40. package/dist/{secret-Bzzi2e9E.mjs → secret-AcPi-FoA.mjs} +1 -1
  41. package/package.json +7 -7
  42. package/skills/void/SKILL.md +2 -2
  43. package/skills/void/docs/guide/deployment.md +14 -14
  44. package/skills/void/docs/guide/email.md +12 -10
  45. package/skills/void/docs/guide/platform/administration/access.md +163 -0
  46. package/skills/void/docs/guide/platform/administration/email.md +121 -0
  47. package/skills/void/docs/guide/platform/administration/operations.md +97 -0
  48. package/skills/void/docs/guide/platform/administration/projects.md +54 -0
  49. package/skills/void/docs/guide/platform/development/local.md +119 -0
  50. package/skills/void/docs/guide/platform/development/runtime.md +124 -0
  51. package/skills/void/docs/guide/platform/development/schema-ci.md +95 -0
  52. package/skills/void/docs/guide/platform/installation/ci.md +55 -0
  53. package/skills/void/docs/guide/platform/installation/credentials.md +80 -0
  54. package/skills/void/docs/guide/platform/installation/domains.md +68 -0
  55. package/skills/void/docs/guide/platform/installation/first-deployment.md +82 -0
  56. package/skills/void/docs/guide/platform/installation/maintenance.md +137 -0
  57. package/skills/void/docs/guide/platform/installation/prerequisites.md +86 -0
  58. package/skills/void/docs/guide/platform/installation/setup.md +169 -0
  59. package/skills/void/docs/guide/platform/installation/uninstall.md +54 -0
  60. package/skills/void/docs/guide/platform-administration.md +6 -414
  61. package/skills/void/docs/guide/platform-development.md +5 -316
  62. package/skills/void/docs/guide/project-collaboration.md +1 -1
  63. package/skills/void/docs/guide/sandboxes.md +9 -24
  64. package/skills/void/docs/guide/self-hosted-platform.md +11 -694
  65. package/skills/void/docs/reference/api.md +34 -34
  66. package/skills/void/docs/reference/cli.md +28 -11
  67. package/skills/void/docs/reference/config.md +1 -1
  68. package/skills/void/docs/reference/resource-inference.md +10 -10
@@ -6,419 +6,11 @@ outline: deep
6
6
 
7
7
  `void platform` lets you manage the people and apps on a Void platform from your terminal. You can give teammates access, inspect their projects, follow deployment logs, and check the platform's health.
8
8
 
9
- These commands require an administrator account. If you're setting up a platform for the first time, start with [Install a Void Platform](./self-hosted-platform.md).
9
+ The operator commands for users, projects, deployments, and system status require an administrator account. Connection and installation lifecycle commands use their own authentication. If you're setting up a platform for the first time, start with [Install a Void Platform](/guide/self-hosted-platform).
10
10
 
11
- ## Signing In
11
+ ## Administration Guides
12
12
 
13
- For the browser dashboard, open `<API URL>/admin` and sign in with GitHub. On a new installation, signing in with the administrator account selected during setup creates the first admin user. You do not need to create an app or sign in through the CLI first.
14
-
15
- Connect to your platform's API URL, then sign in as an administrator:
16
-
17
- ```sh
18
- void connect https://platform.example.com --no-login
19
- void platform auth login
20
- ```
21
-
22
- The first command saves the connection. The second opens your browser to sign in and saves an administrator session in your system keychain. Sessions last for one hour and are stored separately for each platform.
23
-
24
- You can check which account is signed in at any time:
25
-
26
- ```sh
27
- void platform auth status
28
- ```
29
-
30
- This shows your account, the session's expiry, and the features available on the platform. To end the session, run `void platform auth logout`.
31
-
32
- If the platform is protected by Cloudflare Access, `void connect <url>` handles
33
- the company sign-in before Void login. Interactive Access authentication uses a
34
- locally installed `cloudflared` and saves its short-lived credential in your
35
- system keychain for that platform origin. You do not need to copy browser cookies.
36
-
37
- For CI, Access credentials do not replace Void deployment credentials. A project
38
- owner creates the latter with `void project token create`; it is independently
39
- revocable, expires within 90 days, and authorizes only that project's deploy
40
- workflow. Human and operator tokens cannot be renewed by Access service proof.
41
-
42
- Store Access credentials in origin-keyed `VOID_ACCESS_CREDENTIALS`. A deploy
43
- that uses prerendering or remote bindings needs entries for both the exact API
44
- and proxy HTTPS origins, even when both entries contain the same admitted
45
- service-token pair. `VOID_ACCESS_ORIGIN` selects only one recipient and therefore
46
- cannot cover both calls. Keep the JSON value in your secret manager, not in
47
- application configuration. See [CI deployment setup](./self-hosted-platform.md#connect-and-deploy-an-app)
48
- for the required shape.
49
-
50
- ## Choosing a Platform
51
-
52
- If you manage more than one platform, list your connections and choose a default:
53
-
54
- ```sh
55
- void platform list
56
- void platform use <connection-id>
57
- ```
58
-
59
- You can also select a platform for a single command with `--connection`:
60
-
61
- ```sh
62
- void platform user list --connection <connection-id>
63
- ```
64
-
65
- Use an ID or URL from the connection list. Administrative commands use this selection even when you run them inside an app with a different deployment destination.
66
-
67
- ## Recovering Administrator Login
68
-
69
- If no administrator can use the configured identity provider, the installation
70
- owner can recover an existing administrator with Cloudflare management access,
71
- direct database access, and the original encrypted recovery credentials:
72
-
73
- ```sh
74
- void platform config auth recover company --installation <id> --file recovery.json
75
- ```
76
-
77
- The file identifies the existing account, for example
78
- `{"administratorUserId":"existing-admin-id"}`. Recovery opens a real login test
79
- and asks you to confirm the exact identity before restoring access. It does not
80
- create a new administrator. To use a replacement provider, include its nonsecret
81
- `configuration` with a new connection ID and supply the secret through
82
- `--client-secret-env <name>`. To rotate an existing provider's secret, keep its
83
- connection ID and identity configuration.
84
-
85
- For `--yes`, also pin `expectedIdentity` with the exact `issuer` and `subject` in
86
- the file. A successful browser login is still required. Use `--plan` to preview
87
- the affected administrator and connection before starting recovery.
88
-
89
- ## Giving People Access
90
-
91
- Open **Settings** in the administrator UI, or run `void platform config auth`,
92
- to add, test, enable, or disable login methods. Access protection and login
93
- methods are separate settings. A provider test shows the authenticated account
94
- before you explicitly link it or enable the configuration.
95
-
96
- To change the company gate after installation, use the installing workstation
97
- with its saved recovery credentials:
98
-
99
- ```sh
100
- void platform config auth protection show
101
- void platform config auth protection enable --installation <id>
102
- void platform config auth protection disable --installation <id>
103
- ```
104
-
105
- Enabling offers application creation or connection to an existing application.
106
- It checks every API, proxy, and configured dashboard origin and requires a company
107
- user sign-in. Changing protection ends all current human sessions; sign in again
108
- afterwards. Before removing a gate used for company signup, select another
109
- verified company rule or restricted signup. Removing protection retains the
110
- Cloudflare applications for deliberate cleanup. Disabling an Access login method
111
- does not remove the gate.
112
-
113
- Users can add another enabled login to their existing account with
114
- `void auth link <connection-id>` or **Account** in the optional
115
- dashboard. Sign in again first if prompted, then authenticate with the additional
116
- provider and confirm the identity shown. Matching email addresses alone do not
117
- link accounts.
118
-
119
- For company installations, choose **Company-approved users** under **Who can
120
- join?** to create accounts automatically for users accepted by your configured
121
- company rules. Individual invitations are not required. Invited/allowlisted
122
- signup remains available when you need to approve people individually.
123
-
124
- With invited/allowlisted signup selected, let a teammate join with GitHub by adding their login to the allowlist:
125
-
126
- ```sh
127
- void platform signup allow github teammate
128
- ```
129
-
130
- Void shows the change and asks you to confirm it. The teammate can then run `void connect` with the platform's URL and sign in.
131
-
132
- You can allow an email address or a whole email domain in the same way:
133
-
134
- ```sh
135
- void platform signup allow email teammate@example.com
136
- void platform signup allow email '*@example.com'
137
- ```
138
-
139
- Email patterns apply across the platform's sign-in providers. Quote a domain pattern so your shell passes the `*` to Void.
140
-
141
- For an OIDC login without a verified email, allow the identity by its login connection and stable provider subject instead:
142
-
143
- ```sh
144
- void platform signup allow identity company-sso 'Employee-42'
145
- ```
146
-
147
- Use the connection ID shown by `void platform config auth list` and the exact subject reported by your identity provider. The match is case-sensitive and does not infer an email address or link another account. Any domain or group restrictions configured for that login method still apply, and the account joins as an ordinary user. Remove the grant with `void platform signup disallow identity company-sso 'Employee-42'`.
148
-
149
- To invite someone else by email, use:
150
-
151
- ```sh
152
- void platform invitation send alex@example.org
153
- ```
154
-
155
- An invitation grants signup access and sends an email when the platform has email delivery configured. If delivery is unavailable or fails, the result tells you; the person can still join using the platform's URL.
156
-
157
- Inspect the current access settings and invitations with:
158
-
159
- ```sh
160
- void platform signup show
161
- void platform invitation list
162
- ```
163
-
164
- Invitation history remains available after an involved account is removed. The stored actor ID
165
- remains visible when that account's login no longer exists.
166
-
167
- `void platform signup open` allows anyone to sign up. Use `void platform signup restrict` to require an allowlist match again. Disallowing an entry affects future signup; it does not suspend an existing account.
168
-
169
- ## Managing Users and Projects
170
-
171
- Start by finding the user you want to inspect:
172
-
173
- ```sh
174
- void platform user list --search teammate
175
- void platform user show <user-id>
176
- ```
177
-
178
- Use the ID from the list in the second command. The detail view shows the user's projects and usage. You can change their plan or list just their projects:
179
-
180
- ```sh
181
- void platform user plan <user-id> pro
182
- void platform project list --user <user-id>
183
- void platform project show <project-id>
184
- ```
185
-
186
- Project details include resources, domains, and recent builds and deployments. The [command reference](../reference/cli.md#operator-commands) also covers suspending and restoring users, deleting projects, and removing accounts.
187
-
188
- ### Transferring Project Ownership
189
-
190
- Only an installation administrator can change a project's owner. The new owner must already have an account on this platform. Preview the transfer before applying it:
191
-
192
- ```sh
193
- void platform project owner <project-id> <new-owner-user-id> --plan
194
- void platform project owner <project-id> <new-owner-user-id> --yes
195
- ```
196
-
197
- The preview shows both owners, their plans and suspension state, active work that blocks the transfer, and the changes to routing and usage counters. Wait for or cancel any active deploy, rollback, or build before retrying.
198
-
199
- After the transfer, the former owner becomes a project administrator. Existing project-scoped CI deploy credentials are revoked; create replacements as the new owner. The new owner's plan and limits apply immediately. Usage before the transfer remains charged to the former owner; later usage is charged to the new owner. If an apply reports partial convergence, inspect the project and operator event log before repeating it.
200
-
201
- New users on a self-hosted installation start with the `custom` profile, which
202
- does not cap application requests, AI usage, deployment frequency, or retained
203
- Worker deployments. Named profiles such as `pro` apply the platform's quota and
204
- retention policies; they do not purchase Cloudflare services or bill your users.
205
- Storage figures are not a hard storage-quota boundary. Set an operating budget
206
- and retention policy before opening signup beyond your invited team.
207
-
208
- The last active administrator cannot be deleted or suspended, including through
209
- the browser admin UI. Another administrator must still have access. Automatic
210
- usage limits do not remove administrator access and do not count as a manual
211
- suspension.
212
-
213
- When removing another administrator, Void revokes their administrator access
214
- before changing application traffic or deleting resources. If cleanup fails,
215
- access stays revoked and the error describes the partial result. A remaining
216
- administrator can inspect it and retry cleanup.
217
-
218
- ## Managing Email
219
-
220
- These commands apply to a platform that enables email. Every project can send from and receive at `<slug>+tag@<mail domain>` on the platform's shared mail domain; the [email guide](./email.md) describes what applications do with that.
221
-
222
- ### Deciding who mail may reach
223
-
224
- By default, mail from the shared sender reaches only the recipients each project has verified. For a team whose applications mainly mail colleagues, widen that once for the whole installation:
225
-
226
- ```sh
227
- void platform email policy
228
- void platform email policy-set domains --domains example.com,corp.example.net
229
- void platform email policy-set any
230
- void platform email policy-set verified
231
- ```
232
-
233
- `domains` lets every project mail any address on the listed domains in addition to its verified recipients; `any` lifts the check. Cloudflare still refuses a recipient it has not verified until your mail domain is onboarded for Email Sending, which needs Workers Paid on the platform's account. Until then such sends come back as `UNVERIFIED_DESTINATION` for that recipient, whatever the policy says. Two things the policy never changes: sends from a project's own custom domain, and mail to any address on the platform's own mail domain — those stay verified-recipient-only, so no project reaches another project's inbox without its consent. A tightening applies to new send admissions as soon as it commits; previously admitted attempts may finish. The same setting is on the admin UI's **Email** page.
234
-
235
- ### Project caps
236
-
237
- Each project has 200 recipient submissions per UTC calendar month and 10 in a rolling 60-second window by default. An attempt stays charged once it starts, including a failed or uncertain outcome. Raise or lower a project's caps by id or slug:
238
-
239
- ```sh
240
- void platform email limit hr-portal --monthly 2000 --burst 30
241
- ```
242
-
243
- The project's page in the admin UI shows the current values and clears an override.
244
-
245
- ### Recovering an interrupted send
246
-
247
- If a sender stops after beginning a provider call, its unresolved attempt blocks
248
- removal of the project or sender domain. Inspect the attempt ID and start time:
249
-
250
- ```sh
251
- void platform email attempts --project hr-portal
252
- ```
253
-
254
- First confirm that the original execution has ended through your Worker logs or
255
- incident records. Once the attempt is at least 24 hours old, resolve it with an
256
- audit reason that contains no recipient address or message content:
257
-
258
- ```sh
259
- void platform email attempt-resolve <attempt-id> --ended --reason "Original Worker execution ended; provider outcome could not be verified" --plan
260
- void platform email attempt-resolve <attempt-id> --ended --reason "Original Worker execution ended; provider outcome could not be verified"
261
- ```
262
-
263
- This records the send as `outcome_unknown` and releases its cleanup fence. The
264
- attempt remains charged and is never retried. If its 30-day delivery record has
265
- expired, only its recipient-free fence is removed. Do not resolve an attempt
266
- while its original execution may still be active.
267
-
268
- Inspect a project's retained receipt and recipient outcomes with:
269
-
270
- ```sh
271
- void platform email logs hr-portal --page 1 --limit 50 --json
272
- ```
273
-
274
- Logs include operation IDs, recorded outcomes, provider references, and error codes.
275
- After project deletion, use its project ID until the 30-day metadata retention
276
- period expires. Message bodies, subjects, attachments, and credentials are not logged.
277
-
278
- ### Registering email domains for projects
279
-
280
- Your users may hold no Cloudflare account. Tell the platform that administrators register email domains, so `void email domain add` prints the command to ask you for instead of opening a token-creation page:
281
-
282
- ```sh
283
- void platform email settings-set --domains admin
284
- ```
285
-
286
- Then register a domain for a project. The zone must be in the platform's Cloudflare account; the platform's own credential does the setup, and no Cloudflare credential is stored per domain:
287
-
288
- ```sh
289
- void platform email domain-add mail.example.com --project hr-portal
290
- void platform email domain-status mail.example.com
291
- void platform email domain-rotate-secret mail.example.com
292
- void platform email domains
293
- ```
294
-
295
- Name the exact mail domain: a subdomain such as `mail.example.com` when the apex already receives mail, otherwise the apex itself. `domain-status` reports inbound, outbound, and management readiness separately. Follow any required DNS or Cloudflare dashboard step, then use `domain-sync` to reconcile. Use `domain-rotate-secret` when you need to replace the zone ingress credential explicitly. Email Sending onboarding needs Workers Paid; after upgrading, `domain-sync` re-attempts it. For a zone in another Cloudflare account, pipe an API token for that account on standard input:
296
-
297
- ```sh
298
- void platform email domain-add mail.other.example --project hr-portal --token-stdin --yes < token.txt
299
- ```
300
-
301
- Project owners see administrator-registered domains in `void email domain list` and `status`; `status` names the `void platform email` command for any step they cannot take themselves, and `sync` and `remove` point them at `domain-sync` and `domain-remove`. A domain an owner registered before you switched to `admin` stays theirs to renew, sync and remove. The runtime token needs the email permissions listed in the [self-hosting guide](./self-hosted-platform.md#runtime-token-permissions) for this to work.
302
-
303
- A permission refusal leaves setup blocked. After correcting it, run `domain-sync`
304
- to resume that same setup operation; repeat `domain-rotate-secret` to resume a
305
- blocked rotation without replacing its staged secret. If project deletion leaves
306
- a blocked domain cleanup, correct the permission and run `domain-remove <domain>`
307
- to finish the retained cleanup. If its token has expired or been revoked, provide
308
- a replacement scoped to the same account and zone:
309
-
310
- ```sh
311
- void platform email domain-remove mail.other.example --token-stdin --yes < token.txt
312
- ```
313
-
314
- This recovery is available only after project deletion has begun and no other
315
- project uses the connection. For a live project, renew its token through
316
- `domain-add`. A timed-out Cloudflare
317
- mutation stays stopped because replay may duplicate a provider write. After
318
- confirming the original execution ended, wait 24 hours, inspect the exact
319
- routing, Worker, secret, catch-all, or Sending resource named by the preview,
320
- and use its recovery fence:
321
-
322
- ```sh
323
- void platform email operation-resolve <operation-id> --ended --outcome <applied|not-applied> --reason "Provider state verified" --plan
324
- void platform email operation-resolve <operation-id> --ended --outcome <applied|not-applied> --reason "Provider state verified"
325
- ```
326
-
327
- Run recovery with the same platform version that created the persisted intent.
328
- `applied` continues without replaying the write; `not-applied` permits that exact
329
- step to retry. Secret rotation keeps its staged generation, and removal resumes
330
- from the unresolved cleanup step. Age alone never authorizes a retry.
331
-
332
- Register administrator domains only after a platform upgrade has completed, and remove them before rolling the platform back to a version that predates this feature: an earlier runtime cannot use the platform credential for them and does not distinguish administrator-registered domains from owner-registered ones.
333
-
334
- ## Previewing Changes
335
-
336
- Commands that change the platform show the affected objects before asking for confirmation. To inspect a change without applying it, add `--plan`:
337
-
338
- ```sh
339
- void platform user suspend <user-id> --reason "Investigating unexpected traffic" --plan
340
- ```
341
-
342
- The preview shows which account will be suspended and the effect on its projects. Run the command again without `--plan` to confirm interactively, or use `--yes` when the change is ready to apply:
343
-
344
- ```sh
345
- void platform user suspend <user-id> --reason "Investigating unexpected traffic" --yes
346
- ```
347
-
348
- Scripts must use `--yes` to apply these changes. Authentication commands run directly and do not use `--plan` or `--yes`. After a change, `void platform system events` shows the administrator, affected objects, and recorded outcome.
349
-
350
- Changes can take longer when an account owns many resources. Requests that change the platform allow five minutes by default; use `--timeout` to set a different limit in seconds:
351
-
352
- ```sh
353
- void platform user delete <user-id> --timeout 600 --plan
354
- ```
355
-
356
- If a request times out or loses its connection, some work may already have finished. Check the affected objects and `system events` before retrying. Void reports partial results when it can and does not automatically repeat the change.
357
-
358
- ## Following Logs
359
-
360
- To investigate a deployment, find its ID and follow its runtime logs:
361
-
362
- ```sh
363
- void platform deployment list --project <project-id>
364
- void platform deployment logs <deployment-id> --since 10m --follow
365
- ```
366
-
367
- Runtime logs include application messages, exceptions, and HTTP status codes. Without `--follow`, the command reads a page of historical logs. Use `--since` to choose a duration, an ISO date, or a timestamp in milliseconds.
368
-
369
- Logs can become available after a request finishes. Following checks a five-minute overlap to pick up delayed records without printing them again. Records delayed longer than that may need a later historical query.
370
-
371
- Build logs use the build's ID:
372
-
373
- ```sh
374
- void platform build logs <build-id> --follow
375
- ```
376
-
377
- Following waits for the final logs before stopping, including diagnostics written after the build's status changes. For a GitHub Actions build, the command gives you the URL of its logs.
378
-
379
- ## Checking the Platform
380
-
381
- Use the overview to see recent activity, or run a health check to test the platform's services and database:
382
-
383
- ```sh
384
- void platform system overview
385
- void platform system health
386
- ```
387
-
388
- Health checks use the services configured for the selected platform. An unhealthy result exits with a nonzero status, so the same command can be used in a script.
389
-
390
- The browser dashboard's **System Status** checks refresh every 30 seconds. Failed checks show an HTTP status or connection error beside the service name. If the dashboard cannot refresh the checks, it reports that status is unavailable instead of displaying stale results.
391
-
392
- Use `void platform upgrade`, `repair`, `disable`, and `enable` to maintain your platform. See [platform maintenance](./self-hosted-platform.md#resume-repair-recover-and-upgrade).
393
-
394
- For disaster recovery, keep a matching PostgreSQL backup, provider data backups, installation identity and complete project-encryption keyring, and immutable runtime artifacts. Keep traffic disabled while restoring data, run `discover` to reconstruct verified local metadata, and review `repair --plan` before recreating missing installer-owned infrastructure. Neither command restores backed-up data. See [Prepare for disaster recovery](./self-hosted-platform.md#prepare-for-disaster-recovery) for the full sequence.
395
-
396
- ## Using Scripts
397
-
398
- Add `--json` to read a command's result from another program:
399
-
400
- ```sh
401
- void platform user list --page 1 --limit 50 --json
402
- void platform system health --json
403
- ```
404
-
405
- Results go to standard output. Command errors go to standard error as JSON and exit with a nonzero status. With `--follow`, each log response is a separate JSON line.
406
-
407
- Operator tokens expire after one hour. For CI, mint a new operator token at the start of each job from a valid full API login session belonging to an active administrator. Choose the platform explicitly, inject the full session as `VOID_TOKEN` from your secret manager, and capture the exchange output directly into the protected job environment:
408
-
409
- ```sh
410
- export VOID_API_URL=https://platform.example.com
411
- VOID_OPERATOR_TOKEN="$(
412
- printf '%s' "$VOID_TOKEN" | void platform auth token --token-stdin
413
- )" || exit 1
414
- export VOID_OPERATOR_TOKEN
415
- unset VOID_TOKEN
416
- void platform system health --json
417
- unset VOID_OPERATOR_TOKEN
418
- ```
419
-
420
- Disable shell tracing for the exchange and do not write either token to logs or plaintext files. A full API login session expires after 30 days and can be revoked sooner; renew it through the normal authenticated login flow and update the protected CI secret. A job that runs longer than one hour must repeat the exchange while its full API session is still valid. An expired operator token cannot refresh itself, and Void does not issue permanent service tokens for administrator automation.
421
-
422
- `auth login --token-stdin` performs the same elevation and saves the one-hour operator token in the system keychain for interactive use. See [operator authentication](../reference/cli.md#operator-authentication) for the full command syntax.
423
-
424
- An email zone has one connection and ingress Worker shared by its exact domain assignments. Removing one assignment preserves resources used by the others. The Email administration page can explicitly rotate that connection secret; ordinary synchronization does not rotate it. Setup and cleanup outcomes include operation IDs, and uncertain provider writes remain recorded until reconciled.
13
+ - [Sign-in and Access](/guide/platform/administration/access)
14
+ - [Users and Projects](/guide/platform/administration/projects)
15
+ - [Email](/guide/platform/administration/email)
16
+ - [Operations](/guide/platform/administration/operations)