v0.2.0.0 feat: sync gradle.properties keys via .secrets-files (EGB-531)
Add a committed .secrets-files manifest that lets secrets track designated keys from files outside the project root (motivating case: ~/.gradle/gradle.properties for Android Clerk publishable keys, which Android Studio GUI builds read but terminal env vars can't reach). - push extracts only the named keys, encrypts under <project>/external/ - pull MERGES them into the target, preserving unrelated keys/comments/order - pure-bash merge (no sed/regex): exact-string key match, opaque values - path validator: basename gradle.properties, within $HOME, no symlink/.. - external/ subdir keeps blobs out of the dotenv *.age globs; rekey + list recurse explicitly - which reads back the manifest; list shows [external]; pre-commit blocks plaintext gradle.properties Also fixes two latent bugs in 'secrets rekey' (never completed before, no prior test): age-keygen refusing to overwrite key.txt, and an EXIT trap referencing an out-of-scope local under set -u. Tests: 80 -> 104. Reviewed via /autoplan (CEO/Eng/DX). EGB-531.
This commit is contained in:
parent
ac2195d830
commit
110ac514cc
7 changed files with 816 additions and 13 deletions
45
README.md
45
README.md
|
|
@ -54,6 +54,8 @@ flowchart TD
|
|||
|
||||
Files like `.envrc` (direnv) and `.environment-*` are intentionally **not** tracked.
|
||||
|
||||
Beyond project files, `secrets` can also sync designated keys from files that live *outside* the project — like `~/.gradle/gradle.properties` — merging them in without clobbering unrelated keys. See [External files (Gradle properties)](#external-files-gradle-properties).
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- **macOS** (uses Homebrew for installation)
|
||||
|
|
@ -346,6 +348,47 @@ Inside `~/.secrets/`, workspace secrets are organized by path:
|
|||
|
||||
Requires `jq` (`brew install jq`).
|
||||
|
||||
### External files (Gradle properties)
|
||||
|
||||
Some credentials don't live in your project at all. Android builds, for example, read keys from `~/.gradle/gradle.properties` — a global file, outside any project, shared by every Gradle project on your machine (the project's own `gradle.properties` is git-tracked, so it's the wrong home for secrets). `secrets` can sync specific keys from such a file without touching the unrelated keys around them.
|
||||
|
||||
You declare what to sync in a committed `.secrets-files` manifest at your project root, one entry per line:
|
||||
|
||||
```
|
||||
# <type> <path> <keys...>
|
||||
gradle-properties ~/.gradle/gradle.properties beaconClerkPkTest beaconClerkPkLive
|
||||
```
|
||||
|
||||
- **type** — `gradle-properties` (the only supported type today).
|
||||
- **path** — absolute or `~/`-relative. The basename must be `gradle.properties` and must resolve inside `$HOME`.
|
||||
- **keys** — the property names to sync. Only these keys are read on push and merged on pull; everything else in the file is left alone.
|
||||
|
||||
#### Syncing to a second machine
|
||||
|
||||
On the machine that already has the keys set:
|
||||
|
||||
```bash
|
||||
cd ~/myapp
|
||||
echo "gradle-properties ~/.gradle/gradle.properties beaconClerkPkTest beaconClerkPkLive" > .secrets-files
|
||||
git add .secrets-files && git commit -m "sync gradle Clerk keys"
|
||||
secrets push
|
||||
# ==> Extracted 2 key(s) from ~/.gradle/gradle.properties
|
||||
```
|
||||
|
||||
`secrets push` extracts just those keys, encrypts them, and stores them under `<project>/external/` in your secrets repo. Run `secrets which` from the project to confirm the manifest parsed.
|
||||
|
||||
On the other machine (after the usual key + repo setup):
|
||||
|
||||
```bash
|
||||
cd ~/myapp
|
||||
secrets pull
|
||||
# ==> Merged 2 key(s) into ~/.gradle/gradle.properties (beaconClerkPkTest, beaconClerkPkLive)
|
||||
```
|
||||
|
||||
`secrets pull` merges those keys into the local `~/.gradle/gradle.properties`, leaving every other key untouched. If a managed key already exists, its value is updated in place; comments, ordering, and unrelated entries are preserved. The file is backed up to `gradle.properties.secrets-bak` before the first merge.
|
||||
|
||||
> **Note:** unlike `.env` files, merged Gradle keys are written as **permanent plaintext** into the target file — `secrets clear` does **not** remove them. This is appropriate for publishable / low-secrecy values (like Clerk publishable keys, `pk_*`). For high-value secrets that should never sit on disk, use `secrets run` with a `.env` instead.
|
||||
|
||||
## Safety features
|
||||
|
||||
- **`secrets run` auto-clears** — plaintext files are deleted when the command exits, errors, or is interrupted with Ctrl-C
|
||||
|
|
@ -389,7 +432,7 @@ For complete rotation with no historical exposure, create a fresh `~/.secrets/`
|
|||
## Development
|
||||
|
||||
```bash
|
||||
# Run the test suite (37 tests)
|
||||
# Run the test suite (104 tests)
|
||||
brew install bats-core
|
||||
bats test/secrets.bats
|
||||
```
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue