Skip to content

cli-tools config pull: take API keys from the logicsrc team vault - #15

Merged
ralyodio merged 1 commit into
masterfrom
vault-pull
Aug 19, 2026
Merged

cli-tools config pull: take API keys from the logicsrc team vault#15
ralyodio merged 1 commit into
masterfrom
vault-pull

Conversation

@ralyodio

Copy link
Copy Markdown
Contributor

Keys now come from the team vault instead of being hunted down per-machine.

cli-tools config pull
# config: pulling profullstack/profullstack-sharable-keys--prod…
# config: imported OPENAI_API_KEY (sk-pr…ZyAA (164 chars))
# config: imported ANTHROPIC_API_KEY (sk-an…uAAA (108 chars))
#
# 11 other key(s) in the vault were left there — this stores only what
# these commands read. The vault stays the authority.

Why

Setting a machine up meant knowing which of ~180 vaults happened to carry the OpenAI key, and pulling it by hand. A rotated key reached a machine only when somebody remembered to repeat that.

A scan of all 183 team vaults found the same OpenAI key already duplicated across 27 prod vaults, and Resend across 27 more — duplication nobody chose. profullstack-sharable-keys--prod now holds the account-level keys (one account, many projects) in one place.

It imports only what these commands read

Two of the vault's thirteen keys, and it reports how many it left behind.

Copying the whole vault down would put a second copy of every team secret on the machine, drifting from the thing that is supposed to be authoritative — exactly the failure the vault exists to prevent. This is a cache of two or three keys, not a mirror, and the direction of authority is the point.

Handling the plaintext

logicsrc teams pull can only write a decrypted .env to a path, so plaintext exists for the length of one read. It goes to a 0700 temp directory and is removed in a finally, so neither a failed pull nor an unparseable file can leave it behind. Two tests assert the directory is gone on both paths, because that is the whole risk of the feature.

A missing logicsrc is reported as a missing logicsrc, with the command that installs it, rather than as an exec failure three layers down.

Target

Defaults to profullstack/profullstack-sharable-keys--prod; CLI_TOOLS_VAULT_TEAM, CLI_TOOLS_VAULT_PROJECT and CLI_TOOLS_VAULT_ENV point it elsewhere.

Checks

180 tests pass (was 167), typecheck clean. The runner is injectable, so none of the 13 new tests talk to a real vault — they cover = inside values (base64 keys and URLs would otherwise truncate), quote stripping, malformed lines, both cleanup paths, and the wrote-no-file case.

Verified against the real vault: imports 2 of 13 keys, a second run reports both already matching, credentials.json stays 0600, and no temp directory survives.

🤖 Generated with Claude Code

Setting a machine up meant knowing which of ~180 vaults happened to carry the
OpenAI key and pulling it by hand — and a rotated key reached a machine only
when somebody remembered to repeat that. Meanwhile the same key was already
sitting in 27 prod vaults, which is duplication nobody chose.

So there is now a shared vault, profullstack-sharable-keys--prod, holding the
account-level keys that are one account across many projects, and:

  cli-tools config pull

decrypts it and imports what these commands read.

It imports ONLY those keys and says how many it left behind. Copying the whole
vault down would put a second copy of every team secret on the machine, drifting
from the thing that is supposed to be authoritative — the failure the vault
exists to prevent. This is a cache of two or three keys, not a mirror, and the
direction of authority is the point.

`logicsrc teams pull` can only write a decrypted .env to a path, so plaintext
exists for the length of one read: a 0700 temp directory, removed in a finally
so a failed pull or an unparseable file cannot leave it behind. Tests assert the
directory is gone on both paths, because that is the whole risk of the feature.

A missing logicsrc is reported as a missing logicsrc, with the command that
installs it, rather than as an exec failure three layers down.

The runner is injectable, so none of the 13 new tests talk to a real vault.

180 tests pass (was 167), typecheck clean. Verified against the real vault:
imports 2 of 13 keys, second run reports both already matching, credentials.json
stays 0600, and no temp directory survives.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

ThreatCrush Security Scan

6 finding(s)

MEDIUM: 1 | LOW: 5

Severity Rule Location
MEDIUM redos-nested-quantifier src/domain-free.ts:56
LOW insecure-temp-file test/blog.test.ts:73
LOW insecure-temp-file test/blog.test.ts:74
LOW insecure-temp-file test/credentials.test.ts:43
LOW insecure-temp-file test/credentials.test.ts:44
LOW secret-generic-api-key test/credentials.test.ts:208

Snippets are redacted; ThreatCrush never prints matched credential material.

@ralyodio
ralyodio merged commit 9e22a07 into master Aug 19, 2026
5 checks passed
@ralyodio
ralyodio deleted the vault-pull branch August 19, 2026 14:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant