@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.
- package/README.md +95 -22
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
[](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
|
|
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`
|
|
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
|
-
###
|
|
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
|
-
#
|
|
94
|
-
vlt
|
|
95
|
-
|
|
96
|
-
#
|
|
97
|
-
vlt
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
#
|
|
101
|
-
vlt
|
|
102
|
-
|
|
103
|
-
#
|
|
104
|
-
vlt
|
|
105
|
-
vlt
|
|
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
|
-
|
|
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
|
|
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