@vectros-ai/cli 0.19.0 → 0.20.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/AUTHORING.md +17 -6
- package/CHANGELOG.md +141 -0
- package/README.md +77 -13
- package/dist/cli.js +743 -36
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +743 -36
- package/dist/cli.mjs.map +1 -1
- package/package.json +3 -3
package/AUTHORING.md
CHANGED
|
@@ -69,6 +69,16 @@ A name must be 2–50 chars: a lowercase letter, then lowercase letters / digits
|
|
|
69
69
|
`dataScope: {}` when a shared/tenant-wide resource is what you intend
|
|
70
70
|
(warnings — they print but don't fail).
|
|
71
71
|
|
|
72
|
+
A schema may also declare `expectedScopeDims` — the ownership dimensions
|
|
73
|
+
its records are typically scoped by, e.g. `expectedScopeDims: [org,
|
|
74
|
+
client]`. Purely advisory (never sent to the platform, never runtime-
|
|
75
|
+
enforced): it lets the lint warn when a role/`accessProfile` clause grants
|
|
76
|
+
`r`/`u`/`d` on that typeName (via a type-qualified action like
|
|
77
|
+
`records:r:case`) but its `dataScope` names only SOME of the declared
|
|
78
|
+
dims — reads never require full-dimension coverage the way creates do, so
|
|
79
|
+
a clause naming one of two declared dims silently leaves the other
|
|
80
|
+
unconstrained. Omit the field entirely and this lint never fires.
|
|
81
|
+
|
|
72
82
|
`validate` accepts a file path **or** a bundled blueprint name.
|
|
73
83
|
|
|
74
84
|
### 3. `plan` — preview before you mint
|
|
@@ -196,8 +206,9 @@ accessProfile:
|
|
|
196
206
|
# capabilities: [member-lifecycle]
|
|
197
207
|
# A SEPARATE gated dimension from allowedActions — named platform effects a
|
|
198
208
|
# resource:ops verb can't express (e.g. creating/removing an identity in
|
|
199
|
-
# your tenant).
|
|
200
|
-
# is hard-rejected, same posture as the
|
|
209
|
+
# your tenant). 'member-lifecycle' and 'delegate-principal-stamp' are
|
|
210
|
+
# admitted today; every other name is hard-rejected, same posture as the
|
|
211
|
+
# scope gate. See "Capabilities" below.
|
|
201
212
|
#
|
|
202
213
|
# Instead of allowedActions (+ optional dataScope/capabilities), accessProfile
|
|
203
214
|
# may declare `roleIds: [<roleId>, ...]` — one or more roles declared below,
|
|
@@ -456,10 +467,10 @@ boundary, not the file.
|
|
|
456
467
|
An `accessProfile` or role clause may also declare `capabilities: [...]` —
|
|
457
468
|
named platform effects (like creating or removing an identity in your tenant)
|
|
458
469
|
that a `resource:ops` scope token can't express. This rides its own field,
|
|
459
|
-
separate from `allowedActions`, and has its own allowlist:
|
|
460
|
-
`
|
|
461
|
-
including ones the platform's own registry recognizes — is refused,
|
|
462
|
-
fail-closed, deliberately-narrow posture as the scope gate above. `validate`,
|
|
470
|
+
separate from `allowedActions`, and has its own allowlist: **`member-lifecycle`
|
|
471
|
+
and `delegate-principal-stamp` are admitted today.** Every other capability
|
|
472
|
+
name — including ones the platform's own registry recognizes — is refused,
|
|
473
|
+
the same fail-closed, deliberately-narrow posture as the scope gate above. `validate`,
|
|
463
474
|
`plan`, `blueprint-test` and `bootstrap` all report a rejected capability the
|
|
464
475
|
same way they report a rejected scope: nothing mints, and the CLI exits
|
|
465
476
|
non-zero.
|
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,147 @@
|
|
|
3
3
|
All notable changes to `@vectros-ai/cli` are documented here.
|
|
4
4
|
This project adheres to [Semantic Versioning](https://semver.org).
|
|
5
5
|
|
|
6
|
+
## 0.20.0 — 2026-08-27
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
|
|
10
|
+
- **The capability gate now admits `delegate-principal-stamp`**, alongside the
|
|
11
|
+
existing `member-lifecycle`. Grantable on an `accessProfile` or role clause's
|
|
12
|
+
`capabilities: [...]`, same as before — a blueprint can now let an admin
|
|
13
|
+
role create a membership-shaped record on behalf of a known third-party
|
|
14
|
+
user, once the clause authorizing the write also explicitly names `userId`
|
|
15
|
+
in its own `dataScope` (the capability itself may be granted on a
|
|
16
|
+
different clause of the same role, e.g. via a separately-composed
|
|
17
|
+
`roleIds` entry — only the write's own verb + `userId` admission must be
|
|
18
|
+
co-located). Bounded by the SAME app context and record type the clause's
|
|
19
|
+
`dataScope` already confines the write to — unlike `delegate-mint`/
|
|
20
|
+
`forensic-read`/`context-directory-read`, this is not tenant-wide, and
|
|
21
|
+
(like `member-lifecycle`) it is self-signup-eligible.
|
|
22
|
+
- **`vectros identity list-all`** — lists every user in the tenant, for the one
|
|
23
|
+
recovery case `identity list` can't reach: a user created but never granted
|
|
24
|
+
access anywhere (the gap between creating a principal and binding it to a
|
|
25
|
+
context). `identity list` is scoped to the caller's own context by design —
|
|
26
|
+
a user with no access grant at all is invisible there no matter how many
|
|
27
|
+
times a create is retried, since a retry with the same `--external-id` just
|
|
28
|
+
collides with the same invisible row. `list-all` authenticates with your own
|
|
29
|
+
login session (an account owner) instead of a context-scoped credential, so
|
|
30
|
+
it can see every user regardless of context. Supports `--external-id`,
|
|
31
|
+
`--tenant`, `--limit`, and `--json`, matching `identity list`'s conventions.
|
|
32
|
+
- **`vectros blueprint validate`/`plan`: new advisory lint —
|
|
33
|
+
`partial-datascope-dimension-coverage`** (needs `@vectros-ai/blueprints` ≥
|
|
34
|
+
0.17.0). Warns when a role/`accessProfile` clause grants `r`/`u`/`d` on a
|
|
35
|
+
typeName (e.g. `records:r:case`) whose schema declares
|
|
36
|
+
`expectedScopeDims`, but the clause's `dataScope` names only SOME of those
|
|
37
|
+
dims — the missing dimension(s) are silently unconstrained for that grant,
|
|
38
|
+
since reads (unlike creates) never require full-dimension `dataScope`
|
|
39
|
+
coverage. Opt-in: a schema with no `expectedScopeDims` declared never
|
|
40
|
+
trips it, and it never fires on an untyped (bare `records:r`) grant.
|
|
41
|
+
Never runtime-enforced — pure authoring-time visibility into a choice
|
|
42
|
+
that's easy to make by omission rather than intent.
|
|
43
|
+
- **`bootstrap`/`blueprint-test` now catch a FRESH (first-apply) seed index
|
|
44
|
+
failure, not just a re-apply's.** A seed create's response always carries
|
|
45
|
+
`PENDING_INDEX` on a first apply (indexing runs async, after the
|
|
46
|
+
response), so the existing `seedIndexFailures` summary previously only
|
|
47
|
+
ever saw a terminal `FAILED` on a later idempotent re-apply — a
|
|
48
|
+
newly-bootstrapped demo whose seeds failed to index looked silently empty
|
|
49
|
+
in search/RAG until the operator happened to re-run bootstrap. Every seed
|
|
50
|
+
still `PENDING_INDEX` after seeding is now re-checked with a bounded,
|
|
51
|
+
concurrent, best-effort poll (default: 3 attempts, 500ms apart, ≤ ~1.5s
|
|
52
|
+
added to the happy path) and folded into the same run-summary warning if
|
|
53
|
+
it settles to `FAILED` within the bound. Deliberately NOT a guarantee — a
|
|
54
|
+
seed still `PENDING_INDEX` when the bound is exhausted stays silent, so a
|
|
55
|
+
genuinely slow index (reconcile/quarantine can stall for minutes) never
|
|
56
|
+
turns a one-shot provisioning command into an unbounded wait.
|
|
57
|
+
- **`vectros issuers` gains `register`/`update`/`delete`** — previously
|
|
58
|
+
read-only (`list`/`get`). Closes the gap where adding a second IdP, or
|
|
59
|
+
editing one issuer's `selfSignupPolicies` after initial setup, required
|
|
60
|
+
hand-authoring a blueprint `issuers:` block and re-running a full apply.
|
|
61
|
+
`register` is idempotent by issuer id (a repeat returns the existing
|
|
62
|
+
registration unchanged, not an error); `update` only ever sends the safe,
|
|
63
|
+
mutable fields (`subClaim`/`emailClaim`/`userinfoUri`/`status`/
|
|
64
|
+
`selfSignupPolicies`) — trust-anchor fields stay immutable via this route,
|
|
65
|
+
matching the platform; `delete` uses the same re-type-the-id confirmation
|
|
66
|
+
as `context destroy` (`--force` for non-interactive use), and is refused
|
|
67
|
+
server-side while any user is bound through the issuer. All three accept
|
|
68
|
+
`--tenant test|live` (like their `list`/`get` siblings) so a context
|
|
69
|
+
living in the `test` tenant is reachable, not just `live`.
|
|
70
|
+
- **New `vectros namespace` command group: `register`/`list`/`get`.**
|
|
71
|
+
Registering a brand-new scope namespace (e.g. a `practice`/`team` entity
|
|
72
|
+
dimension) was blueprint-apply-only before this; there was also no way to
|
|
73
|
+
discover which namespaces already exist without already knowing their
|
|
74
|
+
names. `register --entity-backed` is what makes a namespace a real
|
|
75
|
+
identity-entity dimension that `identity create --type <name>` can create
|
|
76
|
+
entities in. No `update`/`delete` verbs — both are gated to a genuine root
|
|
77
|
+
API key on the platform side with no provisioning-capability door, so
|
|
78
|
+
neither could ever succeed for any credential the CLI holds (documented in
|
|
79
|
+
the command's own module header).
|
|
80
|
+
- **`role create` gains `--assumable <json>`** — a role-level `vectros
|
|
81
|
+
assume` entitlement grant (JSON map of `scope:<namespace>` → allowed
|
|
82
|
+
values), previously blueprint-`roleAssumable:`-only. Independent of
|
|
83
|
+
`--data-scope`: holding broad data-scope reach in a namespace does not by
|
|
84
|
+
itself grant assuming any value in it.
|
|
85
|
+
- **New `vectros assume --context <c> --scope <ns:value>...`** — re-mints
|
|
86
|
+
the caller's own verb token with one or more `identity.<namespace>` values
|
|
87
|
+
switched (`POST /v1/auth/token/assume`), for a caller whose role
|
|
88
|
+
explicitly grants assuming those values. The CLI's first standalone
|
|
89
|
+
command reaching this endpoint; entitlement is checked live against the
|
|
90
|
+
caller's current roles, never a copy frozen into a token at mint time. No
|
|
91
|
+
`--to-keyring` — the response is an ephemeral bearer token with the same
|
|
92
|
+
remaining lifetime as the verb token this command itself mints to make the
|
|
93
|
+
call, not a durable secret.
|
|
94
|
+
|
|
95
|
+
### Changed
|
|
96
|
+
|
|
97
|
+
- **`runLoader`'s `provisioned` is now REQUIRED — the self-provisioning
|
|
98
|
+
fallback is gone.** Internal hardening only, no CLI-facing behavior
|
|
99
|
+
change: every real caller (`vectros bootstrap`, `blueprint-test`) already
|
|
100
|
+
always ran `provisionContext` first and passed the result in, so the
|
|
101
|
+
fallback branch was dead in production. Removing it makes the
|
|
102
|
+
`provisionContext` → (apply-time identity resolution) → `runLoader`
|
|
103
|
+
ordering structurally required instead of convention-enforced — a future
|
|
104
|
+
caller can no longer reproduce the ordering bug the original fix
|
|
105
|
+
closed by skipping the split. `allowTenantWideNamespaces` and
|
|
106
|
+
`confirmExistingPrincipal` moved with it: both now live only on
|
|
107
|
+
`provisionContext`'s own input, where their actual checks have run since
|
|
108
|
+
that original fix — `runLoader`'s own copies of both parameters were already dead
|
|
109
|
+
plumbing before this change.
|
|
110
|
+
- **Apply-time identity resolution now REQUIRES `provisionContext`'s result.**
|
|
111
|
+
Internal hardening only, no CLI-facing behavior change. Closes the other
|
|
112
|
+
half of the ordering gap above: `runLoader` already required
|
|
113
|
+
`provisionContext`'s output, but the step between them — resolving a
|
|
114
|
+
blueprint's declared `identities:` — took a bare client with nothing tying
|
|
115
|
+
it to `provisionContext` having run first, so a caller could still
|
|
116
|
+
reproduce the original ordering bug (a non-`user` identity in a namespace
|
|
117
|
+
the same blueprint also registers racing that registration) with no
|
|
118
|
+
compiler signal. It now derives which client to use internally instead of
|
|
119
|
+
each caller doing so independently.
|
|
120
|
+
|
|
121
|
+
### Fixed
|
|
122
|
+
|
|
123
|
+
- **`bootstrap`'s post-merge hint is now blueprint-specific, and `--client
|
|
124
|
+
code` always shows the `claude mcp add` command.** The restart hint used to
|
|
125
|
+
read "list my tasks" / "add a task to …" for EVERY blueprint (a leftover
|
|
126
|
+
from when only `task-management` existed) — it now names the actual
|
|
127
|
+
blueprint applied. The `claude mcp add` line (the idiomatic Claude Code
|
|
128
|
+
install path) used to print only on `--no-merge` / a declined / a failed
|
|
129
|
+
merge — a successful auto-merge silently hid it; it's now shown there too.
|
|
130
|
+
- Scrubbed internal issue/MR references, review-process citations, and
|
|
131
|
+
backend class names out of `packages/cli`'s comments — visible in the
|
|
132
|
+
published npm package's sourcemaps to anyone who reads mapped source.
|
|
133
|
+
Comment-only; no behavior change.
|
|
134
|
+
- **Keyring secret-store hardening.** A 0-byte salt file removed by
|
|
135
|
+
something else mid-poll (a concurrent cleanup, a manual delete of the
|
|
136
|
+
crash remnant) used to throw a raw `ENOENT` out of `setSecret`; it now
|
|
137
|
+
restarts salt creation instead, since nothing was ever encrypted under an
|
|
138
|
+
empty salt in the first place. Also fixed an order-dependent assumption
|
|
139
|
+
in two `keyring prune` tests (they now pin the processing order they
|
|
140
|
+
depend on, so a future ordering change fails with a diagnosable message
|
|
141
|
+
instead of a confusing downstream one).
|
|
142
|
+
|
|
143
|
+
### Changed
|
|
144
|
+
|
|
145
|
+
- Bundled `@vectros-ai/sdk` refreshed to the current release's staging build.
|
|
146
|
+
|
|
6
147
|
## 0.19.0 — 2026-08-27
|
|
7
148
|
|
|
8
149
|
### Added
|
package/README.md
CHANGED
|
@@ -9,9 +9,11 @@ The Vectros provisioning CLI — the `vectros` binary:
|
|
|
9
9
|
- **`vectros blueprint`** — author + inspect blueprints (`init` / `validate` / `plan` / `list`), creds-free.
|
|
10
10
|
- **`vectros blueprint-test`** — apply a blueprint to a live env, assert it provisioned a working credential, then tear it down.
|
|
11
11
|
- **`vectros context`** — create, list, and destroy app contexts.
|
|
12
|
-
- **`vectros issuers`** — inspect
|
|
12
|
+
- **`vectros issuers`** — register, update, delete, and inspect third-party IdP issuers (token-exchange trust anchors) for a context.
|
|
13
|
+
- **`vectros namespace`** — register a new scope namespace, and list/get existing ones.
|
|
13
14
|
- **`vectros identity`** — manage tenant-wide principals (users, orgs, clients, and namespaces you register).
|
|
14
15
|
- **`vectros role`** — define reusable, context-scoped access rules.
|
|
16
|
+
- **`vectros assume`** — switch identity namespace values on your own token, per a role's `assumable` grant.
|
|
15
17
|
- **`vectros access`** — bind principals to contexts, and inspect what a binding grants.
|
|
16
18
|
- **`vectros key`** — issue, list, revoke, and rotate scoped API keys (`ssk_*`).
|
|
17
19
|
- **`vectros keyring`** — hold several identities on one machine, pick which is active, and let other tools resolve keys from one place.
|
|
@@ -148,23 +150,60 @@ flags (`--base-url`, `--token`).
|
|
|
148
150
|
|
|
149
151
|
## `vectros issuers` — registered third-party IdP issuers
|
|
150
152
|
|
|
151
|
-
|
|
153
|
+
Manage the third-party identity-provider registrations a context trusts for
|
|
152
154
|
[RFC 8693 token exchange](https://www.rfc-editor.org/rfc/rfc8693) — the
|
|
153
155
|
`issuer`/`jwksUri`/`audience` a blueprint's `issuers[]` entries register, plus
|
|
154
|
-
any self-signup policy attached to one.
|
|
155
|
-
|
|
156
|
+
any self-signup policy attached to one. Everything a blueprint's `issuers:`
|
|
157
|
+
block can do is available standalone here too — adding a second IdP, or
|
|
158
|
+
editing one issuer's `selfSignupPolicies` after initial setup, no longer
|
|
159
|
+
requires hand-authoring a blueprint and re-running a full apply.
|
|
156
160
|
|
|
157
161
|
```bash
|
|
162
|
+
vectros issuers register --context my-app --issuer-id auth0-prod \
|
|
163
|
+
--issuer https://your-tenant.us.auth0.com/ \
|
|
164
|
+
--jwks-uri https://your-tenant.us.auth0.com/.well-known/jwks.json \
|
|
165
|
+
--audience https://api.your-app.example.com
|
|
158
166
|
vectros issuers list --context my-app
|
|
159
167
|
vectros issuers get primary --context my-app
|
|
168
|
+
vectros issuers update primary --context my-app --status suspended
|
|
169
|
+
vectros issuers delete primary --context my-app # re-types the id to confirm
|
|
160
170
|
```
|
|
161
171
|
|
|
162
172
|
| Subcommand | Flags | Notes |
|
|
163
173
|
|---|---|---|
|
|
174
|
+
| `register` | `--context`, `--issuer-id`, `--issuer`, `--jwks-uri`, `--audience` (all required); `--sub-claim`, `--email-claim`, `--userinfo-uri`, `--self-signup-policy <type:roleId>` (repeatable), `--tenant test\|live` | Idempotent by `--issuer-id` within the tenant — a repeat returns the existing registration unchanged, not an error. |
|
|
175
|
+
| `update <issuerId>` | `--context <contextId>` (required); `--sub-claim`, `--email-claim`, `--userinfo-uri`, `--status active\|suspended`, `--self-signup-policy <type:roleId>` (repeatable), `--clear-self-signup-policies`, `--tenant test\|live` | Only ever sends the SAFE, mutable fields — `issuer`/`jwks-uri`/`audience`/`contextId` are trust-anchor fields, immutable via this route on the platform side; rotating one is `delete` + `register`. |
|
|
176
|
+
| `delete <issuerId>` | `--context <contextId>` (required), `--force`, `--tenant test\|live` | Re-types the issuer id to confirm (mirrors `context destroy`); `--force` skips the prompt and is required when stdin isn't a TTY. Refused server-side while any user was ever created or matched through this issuer. |
|
|
164
177
|
| `list` | `--context <contextId>` (required), `--tenant test\|live` | Every issuer registered in that context. `--context` has no default — an issuer read is confined to the context you name; there's no tenant-wide "every issuer in every context" view. |
|
|
165
178
|
| `get <issuerId>` | `--context <contextId>` (required), `--tenant test\|live` | One issuer's full registration, including its self-signup policies. |
|
|
166
179
|
|
|
167
|
-
|
|
180
|
+
All five accept `--json`, plus the common auth flags (`--base-url`, `--token`).
|
|
181
|
+
|
|
182
|
+
## `vectros namespace` — scope-namespace registrations
|
|
183
|
+
|
|
184
|
+
Register and inspect the namespaces a `scope:<namespace>` value can belong
|
|
185
|
+
to — whether values in that namespace must resolve to a real identity entity
|
|
186
|
+
(`entityBacked`, the same field `identity create --type <namespace>`
|
|
187
|
+
relies on) or are free-form strings. Registering a brand-new namespace (e.g.
|
|
188
|
+
a `practice`/`team` entity dimension) was blueprint-apply-only before this
|
|
189
|
+
command existed.
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
vectros namespace register practice --context my-app --specificity-rank 1500 --entity-backed
|
|
193
|
+
vectros namespace list # tenant-wide registrations
|
|
194
|
+
vectros namespace list --context my-app # just my-app's own
|
|
195
|
+
vectros namespace get practice --context my-app
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
| Subcommand | Flags | Notes |
|
|
199
|
+
|---|---|---|
|
|
200
|
+
| `register <name>` | `--context`, `--specificity-rank <n>` (both required); `--entity-backed`, `--default-schema-id <id>` | NOT idempotent — a repeat name 400s (unlike `issuers register`). `--context` has no tenant-wide option here — a confined credential may only register against its own bound context. |
|
|
201
|
+
| `list` | `--context <contextId>` (optional) | Omit for every tenant-wide registration; supply for one context's own. |
|
|
202
|
+
| `get <name>` | `--context <contextId>` (optional) | Same two-mode read as `list`. |
|
|
203
|
+
|
|
204
|
+
No `update`/`delete` — both routes require a genuine root API key on the
|
|
205
|
+
platform side, which this CLI never holds, so neither could ever succeed
|
|
206
|
+
here. All three subcommands accept `--json`.
|
|
168
207
|
|
|
169
208
|
## `vectros identity` — tenant-wide principals
|
|
170
209
|
|
|
@@ -190,12 +229,13 @@ vectros identity invite --context my-app --role editor --email bob@example.com \
|
|
|
190
229
|
| | `--type user` only: `--email <email>`, `--service` (mint a SERVICE principal; default HUMAN) | `--name`/`--scope` are rejected for `--type user`. |
|
|
191
230
|
| | entity namespaces only: `--name <name>`, `--scope <ns:value>` (repeatable, up to 2 parent ownership edges) | `--email`/`--service` are rejected for an entity namespace. |
|
|
192
231
|
| | both: `--metadata <json>` | Free-form JSON object. |
|
|
193
|
-
| `list` | `--type <user\|namespace>` (required), `--external-id <id>` (filter), `--limit <n>` | Omit `--limit` and the CLI drains every page for the complete set; pass `--limit` (1–100) and it returns exactly one page of that size instead. |
|
|
232
|
+
| `list` | `--type <user\|namespace>` (required), `--external-id <id>` (filter), `--limit <n>` | Scoped to your own context — see `list-all` below for a user created but never granted access anywhere. Omit `--limit` and the CLI drains every page for the complete set; pass `--limit` (1–100) and it returns exactly one page of that size instead. |
|
|
233
|
+
| `list-all` | `--external-id <id>` (filter), `--tenant test\|live`, `--limit <n>` | **Users only, and requires an account owner login.** Lists every user in the tenant, regardless of app-context access — for recovering a user `identity list` can never show you: one created but not (yet) granted access anywhere, so no context-scoped view can ever reach it, and a `create` retry with the same `--external-id` just collides with the same invisible row. Find it here by `--external-id`, then grant it access or `identity delete` it with an ordinary credential. |
|
|
194
234
|
| `get` | `--type <user\|namespace>` (required), `--id <vectrosId>` (required) | `--id` is the Vectros-assigned id from `create`/`list`, not the `--external-id`. |
|
|
195
235
|
| `delete` | `--type <user\|namespace>` (required), `--id <vectrosId>` (required) | |
|
|
196
236
|
| `invite` | `--context <c>`, `--role <roleId>`, `--email <e>` (all required); `--first-name <n>`, `--accept-url <url>`, `--no-send-email` | Onboards a person into a context by email (`POST /v1/users/invite`) — no root key required, your `vectros login` session already carries enough scope. `--role` is an existing Role's own id (no separate lookup). `--accept-url` is required unless `--no-send-email` is given, in which case the response carries the raw `inviteToken`/`acceptLink` for you to deliver yourself. |
|
|
197
237
|
|
|
198
|
-
`create`/`list`/`get`/`invite` accept `--json`; `delete` does not.
|
|
238
|
+
`create`/`list`/`list-all`/`get`/`invite` accept `--json`; `delete` does not.
|
|
199
239
|
|
|
200
240
|
## `vectros role` — reusable, context-scoped access rules
|
|
201
241
|
|
|
@@ -210,6 +250,8 @@ vectros role create --context my-app --role-id editor --name Editor \
|
|
|
210
250
|
--actions records:cru,search:r
|
|
211
251
|
vectros role create --context my-app --role-id own-org --name "Own org" \
|
|
212
252
|
--actions records:r --data-scope '{"scope:org":["<orgId>", null]}'
|
|
253
|
+
vectros role create --context my-app --role-id hr-admin --name "HR Admin" \
|
|
254
|
+
--actions records:cru --assumable '{"scope:org":["org_engineering", "org_sales"]}'
|
|
213
255
|
vectros role list --context my-app
|
|
214
256
|
vectros role get --context my-app --role-id editor
|
|
215
257
|
vectros role delete --context my-app --role-id editor
|
|
@@ -217,13 +259,35 @@ vectros role delete --context my-app --role-id editor
|
|
|
217
259
|
|
|
218
260
|
| Subcommand | Flags | Notes |
|
|
219
261
|
|---|---|---|
|
|
220
|
-
| `create` | `--context <c>`, `--role-id <id>`, `--name <n>`, `--actions <csv>` (all required); `--data-scope <json>`, `--description <text>` | Idempotent by `roleId`. `--data-scope` confines the clause to owned data — a JSON map of ownership dimension → allowed values, ANDed across keys (e.g. `{"userId":["${{ self.userId }}"]}`, or `{"scope:org":["<orgId>", null]}` — the `null` entry additionally admits scope-less/tenant-shared records). Keys must be `userId` or `scope:<namespace>` (the legacy flat `orgId`/`clientId` keys are rejected server-side). |
|
|
262
|
+
| `create` | `--context <c>`, `--role-id <id>`, `--name <n>`, `--actions <csv>` (all required); `--data-scope <json>`, `--assumable <json>`, `--description <text>` | Idempotent by `roleId`. `--data-scope` confines the clause to owned data — a JSON map of ownership dimension → allowed values, ANDed across keys (e.g. `{"userId":["${{ self.userId }}"]}`, or `{"scope:org":["<orgId>", null]}` — the `null` entry additionally admits scope-less/tenant-shared records). Keys must be `userId` or `scope:<namespace>` (the legacy flat `orgId`/`clientId` keys are rejected server-side). `--assumable` is a SEPARATE, role-level grant — a JSON map of `scope:<namespace>` → allowed values naming which values a holder of this role may switch into via `vectros assume`; holding broad `--data-scope` reach in a namespace does not by itself grant assuming any value in it. |
|
|
221
263
|
| `list` | `--context <c>` (required) | |
|
|
222
|
-
| `get` | `--context <c>`, `--role-id <id>` (both required) | Also shows the role's `assumable` grant
|
|
264
|
+
| `get` | `--context <c>`, `--role-id <id>` (both required) | Also shows the role's `assumable` grant, if any is set. |
|
|
223
265
|
| `delete` | `--context <c>`, `--role-id <id>` (both required) | No cascade — any access profile still referencing the role fails to mint (not silently downgraded) until reassigned. |
|
|
224
266
|
|
|
225
267
|
`create`/`list`/`get` accept `--json`; `delete` does not.
|
|
226
268
|
|
|
269
|
+
## `vectros assume` — switch identity namespace values on your own token
|
|
270
|
+
|
|
271
|
+
Re-mints your own verb token with one or more `identity.<namespace>` values
|
|
272
|
+
switched — the "org switcher" flow, named (like the platform endpoint it
|
|
273
|
+
calls) after AWS STS `AssumeRole`. Only works if a role you currently hold
|
|
274
|
+
explicitly grants assuming the requested value(s) via that role's own
|
|
275
|
+
`--assumable` grant (checked live against your CURRENT roles, never a value
|
|
276
|
+
frozen into your token at mint time).
|
|
277
|
+
|
|
278
|
+
```bash
|
|
279
|
+
vectros assume --context my-app --scope org:org_sales
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
| Flags | Notes |
|
|
283
|
+
|---|---|
|
|
284
|
+
| `--context <c>` (required), `--scope <ns:value>` (repeatable, at least one required) | Each `--scope` becomes one `scope:<namespace>` entry in the request. No artificial cap on how many namespaces you name — the platform requires a SINGLE role to jointly grant the whole combination and rejects an unsatisfiable one itself. |
|
|
285
|
+
|
|
286
|
+
Prints the re-minted `access_token`/`expires_in` (accepts `--json`) — there
|
|
287
|
+
is no `--to-keyring` here, since the result is an ephemeral bearer token
|
|
288
|
+
with the same remaining lifetime as the verb token this command itself
|
|
289
|
+
mints to make the call, not a durable secret the keyring is built to hold.
|
|
290
|
+
|
|
227
291
|
## `vectros access` — bind principals to contexts
|
|
228
292
|
|
|
229
293
|
The binding layer between an identity and a context: `access grant` joins a
|
|
@@ -437,10 +501,10 @@ A blueprint's `accessProfile` and role clauses may also declare
|
|
|
437
501
|
`capabilities: [...]` — named platform effects (like creating or removing an
|
|
438
502
|
identity in your tenant) that reach across a partition boundary in a way no
|
|
439
503
|
`resource:ops` verb can express. This rides a field entirely separate from
|
|
440
|
-
`allowedActions`, and it has its own allowlist:
|
|
441
|
-
admitted today.** Every other capability name —
|
|
442
|
-
own registry recognizes — is refused, the same
|
|
443
|
-
posture as the scope gate above. `vectros blueprint validate`/`plan` and
|
|
504
|
+
`allowedActions`, and it has its own allowlist: **`member-lifecycle` and
|
|
505
|
+
`delegate-principal-stamp` are admitted today.** Every other capability name —
|
|
506
|
+
including ones the platform's own registry recognizes — is refused, the same
|
|
507
|
+
fail-closed, deliberately-widen posture as the scope gate above. `vectros blueprint validate`/`plan` and
|
|
444
508
|
`bootstrap` all report a rejected capability the same way they report a
|
|
445
509
|
rejected scope: nothing mints, and the CLI exits non-zero.
|
|
446
510
|
|