@xano/cli 1.2.0 → 1.3.1-beta.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.
- package/README.md +381 -4
- package/dist/base-command.d.ts +54 -36
- package/dist/base-command.js +246 -169
- package/dist/commands/auth/index.d.ts +1 -1
- package/dist/commands/auth/index.js +7 -7
- package/dist/commands/branch/create/index.d.ts +1 -1
- package/dist/commands/branch/create/index.js +1 -1
- package/dist/commands/branch/set_live/index.d.ts +22 -0
- package/dist/commands/branch/set_live/index.js +60 -1
- package/dist/commands/ephemeral/create/index.d.ts +18 -0
- package/dist/commands/ephemeral/create/index.js +103 -0
- package/dist/commands/ephemeral/delete/index.d.ts +18 -0
- package/dist/commands/ephemeral/delete/index.js +99 -0
- package/dist/commands/ephemeral/edit/index.d.ts +18 -0
- package/dist/commands/ephemeral/edit/index.js +109 -0
- package/dist/commands/ephemeral/get/index.d.ts +21 -0
- package/dist/commands/ephemeral/get/index.js +125 -0
- package/dist/commands/ephemeral/impersonate/index.d.ts +20 -0
- package/dist/commands/ephemeral/impersonate/index.js +120 -0
- package/dist/commands/ephemeral/list/index.d.ts +19 -0
- package/dist/commands/ephemeral/list/index.js +123 -0
- package/dist/commands/ephemeral/pull/index.d.ts +19 -0
- package/dist/commands/ephemeral/pull/index.js +163 -0
- package/dist/commands/ephemeral/push/index.d.ts +35 -0
- package/dist/commands/ephemeral/push/index.js +228 -0
- package/dist/commands/ephemeral/static_host/build/delete/index.d.ts +20 -0
- package/dist/commands/ephemeral/static_host/build/delete/index.js +121 -0
- package/dist/commands/ephemeral/static_host/build/get/index.d.ts +18 -0
- package/dist/commands/ephemeral/static_host/build/get/index.js +137 -0
- package/dist/commands/ephemeral/static_host/build/list/index.d.ts +18 -0
- package/dist/commands/ephemeral/static_host/build/list/index.js +137 -0
- package/dist/commands/ephemeral/static_host/build/pull/index.d.ts +53 -0
- package/dist/commands/ephemeral/static_host/build/pull/index.js +308 -0
- package/dist/commands/ephemeral/static_host/build/push/index.d.ts +24 -0
- package/dist/commands/ephemeral/static_host/build/push/index.js +250 -0
- package/dist/commands/ephemeral/static_host/create/index.d.ts +18 -0
- package/dist/commands/ephemeral/static_host/create/index.js +92 -0
- package/dist/commands/ephemeral/static_host/deploy/index.d.ts +19 -0
- package/dist/commands/ephemeral/static_host/deploy/index.js +112 -0
- package/dist/commands/ephemeral/static_host/edit/index.d.ts +24 -0
- package/dist/commands/ephemeral/static_host/edit/index.js +158 -0
- package/dist/commands/ephemeral/static_host/get/index.d.ts +19 -0
- package/dist/commands/ephemeral/static_host/get/index.js +101 -0
- package/dist/commands/ephemeral/static_host/list/index.d.ts +17 -0
- package/dist/commands/ephemeral/static_host/list/index.js +132 -0
- package/dist/commands/flatten/index.d.ts +34 -0
- package/dist/commands/flatten/index.js +140 -0
- package/dist/commands/function/create/index.d.ts +15 -0
- package/dist/commands/function/create/index.js +41 -1
- package/dist/commands/function/edit/index.d.ts +15 -0
- package/dist/commands/function/edit/index.js +66 -32
- package/dist/commands/function/get/index.js +2 -3
- package/dist/commands/function/run/index.d.ts +1 -0
- package/dist/commands/function/run/index.js +19 -6
- package/dist/commands/policy/catalogue/index.d.ts +15 -0
- package/dist/commands/policy/catalogue/index.js +29 -0
- package/dist/commands/policy/create/index.d.ts +18 -0
- package/dist/commands/policy/create/index.js +39 -0
- package/dist/commands/policy/delete/index.d.ts +19 -0
- package/dist/commands/policy/delete/index.js +61 -0
- package/dist/commands/policy/evaluate/index.d.ts +32 -0
- package/dist/commands/policy/evaluate/index.js +71 -0
- package/dist/commands/policy/list/index.d.ts +14 -0
- package/dist/commands/policy/list/index.js +21 -0
- package/dist/commands/policy/parse/index.d.ts +19 -0
- package/dist/commands/policy/parse/index.js +18 -0
- package/dist/commands/policy/publish/index.d.ts +20 -0
- package/dist/commands/policy/publish/index.js +38 -0
- package/dist/commands/policy/runs/index.d.ts +54 -0
- package/dist/commands/policy/runs/index.js +273 -0
- package/dist/commands/policy/status/index.d.ts +21 -0
- package/dist/commands/policy/status/index.js +54 -0
- package/dist/commands/profile/create/index.d.ts +1 -1
- package/dist/commands/profile/create/index.js +7 -7
- package/dist/commands/profile/me/index.js +1 -1
- package/dist/commands/profile/use/index.js +0 -4
- package/dist/commands/profile/wizard/index.d.ts +1 -1
- package/dist/commands/profile/wizard/index.js +12 -10
- package/dist/commands/profile/workspace/set/index.js +1 -1
- package/dist/commands/release/create/index.js +7 -0
- package/dist/commands/release/deploy/index.d.ts +28 -0
- package/dist/commands/release/deploy/index.js +90 -6
- package/dist/commands/release/edit/index.js +2 -2
- package/dist/commands/release/export/index.js +1 -2
- package/dist/commands/release/import/index.js +6 -2
- package/dist/commands/release/list/index.d.ts +7 -0
- package/dist/commands/release/list/index.js +54 -10
- package/dist/commands/release/pull/index.d.ts +0 -6
- package/dist/commands/release/pull/index.js +13 -99
- package/dist/commands/release/push/index.js +21 -3
- package/dist/commands/sandbox/env/get_all/index.js +1 -1
- package/dist/commands/sandbox/env/set_all/index.js +1 -1
- package/dist/commands/sandbox/get/index.js +1 -1
- package/dist/commands/sandbox/license/get/index.js +1 -1
- package/dist/commands/sandbox/license/set/index.js +1 -1
- package/dist/commands/sandbox/pull/index.d.ts +0 -1
- package/dist/commands/sandbox/pull/index.js +13 -81
- package/dist/commands/sandbox/push/index.d.ts +1 -1
- package/dist/commands/sandbox/push/index.js +11 -6
- package/dist/commands/skills/pull/index.d.ts +30 -0
- package/dist/commands/skills/pull/index.js +118 -0
- package/dist/commands/static_host/build/create/index.d.ts +1 -1
- package/dist/commands/static_host/build/create/index.js +2 -2
- package/dist/commands/static_host/build/pull/index.js +1 -1
- package/dist/commands/static_host/build/push/index.js +1 -1
- package/dist/commands/static_host/edit/index.js +1 -1
- package/dist/commands/tenant/backup/export/index.js +1 -2
- package/dist/commands/tenant/backup/import/index.js +1 -1
- package/dist/commands/tenant/cluster/create/index.js +1 -1
- package/dist/commands/tenant/cluster/license/get/index.js +1 -1
- package/dist/commands/tenant/cluster/license/set/index.js +1 -1
- package/dist/commands/tenant/create/index.d.ts +4 -1
- package/dist/commands/tenant/create/index.js +26 -5
- package/dist/commands/tenant/deploy_platform/index.js +1 -1
- package/dist/commands/tenant/deploy_release/index.d.ts +40 -0
- package/dist/commands/tenant/deploy_release/index.js +186 -4
- package/dist/commands/tenant/edit/index.d.ts +2 -0
- package/dist/commands/tenant/edit/index.js +46 -11
- package/dist/commands/tenant/env/get_all/index.js +1 -1
- package/dist/commands/tenant/env/set_all/index.js +1 -1
- package/dist/commands/tenant/impersonate/index.d.ts +1 -1
- package/dist/commands/tenant/impersonate/index.js +14 -14
- package/dist/commands/tenant/license/get/index.js +1 -1
- package/dist/commands/tenant/license/set/index.js +1 -1
- package/dist/commands/tenant/pull/index.d.ts +0 -6
- package/dist/commands/tenant/pull/index.js +14 -100
- package/dist/commands/tenant_deploy_request/bypass/index.d.ts +31 -0
- package/dist/commands/tenant_deploy_request/bypass/index.js +109 -0
- package/dist/commands/tenant_deploy_request/create/index.d.ts +21 -0
- package/dist/commands/tenant_deploy_request/create/index.js +108 -0
- package/dist/commands/tenant_deploy_request/edit/index.d.ts +22 -0
- package/dist/commands/tenant_deploy_request/edit/index.js +103 -0
- package/dist/commands/tenant_deploy_request/get/index.d.ts +25 -0
- package/dist/commands/tenant_deploy_request/get/index.js +116 -0
- package/dist/commands/tenant_deploy_request/list/index.d.ts +20 -0
- package/dist/commands/tenant_deploy_request/list/index.js +122 -0
- package/dist/commands/tenant_deploy_request/revision/index.d.ts +21 -0
- package/dist/commands/tenant_deploy_request/revision/index.js +83 -0
- package/dist/commands/tenant_deploy_request/set_status/index.d.ts +38 -0
- package/dist/commands/tenant_deploy_request/set_status/index.js +159 -0
- package/dist/commands/workspace/git/pull/index.d.ts +4 -4
- package/dist/commands/workspace/git/pull/index.js +158 -97
- package/dist/commands/workspace/pull/index.d.ts +9 -5
- package/dist/commands/workspace/pull/index.js +83 -106
- package/dist/commands/workspace/push/index.d.ts +19 -0
- package/dist/commands/workspace/push/index.js +124 -5
- package/dist/help.js +4 -2
- package/dist/policy-command.d.ts +90 -0
- package/dist/policy-command.js +94 -0
- package/dist/update-check.d.ts +1 -1
- package/dist/update-check.js +1 -1
- package/dist/utils/document-parser.d.ts +126 -0
- package/dist/utils/document-parser.js +332 -4
- package/dist/utils/flatten.d.ts +36 -0
- package/dist/utils/flatten.js +68 -0
- package/dist/utils/knowledge-sync.d.ts +1 -0
- package/dist/utils/knowledge-sync.js +11 -6
- package/dist/utils/microservice-wait.d.ts +53 -0
- package/dist/utils/microservice-wait.js +84 -0
- package/dist/utils/multidoc-push.d.ts +143 -2
- package/dist/utils/multidoc-push.js +479 -40
- package/dist/utils/paging.d.ts +2 -1
- package/dist/utils/paging.js +0 -1
- package/dist/utils/policy/catalogue.d.ts +7 -0
- package/dist/utils/policy/catalogue.js +72 -0
- package/dist/utils/policy/errors.d.ts +12 -0
- package/dist/utils/policy/errors.js +61 -0
- package/dist/utils/policy/feedback.d.ts +68 -0
- package/dist/utils/policy/feedback.js +165 -0
- package/dist/utils/policy/findings.d.ts +23 -0
- package/dist/utils/policy/findings.js +65 -0
- package/dist/utils/policy/gate.d.ts +161 -0
- package/dist/utils/policy/gate.js +201 -0
- package/dist/utils/policy/goal.d.ts +46 -0
- package/dist/utils/policy/goal.js +95 -0
- package/dist/utils/policy/permission.d.ts +23 -0
- package/dist/utils/policy/permission.js +84 -0
- package/dist/utils/policy/push-gate.d.ts +5 -0
- package/dist/utils/policy/push-gate.js +29 -0
- package/dist/utils/policy/release.d.ts +85 -0
- package/dist/utils/policy/release.js +115 -0
- package/dist/utils/policy/request.d.ts +55 -0
- package/dist/utils/policy/request.js +115 -0
- package/dist/utils/policy/runs.d.ts +30 -0
- package/dist/utils/policy/runs.js +101 -0
- package/dist/utils/policy/status.d.ts +47 -0
- package/dist/utils/policy/status.js +117 -0
- package/dist/utils/policy/types.d.ts +185 -0
- package/dist/utils/policy/types.js +1 -0
- package/dist/utils/reference-checker.js +14 -3
- package/oclif.manifest.json +8538 -3445
- package/package.json +16 -1
package/README.md
CHANGED
|
@@ -46,16 +46,16 @@ The Metadata API pages unevenly, so `list` commands differ in what they expose.
|
|
|
46
46
|
| Commands | Flags | Footer |
|
|
47
47
|
|---|---|---|
|
|
48
48
|
| `function list`, `unit_test list`, `workflow_test list` (plus `sandbox` / `tenant` variants) | `--page`, `--per_page` | `Page 2 · 50 shown · next: --page 3` |
|
|
49
|
-
| `static_host list`, `static_host build list` | `--page` only | `Page 2 · 100 shown · 340 total` |
|
|
49
|
+
| `static_host list`, `static_host build list` (plus `ephemeral` variants) | `--page` only | `Page 2 · 100 shown · 340 total` |
|
|
50
50
|
| `branch list`, `workspace list`, `tenant snapshot list`, `sandbox env list`, `tenant env list` | none | `12 branches` |
|
|
51
|
-
| `tenant list`, `release list`, `platform list`, `tenant cluster list` | none | none |
|
|
51
|
+
| `tenant list`, `release list`, `platform list`, `tenant cluster list`, `ephemeral list` | none | none |
|
|
52
52
|
| `tenant backup list` | `--page` only (pre-existing) | none |
|
|
53
53
|
|
|
54
54
|
Notes:
|
|
55
55
|
|
|
56
56
|
- **`--per_page` is only offered where the endpoint accepts it.** Static-host endpoints hardcode 100 items per page server-side, so those commands take `--page` alone. `xano static_host list --per_page 10` previously parsed but did nothing; it is now rejected rather than silently ignored.
|
|
57
57
|
- **All paged commands default `--per_page` to 50.** The test-list commands previously requested 10000 internally so nothing was ever cut off; now that the footer and the JSON envelope both report position, a page that stops at 50 is visible rather than silent. Raise it (up to 10000) when you want everything in one call.
|
|
58
|
-
- **The last group has no CLI paging.** Those endpoints page server-side but return a plain array with no page or total metadata, so the CLI cannot tell you where you are. Rather than show a page number with no context — or infer "more available" from a full page, which is wrong exactly when the result count is a multiple of the page size — these commands are left as-is. **They return at most 25–50 items** (50 for tenants, 25 for releases, platforms, and tenant backups). If you have more than that, query the Metadata API directly until those endpoints return paging metadata.
|
|
58
|
+
- **The last group has no CLI paging.** Those endpoints page server-side but return a plain array with no page or total metadata, so the CLI cannot tell you where you are. Rather than show a page number with no context — or infer "more available" from a full page, which is wrong exactly when the result count is a multiple of the page size — these commands are left as-is. **They return at most 25–50 items** (50 for tenants and ephemerals, 25 for releases, platforms, and tenant backups). If you have more than that, query the Metadata API directly until those endpoints return paging metadata.
|
|
59
59
|
- **`--output json` returns an envelope, not a bare array.** Every list command emits `{items, ...}` using the Metadata API's own field names — `curPage`, `nextPage`, `prevPage`, `itemsTotal` — each included only when the endpoint actually reports it. `perPage` is the one field the CLI adds, since the API never echoes it back and it is otherwise invisible at its default. This is a **breaking change** for scripts that parsed the previous bare array — read `.items` instead.
|
|
60
60
|
|
|
61
61
|
```jsonc
|
|
@@ -170,6 +170,104 @@ xano profile delete myprofile
|
|
|
170
170
|
xano profile delete myprofile --force
|
|
171
171
|
```
|
|
172
172
|
|
|
173
|
+
### Policies
|
|
174
|
+
|
|
175
|
+
Policies combine a description with deterministic check rules; the platform parses, validates and evaluates
|
|
176
|
+
them. `xano policy <command> --help` gives each command's flags and output, and the Xano developer MCP documents
|
|
177
|
+
the rest: the `policies` topic of `xano_xanoscript_docs` (the language) and the `policy` topic of `xano_cli_docs`.
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
xano policy catalogue --check object.auth_required # The checks a rule can use (all of them without --check)
|
|
181
|
+
xano policy create --goal endpoints_need_login -b dev # Create an independent policy from a platform goal
|
|
182
|
+
xano policy create --goal no_pii_in_responses --key DATA-020 --param 'fields=["email","ssn"]'
|
|
183
|
+
xano policy list # Policies on the branch
|
|
184
|
+
xano policy parse policies/AUTH-001.xs # Validate and print canonical XanoScript (or --file, --stdin)
|
|
185
|
+
xano policy publish policies/AUTH-001.xs -m "Why" # Create or update by key; -m labels the Version History entry
|
|
186
|
+
xano policy evaluate # Evaluate the branch now
|
|
187
|
+
xano policy evaluate --summary # The same, answering the run summary and its first 50 findings
|
|
188
|
+
xano policy status --fail-on-findings # The latest run, without evaluating (CI)
|
|
189
|
+
xano policy runs 1674 --run-detail # One run and its first 100 findings; without an id, the retained runs
|
|
190
|
+
xano policy runs 1674 --offset 100 --limit 100 # The next page of that run's findings (at most 500 a page)
|
|
191
|
+
xano policy runs 1674 --all -o json # Every finding, read page by page
|
|
192
|
+
xano policy runs 1674 --blocking --policy AUTH-001 # Only some findings: --blocking/--advisory, --policy, --rule,
|
|
193
|
+
# --severity, --kind, --object type:id, --tag (repeatable), --search
|
|
194
|
+
xano policy runs --release v1.2 # A release's check (stored when it was cut), paged and filtered the same way
|
|
195
|
+
xano policy runs --release v1.2 --recheck # Check the release again from its archive, store the run, then read it
|
|
196
|
+
xano policy runs --release-id 12 # Read an imported release by ID without a name lookup
|
|
197
|
+
xano policy delete TMP-001 # Remove a policy; its Version History is kept
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
`policy create --goal <id>` reads the instance's goals from `policy catalogue -o json`, copies a goal's
|
|
201
|
+
sparse settings, validates them natively and creates an Active, Advisory policy. Required goal settings must
|
|
202
|
+
be filled before it saves. Repeat `--param 'N.path=JSON'` for overrides: rule numbers start at 1; the `N.`
|
|
203
|
+
prefix is optional for a single-rule goal. Nested paths work, for example `--param '1.when.statement="db.edit"'`.
|
|
204
|
+
Values are JSON, including quoted strings, arrays, booleans and numbers. The goal key gets a free numeric
|
|
205
|
+
suffix if already taken (case-insensitive); an explicitly taken `--key` is refused. It never updates an
|
|
206
|
+
existing policy. `-m/--message` labels its Version History entry; `-o json` returns the saved policy and
|
|
207
|
+
native rule warnings go to stderr. No continuing link to the goal is stored.
|
|
208
|
+
|
|
209
|
+
A push to the live branch is refused before commit when mandatory policies block it. The gate judges the branch by the policies it will have after the push, so the pushed policy files count, and a push that weakens a mandatory policy of the live branch (demotes, deactivates or deletes it, or loosens one of its rules) needs `workspace:policy` update and is otherwise refused before anything is imported. A 403 `policy_gate` exits **2**, says nothing was imported, and lists the blocking findings and introduced/changed counts. With `-o json` it prints `{imported: false, refused: <payload>}`. `--policy-override "reason"` sends an audited override, requiring `workspace:policy` update permission. This gate requires transactions: remove `--no-transaction` if the server refuses it (exit 1).
|
|
210
|
+
|
|
211
|
+
Every policy command takes `-w/--workspace`, `-b/--branch` (the profile's branch by default; `-b ''` is live)
|
|
212
|
+
and `-o/--output summary|json`. `workspace pull` and `workspace push` carry policies as `policies/<KEY>.xs`.
|
|
213
|
+
Policies use `active = true|false` before `enforcement`; authored `lifecycle` is refused. The list shows
|
|
214
|
+
`Active, Mandatory`, `Active, Advisory` or `Inactive`. Inactive policies are saved directly and skipped by
|
|
215
|
+
branch checks; `policy status` reports `inactive`. An inactive policy may have no rules.
|
|
216
|
+
`release push` carries them too, for a credential holding `workspace:policy` create and update: a release ships its
|
|
217
|
+
policies like its code, and a tenant deploy lands them (see Releases). Tier1 tenant, sandbox and ephemeral pushes
|
|
218
|
+
carry them as well; a remote tenant push, or a tenant created before policies, leaves them out and prints the
|
|
219
|
+
platform's notice.
|
|
220
|
+
While the instance's Policies feature is off, `workspace pull` exports no policy (and keeps local policy files)
|
|
221
|
+
and `workspace push` leaves its policy files out, printing the platform's notice instead of a policy count.
|
|
222
|
+
|
|
223
|
+
A run can hold tens of thousands of findings, so the CLI reads them a page at a time. `policy runs <id>` reads
|
|
224
|
+
the run's summary and one page of its findings; a page that is not every finding says `(one page)` and how to read
|
|
225
|
+
the next. `-o json` is the summary with `findings`, the page's findings as an array, and
|
|
226
|
+
`findings_page: {total, offset, limit, next_offset}`. `--all` reads every page (500 a request, saying so on stderr
|
|
227
|
+
when there are more) and returns every matching finding in `findings`. `policy status` reads the latest run's
|
|
228
|
+
summary, so its `-o json` `run` carries each policy's finding count rather than the findings. The `policy_check` a
|
|
229
|
+
`workspace push` prints lists the first 100 findings; when there are more it prints their counts and
|
|
230
|
+
`Listed: the first 100 of N; \`xano policy runs <run_id>\` has them all.` `policy evaluate --summary` does the same
|
|
231
|
+
with the first 50, and `policy evaluate` without it still answers the whole run.
|
|
232
|
+
|
|
233
|
+
`policy evaluate --policy AUTH-001` tries that one policy alone, even if inactive. It never stores or audits
|
|
234
|
+
the trial, replaces the latest run or gates anything. The output names each rule's clear objects (up to five
|
|
235
|
+
names, with the rest counted). Combine it with `--summary`, `--run-detail` or `-o json`; an inactive trial
|
|
236
|
+
does not exit 2. A blank key is refused before any request, and an unknown key gets the platform's 404.
|
|
237
|
+
|
|
238
|
+
`policy runs --release <name>` reads a release's check: the run stored when the release was cut, evaluated on what
|
|
239
|
+
the release ships against the policies it ships. It takes every finding flag a run read takes, `-o json` has the same
|
|
240
|
+
shape (plus the release's `shipped` policies), and a release with no check says so (`{"run": null}` under `-o json`).
|
|
241
|
+
`--recheck` checks the release again from its archive and stores the new run, so a read-only credential is refused.
|
|
242
|
+
`--release-id <id>` reads the same report directly by ID and also supports `--recheck`; it is exclusive with
|
|
243
|
+
`--release` and `--branch`.
|
|
244
|
+
|
|
245
|
+
**Exit codes** of `policy evaluate`, `workspace push` and `policy status --fail-on-findings`: `2` when a finding
|
|
246
|
+
blocks (an active, mandatory policy failed), whatever else happened; `1` when a request or the import failed, or
|
|
247
|
+
when `status --fail-on-findings` finds stale, missing or errored evidence; otherwise `0`. `tenant deploy_release`,
|
|
248
|
+
`tenant_deploy_request set_status` and `tenant_deploy_request bypass` exit `2` when the tenant deploy policy gate
|
|
249
|
+
refuses the deploy (and `tenant deploy_release --check` when it would), `1` for any other failure, otherwise `0`.
|
|
250
|
+
`release deploy --set_live` and `branch set_live` exit `2` when the set-live policy gate refuses to set the branch live, and `1` for any other failure; `branch set_live --policy-override "<reason>"` sets it live past the gate with an audited reason, as `release deploy` does. `function create` and `function edit` exit `2` when the live-branch publish gate refuses the save (see Functions), and `1` for any other failure. A blank `--policy-override` is refused before any request. A `workspace push`, `branch set_live`, `release deploy --set_live` or `policy delete` refused with `policy_weakening_permission_required` exits `1`, like the other permission refusals: it is a missing permission, not a blocking finding.
|
|
251
|
+
|
|
252
|
+
Each route needs the `workspace:policy` permission at the request's level. A refusal's `payload.code` names the
|
|
253
|
+
gate and the CLI prints its remedy: `policy_feature_disabled` (Policies are off on the instance),
|
|
254
|
+
`policy_permission_required` (an instance admin grants your role the level) or `policy_scope_required` (create a
|
|
255
|
+
Metadata API token that has the scope). A push to the live branch, a set live or a merge is judged by the policies it
|
|
256
|
+
leaves, so one that weakens a policy active and mandatory on the branch (demotes, deactivates or deletes it, or
|
|
257
|
+
loosens one of its rules; for a set live, a live mandatory policy the branch lacks counts as deleted) needs
|
|
258
|
+
`workspace:policy` update, and without it is refused before anything is written with
|
|
259
|
+
`policy_weakening_permission_required`, naming the policies. `--policy-override` does not lift it: the CLI prints the
|
|
260
|
+
platform's sentence and how to go on (a push can leave the policy files out with `-e "policies/*"`), and a push's
|
|
261
|
+
`--dry-run` is refused the same way. `policy delete` of an active, mandatory policy needs update too, not only delete,
|
|
262
|
+
and is refused with the same code otherwise. A set live whose check could not read the policies fails closed: only
|
|
263
|
+
update proceeds, and the refusal says so (`unavailable`). A rule naming a check the instance does not have (`policy_unknown_check`)
|
|
264
|
+
points at `xano policy catalogue`. `policy delete` sends the `updated_at` it listed, so a policy changed since is
|
|
265
|
+
refused (`policy_stale`) rather than deleted; it asks first, and without `--force` in a non-interactive shell it
|
|
266
|
+
exits 1. A create past the plan's per-branch policy cap (lower plans cap the policies on each branch; Pro and above are unlimited) is refused with
|
|
267
|
+
`policy_plan_limit`, naming the plan, and a `workspace push` whose new policies would not fit imports nothing.
|
|
268
|
+
`policy parse` and `policy publish` print rule warnings (a part of a rule that would do nothing or allow too much on
|
|
269
|
+
that branch) on stderr; `-o json` keeps stdout the JSON.
|
|
270
|
+
|
|
173
271
|
### Workspaces
|
|
174
272
|
|
|
175
273
|
```bash
|
|
@@ -197,6 +295,7 @@ xano workspace delete -w <workspace_id> --force
|
|
|
197
295
|
xano workspace pull
|
|
198
296
|
xano workspace pull -d ./my-workspace # Specify output directory
|
|
199
297
|
xano workspace pull -b dev # Specific branch
|
|
298
|
+
xano workspace pull -b '' # The live branch, whatever the profile's branch
|
|
200
299
|
xano workspace pull --env --records # Include env vars and table records
|
|
201
300
|
xano workspace pull --draft # Include draft changes
|
|
202
301
|
|
|
@@ -204,6 +303,7 @@ xano workspace pull --draft # Include draft changes
|
|
|
204
303
|
xano workspace push
|
|
205
304
|
xano workspace push -d ./my-workspace # Push from a specific directory
|
|
206
305
|
xano workspace push -b dev
|
|
306
|
+
xano workspace push -b '' # The live branch, whatever the profile's branch
|
|
207
307
|
xano workspace push --sync # Full push — send all files, not just changed ones
|
|
208
308
|
xano workspace push --sync --delete # Full push + delete remote objects not included
|
|
209
309
|
xano workspace push --dry-run # Preview changes without pushing
|
|
@@ -216,6 +316,9 @@ xano workspace push --force # Skip preview and conf
|
|
|
216
316
|
xano workspace push -i "function/*" # Push only matching files
|
|
217
317
|
xano workspace push -e "table/*" # Push all files except tables
|
|
218
318
|
xano workspace push -i "function/*" -e "**/test*" # Include functions, exclude tests
|
|
319
|
+
xano workspace push -o json # One JSON document: the preview (with --dry-run) or the import result with policy_check
|
|
320
|
+
xano workspace push -m "Tightened the auth policies" # Label the Version History entry of each policy this push changes; other objects get no message
|
|
321
|
+
xano workspace push --policy-override "Approved exception" # Proceed past a blocking live-branch gate with an audited reason
|
|
219
322
|
|
|
220
323
|
# Pull from a git repository to local files (defaults to current directory)
|
|
221
324
|
xano workspace git pull -r https://github.com/owner/repo
|
|
@@ -229,6 +332,51 @@ xano workspace git pull -r https://github.com/owner/private-repo -t ghp_xxx
|
|
|
229
332
|
xano workspace git pull -r https://github.com/owner/repo --path subdir
|
|
230
333
|
```
|
|
231
334
|
|
|
335
|
+
**One workspace document per tree.** A push directory must contain at most one
|
|
336
|
+
`workspace/*.xs` document. The server applies the first workspace document it
|
|
337
|
+
receives to the workspace being pushed into and silently discards the rest,
|
|
338
|
+
without checking that it describes that workspace — so a second one renames the
|
|
339
|
+
destination to a foreign name while leaving its content untouched. `workspace push`
|
|
340
|
+
and `sandbox push` refuse a tree carrying more than one, naming the offending
|
|
341
|
+
files; there is no `--force` override, because only you know which workspace the
|
|
342
|
+
tree is meant to be.
|
|
343
|
+
|
|
344
|
+
Trees pick up a second one easily: `pull` names the file after the workspace
|
|
345
|
+
itself (`workspace/{name}.xs`), so pulling a different workspace into the same
|
|
346
|
+
directory *adds* a file rather than overwriting, and renaming a workspace leaves
|
|
347
|
+
the old-name file behind. Delete the stale ones, keeping the single document that
|
|
348
|
+
matches your target workspace.
|
|
349
|
+
|
|
350
|
+
### Flatten
|
|
351
|
+
|
|
352
|
+
A hand-authored `.xs` file can hold several documents joined by `---`. That is
|
|
353
|
+
convenient to edit but unsupported by `push`: the partial-diff filter and GUID
|
|
354
|
+
writeback both parse only the first document in a file, so such a bundle
|
|
355
|
+
silently pushes nothing (partial mode) or corrupts GUIDs (full mode). `push`
|
|
356
|
+
refuses these files and offers to flatten them.
|
|
357
|
+
|
|
358
|
+
`xano flatten` performs that split on demand, producing the same
|
|
359
|
+
one-document-per-file tree `pull` would have written. It is purely local — no
|
|
360
|
+
profile, token, or network — and deletes the original bundle once the split
|
|
361
|
+
succeeds, unless you pass `--keep-source`.
|
|
362
|
+
|
|
363
|
+
```bash
|
|
364
|
+
# Split a bundle in place into per-document files (removes the original)
|
|
365
|
+
xano flatten secret/pdf-micro/multidoc.xs
|
|
366
|
+
|
|
367
|
+
# Write the split files somewhere else instead of alongside the bundle
|
|
368
|
+
xano flatten ./bundle.xs -o ./workspace
|
|
369
|
+
|
|
370
|
+
# Preview the resulting layout without writing anything
|
|
371
|
+
xano flatten secret/pdf-micro/multidoc.xs --dry-run
|
|
372
|
+
|
|
373
|
+
# Flatten every multi-doc .xs under a directory, keeping the originals
|
|
374
|
+
xano flatten ./dir-of-bundles --keep-source
|
|
375
|
+
|
|
376
|
+
# Overwrite existing destination files instead of erroring
|
|
377
|
+
xano flatten ./bundle.xs --force
|
|
378
|
+
```
|
|
379
|
+
|
|
232
380
|
### Knowledge
|
|
233
381
|
|
|
234
382
|
Knowledge items are user-authored docs and skills (e.g. `CLAUDE.md`, `AGENTS.md`, runbooks)
|
|
@@ -285,6 +433,7 @@ xano branch edit <branch_label> --color "#ff0000"
|
|
|
285
433
|
# Set live branch
|
|
286
434
|
xano branch set_live <branch_label>
|
|
287
435
|
xano branch set_live <branch_label> --force
|
|
436
|
+
xano branch set_live <branch_label> --policy-override "Rollback approved" # Past a blocking set-live policy gate (audited)
|
|
288
437
|
|
|
289
438
|
# Delete a branch
|
|
290
439
|
xano branch delete <branch_label>
|
|
@@ -309,6 +458,7 @@ xano function get <function_id> --include_draft # Include draft version
|
|
|
309
458
|
xano function create -f function.xs
|
|
310
459
|
xano function create -f function.xs --edit # Open in $EDITOR before creating
|
|
311
460
|
cat function.xs | xano function create --stdin
|
|
461
|
+
xano function create -f function.xs --policy-override "Exception approved" # Past a blocking publish policy gate (audited)
|
|
312
462
|
|
|
313
463
|
# Edit a function
|
|
314
464
|
xano function edit <function_id> # Opens in $EDITOR
|
|
@@ -316,6 +466,7 @@ xano function edit <function_id> -f new.xs # Update from file
|
|
|
316
466
|
xano function edit <function_id> -f new.xs --edit # Open in $EDITOR before updating
|
|
317
467
|
cat function.xs | xano function edit <function_id> --stdin # Update from stdin
|
|
318
468
|
xano function edit <function_id> --no-publish # Edit without publishing
|
|
469
|
+
xano function edit <function_id> -f new.xs --policy-override "Exception approved" # Past a blocking publish policy gate (audited)
|
|
319
470
|
|
|
320
471
|
# Run (execute) a function by name
|
|
321
472
|
xano function run <name> # Prompts for declared inputs (on a TTY)
|
|
@@ -323,8 +474,14 @@ xano function run <name> --data email=jo@x.com --data age:=30 --data active:=tru
|
|
|
323
474
|
xano function run <name> --json @payload.json --data env=staging # base payload + override
|
|
324
475
|
echo '{"email":"jo@x.com"}' | xano function run <name> --stdin -o json | jq .result
|
|
325
476
|
xano function run <name> --branch dev --logs # run on a branch, show execution logs
|
|
477
|
+
xano function run <name> --datasource test # run against the 'test' data source
|
|
326
478
|
```
|
|
327
479
|
|
|
480
|
+
`function create` and `function edit` save a function on the live branch through the publish policy gate. When
|
|
481
|
+
blocking findings refuse the save, nothing is saved: the command prints the verdict and the platform's message and
|
|
482
|
+
exits `2` (any other failure exits `1`), and `-o json` prints `{created|updated: false, message, policy_gate}`.
|
|
483
|
+
`--policy-override "<reason>"` saves past the gate with an audited reason (requires `workspace:policy` update).
|
|
484
|
+
|
|
328
485
|
Input flexibility for `function run` (assembled into one JSON `input` object):
|
|
329
486
|
|
|
330
487
|
| Form | Meaning |
|
|
@@ -335,6 +492,11 @@ Input flexibility for `function run` (assembled into one JSON `input` object):
|
|
|
335
492
|
| `--json '<inline>'` / `--json @file.json` / `--json -` | a base JSON object (stdin with `-`) |
|
|
336
493
|
| `--stdin` | read the JSON object from stdin (same as `--json -`) |
|
|
337
494
|
|
|
495
|
+
`--datasource <label>` runs the function against a non-live data source by sending the
|
|
496
|
+
`X-Data-Source` header, so table reads and writes hit that data source's tables. Omit it
|
|
497
|
+
to run against `live`; an unknown label is rejected by the server with
|
|
498
|
+
`Invalid data source.`
|
|
499
|
+
|
|
338
500
|
Merge order is JSON base first, then `--data` overrides. Missing required inputs are
|
|
339
501
|
prompted for on an interactive terminal; in a non-TTY (CI) context the command fails
|
|
340
502
|
listing them. Output defaults to the raw `result` (`-o json`); the exit code is non-zero
|
|
@@ -370,12 +532,27 @@ xano knowledge get "deploy-runbook" -w 40 --output json
|
|
|
370
532
|
xano knowledge get "deploy-runbook" -w 40 --file checklist.md
|
|
371
533
|
```
|
|
372
534
|
|
|
535
|
+
### Agent skills
|
|
536
|
+
|
|
537
|
+
```bash
|
|
538
|
+
xano skills pull # Writes ./.claude/skills/xano-policies/SKILL.md
|
|
539
|
+
xano skills pull -d ./my-project # Install into another project directory
|
|
540
|
+
xano skills pull -b dev -o json # Another branch; print the result as JSON
|
|
541
|
+
```
|
|
542
|
+
|
|
543
|
+
`xano skills pull` writes the `xano-policies` skill the instance generates from its check catalogue to
|
|
544
|
+
`<directory>/.claude/skills/xano-policies/SKILL.md`, replacing that file without a backup; pull it again after an
|
|
545
|
+
instance upgrade. A copy installed anywhere else is not touched, so remove it. The route needs the
|
|
546
|
+
`workspace:policy` read permission. The CLI writes the file's frontmatter (`name` and `description`) itself and drops
|
|
547
|
+
any frontmatter the served content opens with, so a workspace knowledge record that replaces the platform skill cannot
|
|
548
|
+
set agent settings such as `allowed-tools` or `hooks`. It refuses to write through a symbolic link at that path.
|
|
549
|
+
|
|
373
550
|
### Releases
|
|
374
551
|
|
|
375
552
|
All release commands use **release names** (e.g., `v1.0`), not IDs.
|
|
376
553
|
|
|
377
554
|
```bash
|
|
378
|
-
# List releases
|
|
555
|
+
# List releases, each tagged with its stored policy check when Policies is enabled and readable (see Policies)
|
|
379
556
|
xano release list
|
|
380
557
|
|
|
381
558
|
# Get release details
|
|
@@ -416,8 +593,54 @@ xano release deploy "v1.0"
|
|
|
416
593
|
xano release deploy "v1.0" --force
|
|
417
594
|
xano release deploy "v1.0" --branch "restore-v1" --no-set_live
|
|
418
595
|
xano release deploy "v1.0" -w 40 -o json --force
|
|
596
|
+
|
|
597
|
+
# Set it live past a blocking set-live policy gate with an audited reason (needs workspace:policy update)
|
|
598
|
+
xano release deploy "v1.0" --branch "rollback-v1" --set_live --policy-override "Rollback approved; tracked in JIRA-12"
|
|
599
|
+
|
|
600
|
+
# Read a release's policy check, or check it again (see Policies)
|
|
601
|
+
xano policy runs --release v1.0
|
|
602
|
+
xano policy runs --release v1.0 --recheck
|
|
419
603
|
```
|
|
420
604
|
|
|
605
|
+
A release carries its branch's policies like its code (`release push` sends `policies/*.xs` with the rest), and a
|
|
606
|
+
tenant deploy lands them on the tenant. A release built by `release push` carries those files only for a credential
|
|
607
|
+
holding `workspace:policy` create and update; for anyone else it carries the workspace's live-branch policies instead,
|
|
608
|
+
and when the files differ from them the push prints the platform's notice naming them (exit `0`). `release import` of
|
|
609
|
+
an archive that carries policies needs the same levels: without them nothing is stored, and the command fails with
|
|
610
|
+
the platform's message and the remedy for your role or token.
|
|
611
|
+
|
|
612
|
+
Cutting a release (`release create`, `release push`, `release import`) stores its policy check, and the summary
|
|
613
|
+
prints it: `Policy check: fail (run 1712), 2 blocking, 1 advisory findings`, or
|
|
614
|
+
`Policy check disabled|skipped|error: <why>` when none was recorded. `-o json` keeps it as `policy_run`
|
|
615
|
+
(`{status, run_id, run_status, blocking, advisory, message?}`, or `null` for a credential without `workspace:policy`
|
|
616
|
+
read). A cut is never refused for its findings: its blocking findings are what gates each tenant deploy (see Tenant
|
|
617
|
+
deployments).
|
|
618
|
+
|
|
619
|
+
`release list` tags each release with its stored check, worded as Studio's Policies column: `[policies: 2 blocking,
|
|
620
|
+
1 advisory]`, `[policies: 11 advisory]`, `[policies: passed]`, `[policies: none shipped]` (the release carries no
|
|
621
|
+
policies), `[policies: could not check]` (a rule could not run) or `[policies: not checked]` (no stored check:
|
|
622
|
+
deploying the release checks it, and so does `policy runs --release <name> --recheck`), and ends with
|
|
623
|
+
`Policy check details: xano policy runs --release <name>`. The tag is the release's own check, its code against the
|
|
624
|
+
policies it ships, and it is also what the tenant deploy gate judges: a release with blocking findings is held on
|
|
625
|
+
every standard or run tenant (`tenant deploy_release --check`). The list reads `release/policy_check` once, stores nothing, and
|
|
626
|
+
prints as it did before when that read is refused (Policies off, no `workspace:policy` read) or fails. `-o json`
|
|
627
|
+
adds `policy_check` to each item (`{run_id, status, finished_at, counts {findings, blocking, advisory, errors},
|
|
628
|
+
policies}`, or `null` for a release with no stored check) and leaves it out when the checks could not be read.
|
|
629
|
+
Tier1 tenant, ephemeral and sandbox pushes carry policy files too when Policies is enabled and the tenant has
|
|
630
|
+
a policy table. Remote tenant pushes still leave them out; remote release deploys carry them.
|
|
631
|
+
|
|
632
|
+
`release deploy --set_live` lands the release as a new branch, then sets it live through the same policy gate as
|
|
633
|
+
`branch set_live`: the branch is checked against its own policies, which live will have once it is set live, and
|
|
634
|
+
blocking findings it introduces compared with the live branch, or leaves on objects it changes, refuse it. A branch
|
|
635
|
+
that weakens a mandatory policy of the live branch needs `workspace:policy` update (a release that lands no policy is
|
|
636
|
+
judged by the live branch's policies instead, and nothing is checked for weakening): without it set live is refused
|
|
637
|
+
with `policy_weakening_permission_required`, the branch stays, and the command exits `1`, naming the branch to set
|
|
638
|
+
live or delete. A gate refusal keeps the branch, prints the verdict, says `The branch was
|
|
639
|
+
created; set live was refused` and exits `2`; `-o json` prints `{"branch_created": true, "set_live": false, "branch",
|
|
640
|
+
"message", "policy_gate"}`. Set it live from Studio's Branches panel with a reason, or delete the branch and deploy
|
|
641
|
+
again with `--policy-override "<reason>"`, which sets it live past the gate and is audited. A policy of the release
|
|
642
|
+
that the new branch could not take (its key is held by another policy) is named in a warning.
|
|
643
|
+
|
|
421
644
|
### Platforms
|
|
422
645
|
|
|
423
646
|
```bash
|
|
@@ -555,9 +778,14 @@ xano tenant get <tenant_name>
|
|
|
555
778
|
xano tenant create "My Tenant"
|
|
556
779
|
xano tenant create "My Tenant" -d "Description" --type tier2 --cluster_id 1 --platform_id 5
|
|
557
780
|
xano tenant create "My Tenant" --type tier2 --cluster_id 1 --license ./license.yaml
|
|
781
|
+
xano tenant create "Production" --required_reviewers 1 --allow_deploy_bypass
|
|
782
|
+
xano tenant create "Staging" --required_reviewers 0 --allow_quick_deploy
|
|
558
783
|
|
|
559
784
|
# Edit a tenant
|
|
560
785
|
xano tenant edit <tenant_name> --display "New Name" -d "New description"
|
|
786
|
+
xano tenant edit <tenant_name> --required_reviewers 1
|
|
787
|
+
xano tenant edit <tenant_name> --required_reviewers 0
|
|
788
|
+
xano tenant edit <tenant_name> --allow_quick_deploy
|
|
561
789
|
|
|
562
790
|
# Delete a tenant (confirmation required)
|
|
563
791
|
xano tenant delete <tenant_name>
|
|
@@ -604,10 +832,101 @@ xano tenant deploy_platform <tenant_name> --platform_id 5
|
|
|
604
832
|
# Deploy a release by name
|
|
605
833
|
xano tenant deploy_release <tenant_name> --release v1.0
|
|
606
834
|
|
|
835
|
+
# Preview the release's policy gate on the tenant without deploying (exit 2 when it would refuse)
|
|
836
|
+
xano tenant deploy_release <tenant_name> --release v1.0 --check
|
|
837
|
+
xano tenant deploy_release <tenant_name> --release v1.0 --check -o json
|
|
838
|
+
|
|
839
|
+
# Deploy past a blocking policy gate with an audited reason (needs workspace:policy update)
|
|
840
|
+
xano tenant deploy_release <tenant_name> --release v1.0 --override-reason "Accepted; fix tracked in JIRA-12"
|
|
841
|
+
|
|
607
842
|
# Deploy with a license override file (deploy_platform only)
|
|
608
843
|
xano tenant deploy_platform <tenant_name> --platform_id 5 --license ./license.yaml
|
|
609
844
|
```
|
|
610
845
|
|
|
846
|
+
If a tenant has `required_reviewers` set above 0, `tenant deploy_release` fails with an
|
|
847
|
+
error naming the `tenant_deploy_request` command to run instead — see below. A tenant
|
|
848
|
+
with `allow_quick_deploy` enabled skips the gate entirely, regardless of
|
|
849
|
+
`required_reviewers`.
|
|
850
|
+
|
|
851
|
+
A release deploy is also gated on policy. The gate judges the release alone, by its own policy check (the one
|
|
852
|
+
stored when it was cut, or checked from its archive on demand): the blocking findings of its active mandatory policies
|
|
853
|
+
refuse the deploy, including findings the tenant's current release already has. It does not compare the release with
|
|
854
|
+
what the tenant runs, so the same release gets the same verdict on every tenant. Ephemeral and sandbox tenants get the
|
|
855
|
+
verdict but are never refused. A release cut before releases carried policies reads `not_carried` and is not gated.
|
|
856
|
+
`--check` prints the verdict (status, the release and its policy run, the number of blocking findings, and the first
|
|
857
|
+
of them) without deploying; `-o json` is the gate's answer as served. A refused deploy prints the same verdict and exits `2`, naming the
|
|
858
|
+
`--override-reason` rerun when your credential may override; under `-o json` it prints
|
|
859
|
+
`{"deployed": false, "message", "policy_gate"}`. `--override-reason` sends `override_policy: true` with the reason,
|
|
860
|
+
and the platform audits it. A successful deploy's summary prints the gate's status when the platform returns one,
|
|
861
|
+
and a warning names any policy of the release the tenant could not take (its key is held by another policy).
|
|
862
|
+
|
|
863
|
+
#### Tenant Deploy Requests
|
|
864
|
+
|
|
865
|
+
When a tenant has `required_reviewers` set above 0 and `allow_quick_deploy` is off (see
|
|
866
|
+
`tenant create`/`tenant edit` above), a release may only be deployed to it through an
|
|
867
|
+
**approved deploy request**, requiring that many distinct reviewer approvals. An author
|
|
868
|
+
with no deploy permission opens a request; a named reviewer who does hold deploy
|
|
869
|
+
permission on the tenant votes to approve it, and once enough reviewers have approved,
|
|
870
|
+
it deploys as part of that action. `allow_deploy_bypass` (set at `tenant create` time
|
|
871
|
+
only) additionally allows an authorized user to skip a specific request's gate via
|
|
872
|
+
`tenant_deploy_request bypass`, audited with a required reason.
|
|
873
|
+
|
|
874
|
+
```bash
|
|
875
|
+
# List deploy requests in a workspace (results show the target tenant and release)
|
|
876
|
+
xano tenant_deploy_request list
|
|
877
|
+
xano tenant_deploy_request list --tenant prod --status pending
|
|
878
|
+
xano tenant_deploy_request list --tenant prod --release v1.2
|
|
879
|
+
xano tenant_deploy_request list --to-review
|
|
880
|
+
|
|
881
|
+
# Get details of a specific deploy request, with its release's policy check on its tenant
|
|
882
|
+
xano tenant_deploy_request get <id>
|
|
883
|
+
|
|
884
|
+
# Open a deploy request (submits for review immediately unless --draft is passed)
|
|
885
|
+
xano tenant_deploy_request create "Deploy v1.2 to prod" --tenant prod --release v1.2 --reviewers 12,45
|
|
886
|
+
xano tenant_deploy_request create "Deploy v1.2 to prod" --tenant prod --release v1.2 --draft
|
|
887
|
+
|
|
888
|
+
# Edit a deploy request's title, description or reviewers
|
|
889
|
+
xano tenant_deploy_request edit <id> --title "Deploy v1.2.1 to prod"
|
|
890
|
+
xano tenant_deploy_request edit <id> --reviewers 12,45,67
|
|
891
|
+
|
|
892
|
+
# Change status: draft, submit, approve, request_changes, close, or reopen
|
|
893
|
+
# (approve records one reviewer's vote; once enough votes are in it deploys the
|
|
894
|
+
# release as part of that same call)
|
|
895
|
+
xano tenant_deploy_request set_status <id> --status submit
|
|
896
|
+
xano tenant_deploy_request set_status <id> --status approve
|
|
897
|
+
xano tenant_deploy_request set_status <id> --status approve --override-policy --reason "Accepted; fix tracked in JIRA-12"
|
|
898
|
+
xano tenant_deploy_request set_status <id> --status request_changes --reason "Needs a migration note"
|
|
899
|
+
xano tenant_deploy_request set_status <id> --status close --reason "Superseded by a newer request"
|
|
900
|
+
xano tenant_deploy_request set_status <id> --status reopen
|
|
901
|
+
|
|
902
|
+
# Link a newer release to a request after changes were requested (author only)
|
|
903
|
+
xano tenant_deploy_request revision <id> --release v1.2.1 --note "Added the missing migration"
|
|
904
|
+
|
|
905
|
+
# Deploy past the approval gate under the deploy-bypass permission (requires the
|
|
906
|
+
# tenant's allow_deploy_bypass to be enabled, and a separately-grantable RBAC
|
|
907
|
+
# permission). Every use is audited.
|
|
908
|
+
xano tenant_deploy_request bypass <id> --reason "Prod incident, reviewer unavailable"
|
|
909
|
+
xano tenant_deploy_request bypass <id> --reason "Prod incident, reviewer unavailable" --override-policy
|
|
910
|
+
```
|
|
911
|
+
|
|
912
|
+
`tenant_deploy_request get` always names the tenant and release. For requests that are neither approved nor closed,
|
|
913
|
+
it also prints what the policy gate would decide now for the request's release on its
|
|
914
|
+
tenant (under `-o json`, as `policy_gate`). It needs `workspace:policy` read; without it, or with the Policies
|
|
915
|
+
feature off, it prints `Policy checks: not available (<why>)` (`policy_gate: null` and `policy_gate_unavailable`
|
|
916
|
+
under `-o json`) and the command still succeeds. The deploy an approval triggers, and a bypass deploy, are gated like
|
|
917
|
+
`tenant deploy_release`: a refusal prints the verdict and exits `2`. An approval refused this way is still recorded
|
|
918
|
+
and the request stays approved; deploy it with `tenant deploy_release --override-reason`. `--override-policy`
|
|
919
|
+
(with `--reason` as the override reason, and the `workspace:policy` update permission) proceeds past the gate on
|
|
920
|
+
`set_status --status approve` and on `bypass`. Approval bypass and policy override are separate permissions:
|
|
921
|
+
neither implies the other.
|
|
922
|
+
|
|
923
|
+
CI example (e.g. a GitHub Action step):
|
|
924
|
+
|
|
925
|
+
```bash
|
|
926
|
+
xano tenant_deploy_request create "$PR_TITLE" --tenant prod --release v1.2 \
|
|
927
|
+
--description "$PR_BODY" --reviewers 12,45 -o json
|
|
928
|
+
```
|
|
929
|
+
|
|
611
930
|
#### Tenant License
|
|
612
931
|
|
|
613
932
|
```bash
|
|
@@ -694,6 +1013,64 @@ xano tenant cluster license set <cluster_id>
|
|
|
694
1013
|
xano tenant cluster license set <cluster_id> --file ./kubeconfig.yaml
|
|
695
1014
|
```
|
|
696
1015
|
|
|
1016
|
+
### Ephemeral Tenants
|
|
1017
|
+
|
|
1018
|
+
Manage ephemeral tenants — short-lived, auto-expiring tenants scoped to a workspace (default TTL 1h, max 24h). Unlike a sandbox, an ephemeral tenant requires a workspace.
|
|
1019
|
+
|
|
1020
|
+
```bash
|
|
1021
|
+
# List ephemeral tenants in the current workspace
|
|
1022
|
+
xano ephemeral list
|
|
1023
|
+
xano ephemeral list -w 5
|
|
1024
|
+
|
|
1025
|
+
# List ephemeral tenants across every workspace you can access
|
|
1026
|
+
xano ephemeral list --global
|
|
1027
|
+
|
|
1028
|
+
# Create an ephemeral tenant (workspace required)
|
|
1029
|
+
xano ephemeral create "PR preview"
|
|
1030
|
+
xano ephemeral create "Demo" --expires-hours 24 -w 5
|
|
1031
|
+
xano ephemeral create "Load test" -d "overnight soak" --expires-hours 24
|
|
1032
|
+
|
|
1033
|
+
# Get / edit / delete
|
|
1034
|
+
xano ephemeral get <tenant_name>
|
|
1035
|
+
xano ephemeral edit <tenant_name> --display "New Name" -d "New description"
|
|
1036
|
+
xano ephemeral delete <tenant_name> --force
|
|
1037
|
+
|
|
1038
|
+
# Pull to / push from local files (multidoc)
|
|
1039
|
+
xano ephemeral pull <tenant_name> -d ./my-ephemeral
|
|
1040
|
+
xano ephemeral push <tenant_name> -d ./my-ephemeral --dry-run # preview first
|
|
1041
|
+
xano ephemeral push <tenant_name> -d ./my-ephemeral
|
|
1042
|
+
|
|
1043
|
+
# Open in the browser (or print the URL)
|
|
1044
|
+
xano ephemeral impersonate <tenant_name>
|
|
1045
|
+
xano ephemeral impersonate <tenant_name> --url-only
|
|
1046
|
+
xano ephemeral impersonate <tenant_name> --guest # read-only session (browse only)
|
|
1047
|
+
```
|
|
1048
|
+
|
|
1049
|
+
#### Static hosting for an ephemeral tenant
|
|
1050
|
+
|
|
1051
|
+
An ephemeral tenant can host static sites, scoped to that tenant. These commands mirror
|
|
1052
|
+
`xano static_host *` but take the tenant name as the first argument (the tenant's static
|
|
1053
|
+
hosting is isolated inside the tenant's own database).
|
|
1054
|
+
|
|
1055
|
+
```bash
|
|
1056
|
+
# List / create / inspect a tenant's static hosts
|
|
1057
|
+
xano ephemeral static_host list <tenant_name>
|
|
1058
|
+
xano ephemeral static_host create <tenant_name> --name marketing --description "Marketing site"
|
|
1059
|
+
xano ephemeral static_host get <tenant_name> -H marketing
|
|
1060
|
+
xano ephemeral static_host edit <tenant_name> -H marketing --description "Updated"
|
|
1061
|
+
|
|
1062
|
+
# Builds: push a directory, list, inspect, deploy to an env, pull, delete
|
|
1063
|
+
xano ephemeral static_host build push <tenant_name> -H default -f ./site
|
|
1064
|
+
xano ephemeral static_host build list <tenant_name> -H default
|
|
1065
|
+
xano ephemeral static_host build get <tenant_name> -H default --build_id 52
|
|
1066
|
+
xano ephemeral static_host deploy <tenant_name> -H default --build_id 52 --env prod
|
|
1067
|
+
xano ephemeral static_host build pull <tenant_name> -H default --latest
|
|
1068
|
+
xano ephemeral static_host build delete <tenant_name> -H default --build_id 52
|
|
1069
|
+
```
|
|
1070
|
+
|
|
1071
|
+
> Static hosting is currently available for **local** tenants. Remote (tier2/tier3)
|
|
1072
|
+
> tenants are not yet supported and will return an error.
|
|
1073
|
+
|
|
697
1074
|
### Sandbox
|
|
698
1075
|
|
|
699
1076
|
Manage your sandbox tenant. Each user has a single sandbox tenant that is auto-provisioned on first use.
|