@circlesac/vlt-cli 26.6.0 → 26.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md 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
 
@@ -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,60 @@ 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
+ ### Flat secrets (vlt://)
106
+
107
+ Flat key→value secrets addressed by GitHub coordinates — separate from the op:// vault/item store. `vlt://github.com/<owner>#<NAME>` is owner-global, `vlt://github.com/<owner>/<repo>#<NAME>` is project-scoped; lookups resolve `project > global`. NAME charset is GitHub-isomorphic (`[A-Z0-9_]`, no digit start, no `GITHUB_` prefix); there is no escaping — anything outside the charset is rejected.
108
+
109
+ ```bash
110
+ # Create / update (value from arg or stdin)
111
+ vlt secret set "vlt://github.com/acme/api#DB_PASSWORD" "s3cret"
112
+ echo -n "s3cret" | vlt secret set "vlt://github.com/acme#OPENAI_KEY"
113
+
114
+ # Read
115
+ vlt secret get "vlt://github.com/acme/api#DB_PASSWORD"
116
+
117
+ # Resolve by name with project > global precedence
118
+ vlt secret resolve DB_PASSWORD --owner acme --repo api # humans pass the coordinate
119
+ vlt secret resolve DB_PASSWORD # CI: coordinate implied by OIDC identity
120
+
121
+ # List (metadata only — values are never listed) / delete
122
+ vlt secret list
123
+ vlt secret delete "vlt://github.com/acme/api#DB_PASSWORD"
124
+ ```
125
+
126
+ Secrets belong to the configured org by default. `--personal` (or having no org configured) targets your personal account namespace instead — same scopes, addressed identically, isolated per user:
127
+
128
+ ```bash
129
+ vlt secret set --personal "vlt://github.com/ygpark80/dotfiles#TOKEN" "..."
130
+ vlt secret list --personal
131
+ ```
132
+
133
+ ### Registering repos for CI access (operator-only)
134
+
135
+ A vault whose name is a GitHub coordinate represents a repo's secret home — **creating it is the consent** that lets that repo's CI read it. One command, once per repo:
91
136
 
92
137
  ```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>
138
+ # Register: circlesac/my-app's CI can now read its project secrets + circlesac's globals
139
+ vlt vault create github.com/circlesac/my-app
140
+
141
+ # Options: CI write access to its own project, env/ref narrowing
142
+ vlt vault create github.com/circlesac/my-app --ci-write --env production
143
+
144
+ # Inspect / revoke (revoking removes CI access; the secrets remain)
145
+ vlt vault list # op:// containers + registered repos
146
+ vlt vault get github.com/circlesac/my-app
147
+ vlt vault delete github.com/circlesac/my-app
109
148
  ```
110
149
 
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.
150
+ Owner-global (`github.com/circlesac`) needs no registration every registered repo of that owner reads it via `project > global`, and org members can `vlt secret set` to it directly.
151
+
152
+ The legacy `vlt oidc grant create|list|get|edit|delete` commands remain for compatibility and for op://-vault-scoped or org-wildcard (`owner/*`) grants.
153
+
154
+ `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
155
 
113
156
  ## GitHub Actions workflow
114
157
 
115
- After registering a grant once, a workflow needs zero stored secrets:
158
+ After registering the repo once, a workflow needs zero stored secrets:
116
159
 
117
160
  ```yaml
118
161
  permissions:
@@ -132,6 +175,38 @@ jobs:
132
175
 
133
176
  `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
177
 
178
+ 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.
179
+
180
+ ### Composite action
181
+
182
+ The repo ships a composite action that installs `vlt` and sets the endpoint:
183
+
184
+ ```yaml
185
+ permissions:
186
+ id-token: write
187
+ contents: read
188
+
189
+ steps:
190
+ - uses: actions/checkout@v4
191
+ - uses: circlesac/vlt-cli/action@main
192
+ with:
193
+ host: https://vault.circles.ac/<your-org>
194
+ - run: vlt run --env-file=.vlt.env -- ./deploy.sh
195
+ ```
196
+
197
+ 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 }}`:
198
+
199
+ ```yaml
200
+ - uses: circlesac/vlt-cli/action@main
201
+ with:
202
+ host: https://vault.circles.ac/<your-org>
203
+ env-file: .vlt.env
204
+ export-env: "true"
205
+ - run: ./deploy.sh # $DB_PASSWORD available to the whole job
206
+ ```
207
+
208
+ `vlt run` keeps secrets scoped to the child process (narrower exposure, recommended); `export-env` trades that for job-wide convenience.
209
+
135
210
  ## Profile / org overrides
136
211
 
137
212
  ```bash
package/bin/install.js CHANGED
@@ -34,7 +34,12 @@ function download(url) {
34
34
  });
35
35
  }
36
36
 
37
- if (process.env.CI) process.exit(0);
37
+ // Only download when installed as a published package (always lives inside a
38
+ // node_modules tree, including npm -g). A repo checkout — local dev or the
39
+ // release workflow itself, where oneup may already have stamped a version —
40
+ // must never try to fetch its own not-yet-published release.
41
+ const isPublishedInstall = __dirname.split(path.sep).includes("node_modules");
42
+ if (!isPublishedInstall || !version) process.exit(0);
38
43
 
39
44
  const platform = `${process.platform}-${process.arch}`;
40
45
  const info = PLATFORMS[platform];
package/bin/vlt.mjs CHANGED
@@ -11,5 +11,9 @@ const bin = path.join(__dirname, "native", `vlt${ext}`);
11
11
  if (!existsSync(bin)) {
12
12
  await import("./install.js");
13
13
  }
14
+ if (!existsSync(bin)) {
15
+ console.error("[ERROR] vlt native binary is not installed (download failed or unsupported platform)");
16
+ process.exit(1);
17
+ }
14
18
  const result = spawnSync(bin, process.argv.slice(2), { stdio: "inherit" });
15
19
  process.exit(result.status ?? 1);
package/package.json CHANGED
@@ -25,5 +25,5 @@
25
25
  "test": "bun test src/"
26
26
  },
27
27
  "type": "module",
28
- "version": "26.6.0"
28
+ "version": "26.6.2"
29
29
  }