v0.1.1.0 feat: optional remote URL in .secrets-store (EGB-282) (#2)
* chore: ignore .gstack/ (per-project local state)
* feat: optional remote URL in .secrets-store (EGB-282)
A second whitespace-separated token after the store name in .secrets-store
is treated as the store's git remote URL. When a teammate clones a project
bound to a store they don't have locally yet, the directed missing-store
error now fills in `git clone <url> <path>` so they can copy-paste instead
of asking the original setter for the URL.
Backward compatible: single-token .secrets-store files (the v0.1.0.x
format) continue to work and produce the existing `<their-store-remote>`
placeholder.
Security hardening (caught by adversarial review during /ship):
- The rendered git clone line is meant to be copy-pasted by a teammate.
Without sanitization, `work evil.git;rm -rf ~` would render verbatim
and execute `rm -rf ~` on paste. The parser now rejects URLs containing
shell metacharacters (;&|<>$`(){}*?!"'\\), control characters (incl.
ANSI escape sequences that could spoof terminal output), and embedded
whitespace. Rejected URLs are dropped with a stderr warning; the error
falls back to the safe placeholder.
- Switched from `set -- $line` to `read -r spec rest` so the URL field
isn't glob-expanded or word-split — important so `work *` from a
populated directory doesn't leak filenames into the URL field.
Tests 72 → 80. New: backward compat, SSH+HTTPS+~/-prefix URL forms,
comment-and-URL form, four named injection vectors (shell metachar,
backtick, $(), ANSI escape), multi-token URL, glob char, and a positive
test asserting standard git URL chars round-trip unchanged.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore: bump version and changelog (v0.1.1.0)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
1bb729f73b
commit
7c3a76e8c1
7 changed files with 296 additions and 20 deletions
18
README.md
18
README.md
|
|
@ -267,6 +267,14 @@ git add .secrets-store
|
|||
git commit -m "use work secrets store"
|
||||
```
|
||||
|
||||
For teammates who haven't set up the store yet, you can include the store's git remote URL on the same line so they don't have to ask you for it:
|
||||
|
||||
```bash
|
||||
echo "work git@github.com:acme/work-secrets.git" > .secrets-store
|
||||
```
|
||||
|
||||
That second token (whitespace-separated) is optional, ignored when the store already exists locally, and used as a copy-paste-ready hint in the missing-store error message when it doesn't. See "Joining a teammate's bound project" below.
|
||||
|
||||
After that, every `secrets push` / `secrets pull` from this project (or any subdirectory) automatically uses `~/.secrets-work`. Teammates who clone the project get the same binding for free — the file is in the repo.
|
||||
|
||||
When you push or pull from a non-default store, `secrets` echoes which one is active so you can spot mistakes immediately:
|
||||
|
|
@ -278,7 +286,9 @@ When you push or pull from a non-default store, `secrets` echoes which one is ac
|
|||
|
||||
#### Joining a teammate's bound project
|
||||
|
||||
If you clone a project that has a committed `.secrets-store: work` file but you don't have `~/.secrets-work` set up locally, `secrets pull` will tell you exactly what to do:
|
||||
If you clone a project that has a committed `.secrets-store: work` file but you don't have `~/.secrets-work` set up locally, `secrets pull` will tell you exactly what to do.
|
||||
|
||||
When the original setter included the remote URL in `.secrets-store` (recommended), the error fills in the actual `git clone` command for you to copy-paste:
|
||||
|
||||
```
|
||||
ERROR: Store not initialized: /Users/you/.secrets-work
|
||||
|
|
@ -286,16 +296,16 @@ ERROR: Store not initialized: /Users/you/.secrets-work
|
|||
This path doesn't exist on this machine yet.
|
||||
|
||||
If you're joining a teammate's existing store:
|
||||
git clone <their-store-remote> /Users/you/.secrets-work
|
||||
git clone git@github.com:acme/work-secrets.git /Users/you/.secrets-work
|
||||
# then copy their key.txt to /Users/you/.secrets-work/key.txt
|
||||
|
||||
If you want a fresh new store at this path:
|
||||
secrets --store /Users/you/.secrets-work init
|
||||
```
|
||||
|
||||
You'll need two things from the teammate who set it up:
|
||||
If the URL wasn't in the file, the error shows `<their-store-remote>` as a placeholder — you'll need to ask the teammate who set it up. Either way, you need two things to finish onboarding:
|
||||
|
||||
1. **The git remote URL** of the work-secrets repo — clone it to `~/.secrets-work` (or wherever the `.secrets-store` file resolves to on your machine).
|
||||
1. **The git remote URL** of the work-secrets repo — clone it to `~/.secrets-work` (or wherever the `.secrets-store` file resolves to on your machine). The `.secrets-store` file may already include this for you.
|
||||
2. **The age key file** (`key.txt`) — same as standing up any new machine. AirDrop, scp, or USB.
|
||||
|
||||
Once both are in place, `secrets pull` works.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue