feat(app): node-override secrets UX + supabase scaffold refresh

- Secrets page: 'Node overrides' section (per-node values that shadow a shared
  secret on that node) — list/reveal/edit/delete + add; shared secrets show an
  'override: <node>' badge. Authority-only writes.
- API: GET /secrets/overrides, GET/PUT/DELETE /secrets/overrides/{node}/{name};
  OpenBaoBackend.list_node_overrides enumerates castle/nodes/*
- supabase scaffold: drop stale 'cat ~/.castle/secrets/...' + 'castle deploy',
  point at the dashboard Secrets page / castle apply
- tests: file-backend override endpoints (empty/400/404)

Verified live: primer's postgres override discoverable + full CRUD round-trip.
This commit is contained in:
2026-07-07 07:54:28 -07:00
parent c07a23e9a1
commit 01d0abd5ed
6 changed files with 327 additions and 11 deletions

View File

@@ -675,8 +675,8 @@ serve((_req: Request) => {
project_dir / "public" / "config.js",
sub(
"""// Substrate wiring for __NAME__. The anon key is designed to be public
// (RLS enforces access) — paste yours here, or inject at deploy time:
// cat ~/.castle/secrets/SUPABASE_ANON_KEY
// (RLS enforces access) — paste yours here. Find it in the dashboard
// Secrets page (or `castle mesh`/vault), secret name SUPABASE_ANON_KEY.
window.APP = {
SUPABASE_URL: "https://supabase.lan",
SUPABASE_ANON_KEY: "PASTE_ANON_KEY_HERE",
@@ -758,8 +758,9 @@ live on the substrate; rebuild the rest from git anytime.
## Develop
- Edit `migrations/`, then `castle program build __NAME__` to apply new migrations
(re-running is a no-op — only unapplied migrations run).
- Set the anon key in `public/config.js` (`cat ~/.castle/secrets/SUPABASE_ANON_KEY`).
- `castle deploy && castle gateway reload` → served at `/__NAME__/`.
- Set the anon key in `public/config.js` (find `SUPABASE_ANON_KEY` in the
dashboard Secrets page).
- `castle apply` → served at `__NAME__.<domain>`.
## Privacy note
RLS protects rows, not the static shell or Storage. For a `private`/`shared` app,