Add fleet setup template and a one-shot project bootstrap script
All checks were successful
Docker / build-and-push (push) Successful in 1m58s

SETUP.local.md.example is a fill-in-the-blanks runbook for rolling
keep out across real machines and projects (gitignored once copied to
SETUP.local.md — real vault keys/recipient ids/hostnames are fleet
topology, not something to commit). bootstrap-project.sh wraps push +
grant --read-only for one or more recipients into a single call for
onboarding a new project vault.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Fredrik Johansson
2026-07-12 21:21:55 +02:00
parent 58d5d787dd
commit 442c3b7cf5
3 changed files with 116 additions and 0 deletions

5
.gitignore vendored
View File

@@ -2,3 +2,8 @@ node_modules/
dist/
.env
data/
# Personal rollout notes — real vault keys, recipient ids, VPS hostnames.
# Not secrets themselves, but fleet topology that doesn't belong in a
# public repo. See SETUP.local.md.example for the template.
SETUP.local.md

80
SETUP.local.md.example Normal file
View File

@@ -0,0 +1,80 @@
# keep fleet setup — personal notes (copy to SETUP.local.md, gitignored)
Fill this in as you actually run the commands. It's your own record of
what recipient id belongs to which machine and which vault backs which
project — none of this is secret by itself (a recipient id or a vault
key doesn't grant access without the matching private key), but it's
real fleet topology that doesn't belong in a public repo.
## 0. Server
- [ ] Deployed at: `___________________` (e.g. https://keep.example.internal)
- [ ] `ADMIN_PASSWORD` stored in: `___________________` (password manager entry, not here)
- [ ] `KEEP_SERVER_URL` exported in shell profile on every machine below
## 1. Identities
One row per machine. `keep identity init` prints the public key; an
admin runs `keep recipient add`, which prints back a recipient id; that
id gets recorded locally with `keep identity set-id <id>`.
| Machine | Recipient id | Grant type (per vault, see §3) |
|---|---|---|
| this laptop | `___________________` | rw on everything it pushes |
| vps-1 (`___________________` hostname) | `___________________` | r- (read-only) |
| vps-2 | `___________________` | r- (read-only) |
Commands, run once per machine:
```bash
keep identity init # on the machine itself
KEEP_ADMIN_PASSWORD=... keep recipient add --label "<name>" --pubkey <hex> # from an admin machine
keep identity set-id <recipient-id> # back on the machine itself
```
## 2. Projects → vaults
One vault per project+environment. Vault key is a free-form string —
it does NOT need to match the repo name or the deploy directory name
(see IMPLEMENTATION.md — these are three independent strings in this
fleet on purpose).
| Project | Deploy dir | Vault key | `.keep-vault` written? |
|---|---|---|---|
| myapp | `/opt/docker/myapp` | `myapp/production` | [ ] |
| otherapp | `/opt/docker/otherapp` | `otherapp/production` | [ ] |
Bootstrap a project:
```bash
keep push myapp/production --file .env.production # from the laptop, becomes rw grantee
keep grant myapp/production <vps-1-recipient-id> --read-only
echo "myapp/production" > /opt/docker/myapp/.keep-vault # on vps-1, next to its docker-compose.yml
```
Or use `scripts/bootstrap-project.sh` (see below) to do the push+grant
step in one call for multiple VPS recipients at once.
## 3. CI announce (optional, per project)
Only needed if you want `keep watch` on a VPS to skip waiting for the
next scheduled sweep. Add to that project's own
`.gitea/workflows/docker.yml`, after the build-and-push step:
```yaml
- name: announce to keep
continue-on-error: true
run: keep announce myapp/production --tag ${{ steps.meta.outputs.short_sha }}
```
The vault key here must be the literal string from §2's table — not
derived from the repo name.
## 4. Sanity check
```bash
KEEP_ADMIN_PASSWORD=... keep overview
```
Confirm every project vault shows up with exactly the grants you
expect — laptop `rw`, each deploying VPS `r-`, nothing else.

31
scripts/bootstrap-project.sh Executable file
View File

@@ -0,0 +1,31 @@
#!/usr/bin/env bash
# Pushes a project's first env file and grants read-only access to one
# or more already-registered recipients (typically the VPS boxes that
# will deploy it), in one call.
#
# Usage:
# ./bootstrap-project.sh <vault> <env-file> <recipient-id> [recipient-id...]
#
# The pusher (this machine's identity) becomes the vault's first,
# read-write recipient automatically — see IMPLEMENTATION.md. Every
# recipient-id argument here is granted read-only; run `keep grant`
# by hand afterward for anyone who needs write access too.
set -euo pipefail
vault="${1:?usage: bootstrap-project.sh <vault> <env-file> <recipient-id> [recipient-id...]}"
file="${2:?usage: bootstrap-project.sh <vault> <env-file> <recipient-id> [recipient-id...]}"
shift 2
if [ "$#" -eq 0 ]; then
echo "error: at least one recipient id is required" >&2
exit 1
fi
keep push "$vault" --file "$file"
for recipient in "$@"; do
keep grant "$vault" "$recipient" --read-only
done
echo ""
echo "done. verify with: KEEP_ADMIN_PASSWORD=... keep overview"