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) => `