@circlesac/vlt-cli 26.6.1 → 26.6.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 (2) hide show
  1. package/README.md +95 -22
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -2,7 +2,12 @@
2
2
 
3
3
  [![npm](https://img.shields.io/npm/v/@circlesac/vlt-cli.svg)](https://www.npmjs.com/package/@circlesac/vlt-cli)
4
4
 
5
- `vlt` is the official CLI for [Circles Vault](https://github.com/circlesac/vault) — a 1Password Connect-compatible secrets manager on Cloudflare Workers. It speaks the same `op://<vault>/<item>/<field>` secret reference syntax as 1Password's `op` CLI, so most workflows that use `op read`, `op inject`, or `op run` work unchanged by setting `OP_CONNECT_HOST`.
5
+ `vlt` is the official CLI for [Circles Vault](https://github.com/circlesac/vault) — a secrets manager on Cloudflare Workers with two parallel address surfaces:
6
+
7
+ - **`op://<vault>/<item>/<field>`** — 1Password Connect-compatible. Most workflows that use `op read`, `op inject`, or `op run` work unchanged by setting `OP_CONNECT_HOST`.
8
+ - **`vlt://<provider>/<owner>[/<repo>]/<NAME>`** — flat GitHub-Secrets-style key→value secrets, addressed by GitHub coordinates. The repo segment selects the scope: present → project secret, absent → owner-global. Designed to replace GitHub Actions secrets (the coordinate is identical to the OIDC `repository` claim).
9
+
10
+ `vlt read`, `vlt inject`, and `vlt run` accept both schemes anywhere a reference appears.
6
11
 
7
12
  ## Install
8
13
 
@@ -25,7 +30,7 @@ npm install -g @circlesac/vlt-cli
25
30
  2. **`OP_CONNECT_HOST` + GitHub Actions OIDC** — if `ACTIONS_ID_TOKEN_REQUEST_URL`/`_TOKEN` are present (workflow has `id-token: write`), `vlt` fetches a short-lived OIDC token automatically. No stored secrets.
26
31
  3. **`crcl` config** (`~/.config/crcl/config`) — interactive user. Run `crcl login`, optionally `--profile dev` to target the dev environment.
27
32
 
28
- `vlt whoami` shows the resolved host + org.
33
+ `vlt whoami` shows the resolved host + account (`personal` by default, or `org:<slug>` with `--org`/`CRCL_ORG`).
29
34
 
30
35
  ## Common commands
31
36
 
@@ -55,9 +60,19 @@ cat template.env | vlt inject > .env
55
60
 
56
61
  ```bash
57
62
  DB_PASS="op://my-vault/db-credentials/password" vlt run -- ./deploy.sh
63
+
64
+ # op run idiom: keep references in a committed env file (references are not secrets)
65
+ vlt run --env-file=.vlt.env -- ./deploy.sh
66
+ ```
67
+
68
+ ```bash
69
+ # .vlt.env — safe to commit; values are fetched at runtime
70
+ DB_PASSWORD=vlt://github.com/acme/api/DB_PASSWORD
71
+ OPENAI_KEY=vlt://github.com/acme/OPENAI_KEY
72
+ LEGACY_PASS=op://my-vault/db-credentials/password
58
73
  ```
59
74
 
60
- `vlt run` scans the process env for `op://` references and replaces them with the actual secret values before exec'ing the command.
75
+ `vlt run` resolves `op://` / `vlt://` references found in `--env-file` entries and the process env, then exec's the command with the actual values.
61
76
 
62
77
  ### Manage vaults
63
78
 
@@ -87,32 +102,58 @@ vlt document list --vault prod-secrets
87
102
  vlt document get "TLS Cert" --vault prod-secrets -o ./cert.pem
88
103
  ```
89
104
 
90
- ### OIDC grants (operator-only)
105
+ ### GitHub-coordinate secrets (vlt://)
106
+
107
+ A secret is just an op:// **item** (there's no separate "secret" store or verb). What's special about a vault named like a GitHub coordinate — `github.com/<owner>[/<repo>]` — is that it's addressed by the **`vlt://` reference scheme**, which exists for two reasons `op://` can't cover:
108
+
109
+ 1. **Coordinate names contain `/`.** An `op://<vault>/<item>/<field>` reference splits on `/`, so it can't name a vault like `github.com/acme/api` (the slashes collide). `vlt://github.com/<owner>[/<repo>]/<NAME>` knows the structure — `<NAME>` is the last segment, the leading github coordinate is the vault — so it parses unambiguously, no escaping.
110
+ 2. **Inheritance.** Reads cascade `project > global` (repo→owner), like GitHub Actions repo/org secrets.
111
+
112
+ - `vlt://github.com/<owner>/<repo>/<NAME>` — project; falls back to the owner if absent
113
+ - `vlt://github.com/<owner>/<NAME>` — owner-global
114
+ - NAME charset is GitHub-isomorphic (`[A-Z0-9_]`, no digit start, no `GITHUB_` prefix)
115
+
116
+ The item itself is still managed with the op `item`/`vault` verbs — those take the coordinate as a `--vault` **name** (a flag value, not an `op://` reference, so the slashes are fine).
91
117
 
92
118
  ```bash
93
- # Allow circlesac/my-app's workflows to read any vault in the org
94
- vlt oidc grant create circlesac/my-app
95
-
96
- # Narrow by env, restrict to a vault, grant write access
97
- vlt oidc grant create circlesac/my-app \
98
- --env production --vault prod-secrets --role write
99
-
100
- # Org-wildcard
101
- vlt oidc grant create "circlesac/*" --role read
102
-
103
- # Inspect / change / revoke
104
- vlt oidc grant list
105
- vlt oidc grant get <id>
106
- vlt oidc grant edit <id> --role write
107
- vlt oidc grant edit <id> --env null # clear an optional field
108
- vlt oidc grant delete <id>
119
+ # Register the coordinate vault (+ CI grant for a repo coordinate; org-scoped → --org)
120
+ vlt vault create github.com/acme/api --org acme
121
+
122
+ # Write a secret = create/edit an item in that vault (--vault takes the name)
123
+ vlt item create --vault github.com/acme/api --title DB_PASSWORD 'value[password]=s3cret'
124
+ vlt item edit DB_PASSWORD --vault github.com/acme/api 'value[password]=rotated'
125
+
126
+ # Read by reference — vlt:// handles the coordinate + inherits (project→owner)
127
+ vlt read "vlt://github.com/acme/api/DB_PASSWORD" # cascades to github.com/acme if absent
128
+
129
+ # List / delete = op item verbs (coordinate as --vault name)
130
+ vlt item list --vault github.com/acme/api
131
+ vlt item delete DB_PASSWORD --vault github.com/acme/api
109
132
  ```
110
133
 
111
- `vault create / edit / delete`, `oidc grant *`, and `whoami` require operator (user JWT) auth. OIDC tokens from GitHub Actions are scoped to data-plane operations (read items, write items if `role=write`) and cannot manage vaults or grants regardless of role.
134
+ **Scope: personal by default.** Commands target your personal account unless you escalate to an org with `--org <slug>` (or `CRCL_ORG`). Personal is always available, non-shared, isolated per user; an org is shared, so targeting it is explicit. CI via GitHub OIDC always resolves to the org.
135
+
136
+ ### Registering repos for CI access (operator-only)
137
+
138
+ `vlt vault create <coordinate>` creates the op:// vault that stores the secrets; for a **repo** coordinate it also records the OIDC grant that lets that repo's CI read it (**creating it is the consent**). Grants are org-scoped, so pass `--org <owner>`. Once per repo:
139
+
140
+ ```bash
141
+ vlt vault create github.com/circlesac/my-app --org circlesac
142
+ vlt vault create github.com/circlesac/my-app --org circlesac --ci-write --env production
143
+
144
+ vlt vault get github.com/circlesac/my-app --org circlesac # registration + secret count
145
+ vlt vault delete github.com/circlesac/my-app --org circlesac # revokes CI access; items remain
146
+ ```
147
+
148
+ Owner-global (`github.com/circlesac`) needs no grant — every registered repo of that owner reads it via `project > global`, and org members write to it with `vlt item create --vault github.com/circlesac --org circlesac …`.
149
+
150
+ The legacy `vlt oidc grant create|list|get|edit|delete` commands remain for op://-vault-scoped or org-wildcard (`owner/*`) grants.
151
+
152
+ `vault create / edit / delete`, `oidc grant *`, and `whoami` require operator (user JWT) auth. OIDC tokens from GitHub Actions are scoped to data-plane operations (read secrets/items, write if allowed) and cannot manage vaults or grants regardless of role.
112
153
 
113
154
  ## GitHub Actions workflow
114
155
 
115
- After registering a grant once, a workflow needs zero stored secrets:
156
+ After registering the repo once, a workflow needs zero stored secrets:
116
157
 
117
158
  ```yaml
118
159
  permissions:
@@ -132,6 +173,38 @@ jobs:
132
173
 
133
174
  `vlt` detects the runner's `ACTIONS_ID_TOKEN_REQUEST_URL` / `_TOKEN` env vars, mints a GitHub OIDC token with the right audience, and sends it to Vault. The server verifies GitHub's signature, matches the claims (`repository`, `environment`, `ref`) against the grant ACL, and serves the request.
134
175
 
176
+ For vlt:// secrets the grant's `repository` doubles as the coordinate: a granted workflow can read its own project secrets plus that owner's globals — no other coordinate, regardless of what it asks for.
177
+
178
+ ### Composite action
179
+
180
+ The repo ships a composite action that installs `vlt` and sets the endpoint:
181
+
182
+ ```yaml
183
+ permissions:
184
+ id-token: write
185
+ contents: read
186
+
187
+ steps:
188
+ - uses: actions/checkout@v4
189
+ - uses: circlesac/vlt-cli/action@main
190
+ with:
191
+ host: https://vault.circles.ac/<your-org>
192
+ - run: vlt run --env-file=.vlt.env -- ./deploy.sh
193
+ ```
194
+
195
+ With `export-env: true` the action resolves `env-file` entries into `$GITHUB_ENV` (each value masked via `::add-mask::` first), so later steps can use `${{ env.NAME }}` — one word away from GitHub-native `${{ secrets.NAME }}`:
196
+
197
+ ```yaml
198
+ - uses: circlesac/vlt-cli/action@main
199
+ with:
200
+ host: https://vault.circles.ac/<your-org>
201
+ env-file: .vlt.env
202
+ export-env: "true"
203
+ - run: ./deploy.sh # $DB_PASSWORD available to the whole job
204
+ ```
205
+
206
+ `vlt run` keeps secrets scoped to the child process (narrower exposure, recommended); `export-env` trades that for job-wide convenience.
207
+
135
208
  ## Profile / org overrides
136
209
 
137
210
  ```bash
package/package.json CHANGED
@@ -25,5 +25,5 @@
25
25
  "test": "bun test src/"
26
26
  },
27
27
  "type": "module",
28
- "version": "26.6.1"
28
+ "version": "26.6.3"
29
29
  }