--all drains an injected process-substitution key after the first project
#36
Labels
No labels
blocked
blocker:ci-red
blocker:conflict
blocker:drill-pending
blocker:unrequested
bug
claimed
documentation
enhancement
epic
merge-next
needs-triage
ready
release
scope:apply
scope:capture
scope:coolify-api
scope:fleet
scope:manifest
scope:secrets
stale
state:addressing
state:bots-reviewing
state:building
state:needs-human
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: heavy-duty/cast#36
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Follow-up from the review of #35 (which fixed #34).
The edge
decryptSecretsnow reads the identity itself (readFileSync(keyFile)) and hands it toage -d -i -on stdin — correct, and it makes the documentedCAST_AGE_KEY_FILE_<ENV>=<(pm read …)recipe work. But a process substitution is a read-once pipe, andrunProjectis called in a loop underdiff --all/apply --all(cli.ts, thefor (const [i, repo] of targets.entries())loop). Each project with a secrets store re-reads the key file:unreachableindiff --all, and aborting the fleet inapply --all.Why it's latent, not live
Only one registered project (
heavy-duty/incubator) has a prod store today, so no current invocation hits it. And the old code never worked with<(…)at all, so this is a new capability's edge, not a regression. It becomes real the moment a second project gains a secrets store.Suggested fix
Read the key bytes once per process — memoize by resolved key path (or read in
mainand thread the bytes through). Exposure is equivalent: the key already transits node memory on every call. A FIFO-based test would pin the read-once shape (the current regression test uses a regular file behind/proc/self/fd/N, which reproduces the path-resolution shape but re-opens at offset 0 on every read).🤖 Generated with Claude Code