From 70a6c9fe5c8dde09ef20091638d5e691895e4880 Mon Sep 17 00:00:00 2001 From: Anthony Ettinger Date: Thu, 13 Aug 2026 23:56:23 +0000 Subject: [PATCH] Advertise the ssh provider on the marketing page The marketing-drift contract failed the build because `ssh` shipped in the provider registry with no entry in MARKETING_PROOF -- which is the test working: it exists so a provider cannot ship while the pages people actually land on still describe the tool without it. The proof regex is `/~\/\.ssh|SSH key/` rather than a bare `/SSH/` on purpose. The provider grid renders every registry `name`, and this one is "Local SSH directory", so `/SSH/` would already be satisfied by the generated grid and the provider could ship with no copy written about it at all -- passing the test while failing its intent. Requiring the path or the phrase means a human wrote a sentence. That sentence is the new block in the credential-sharing band: ~/.ssh is a directory of files whose permission bits are load-bearing, not a set of KEY=VALUE lines, which is the part that makes this provider different from the other six. README already named ~/.ssh keys, so it needed no change. apps/logicsrc-web: 75/75 contract tests pass (was 74 passed, 1 failed). Co-Authored-By: Claude Opus 5 --- .../contract/marketing-drift.contract.test.ts | 8 +++++++- apps/logicsrc-web/src/lib/page-markup.ts | 6 ++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/apps/logicsrc-web/contract/marketing-drift.contract.test.ts b/apps/logicsrc-web/contract/marketing-drift.contract.test.ts index 8789d3f..b9a8cb9 100644 --- a/apps/logicsrc-web/contract/marketing-drift.contract.test.ts +++ b/apps/logicsrc-web/contract/marketing-drift.contract.test.ts @@ -27,7 +27,13 @@ const MARKETING_PROOF: Record = { railway: /Railway/, "github-secrets": /GitHub Secrets/, sh1pt: /sh1pt/, - team: /[Tt]eam vault/ + team: /[Tt]eam vault/, + // Deliberately not a bare /SSH/. The provider grid renders every registry + // `name`, and this one is "Local SSH directory" -- so /SSH/ would be + // satisfied by the grid alone and this provider could ship with no copy + // written about it at all, which is the drift these tests exist to catch. + // Requiring the path or the phrase means a human wrote a sentence. + ssh: /~\/\.ssh|SSH key/ }; const REPO_ROOT = resolve(process.cwd(), "../.."); diff --git a/apps/logicsrc-web/src/lib/page-markup.ts b/apps/logicsrc-web/src/lib/page-markup.ts index 4f0d701..f28f02e 100644 --- a/apps/logicsrc-web/src/lib/page-markup.ts +++ b/apps/logicsrc-web/src/lib/page-markup.ts @@ -309,6 +309,12 @@ logicsrc teams invite acme teammate@example.com # emails an accept link logicsrc teams grant acme web prod teammate@example.com logicsrc teams pull acme web prod --env .env # download + decrypt logicsrc credentials rotate acme web prod --approve +

SSH keys, not just environment variables

+

Not every secret is a KEY=VALUE line. ~/.ssh is a directory of files whose permission bits are load-bearing — a private key restored world-readable is one OpenSSH will refuse to use. The ssh provider moves that directory through the same end-to-end-encrypted vault as everything else and puts each file back with its mode intact, so a new machine is set up rather than merely populated. Restored SSH keys can go straight into ssh-agent instead of onto disk.

+
logicsrc secrets ssh push profullstack   # back up ~/.ssh to vault ssh--<you>
+logicsrc secrets ssh list profullstack   # what the vault holds: paths, kinds, modes
+logicsrc secrets ssh pull profullstack   # restore on another machine, permissions and all
+logicsrc secrets ssh agent profullstack  # load into ssh-agent, never onto disk
${credentialProviders.map((item) => `