Skip to content

feat(secrets): read the openssl passphrase from Keychain - #6048

Merged
norman-abramovitz merged 1 commit into
cloudfoundry:developfrom
nabramovitz:norm/feat/secrets-keychain
Oct 23, 2026
Merged

norman-abramovitz merged 1 commit into
cloudfoundry:developfrom
nabramovitz:norm/feat/secrets-keychain

Conversation

@nabramovitz

Copy link
Copy Markdown
Contributor

Summary

scripts/secrets.sh encrypts and decrypts secrets.yaml with openssl, which asks for the passphrase every time. Nothing records the passphrase, and losing it makes secrets.yaml.enc unreadable. This adds an opt-in macOS Keychain source for the passphrase.

security add-generic-password -s stratos-e2e-secrets -a passphrase -w   # once; security prompts for the value
scripts/secrets.sh run-e2e --keychain stratos-e2e-secrets               # or: export STRATOS_SECRETS_KEYCHAIN=stratos-e2e-secrets

How it works

  • STRATOS_SECRETS_KEYCHAIN=<service> sets the source, and --keychain <service> overrides it. This follows the script's existing flag and variable pairs (--env/E2E_ENV, --backend/STRATOS_SECRETS_BACKEND). The account is always passphrase, so --env NAME can use its own service.
  • encrypt, decrypt and run-e2e all go through one openssl_enc wrapper. With a service set, the passphrase reaches openssl through a file descriptor (-pass fd:3 3< <(security find-generic-password … -w)). It never appears in argv or an exported variable.
  • With neither the flag nor the variable set, the openssl arguments are exactly the same as before and openssl prompts as it does today.
  • The cipher options are unchanged, so files made with the interactive prompt decrypt through the Keychain, and the other way round.
  • A missing Keychain item stops the script and prints the command to add it. No security command (Linux) also stops it. Neither case falls back to the prompt.
  • check reports whether the item exists. The sops backend is unchanged.
  • docs/secrets-management.md gains a Keychain section, a row in the variables table and two troubleshooting rows.

Tests

scripts/tests/secrets-keychain.test.mjs runs under bun with a fake security first on PATH; the real Keychain is never touched. It checks:

  • an encrypt/decrypt round trip;
  • a file made with --keychain decrypts with a plain openssl passphrase;
  • a file made with a plain openssl passphrase decrypts through the Keychain path;
  • run-e2e passes the decrypted content on;
  • a missing item fails loudly;
  • a missing security command fails loudly.

The tests failed against the script before this change and pass after it. With the original script put back, all 6 fail again.

make check gate: passed (4514 tests passed, 1 skipped).

Release note: changelog.d/0024-secrets-keychain.md.

AI disclosure (RFC-0047): prepared with AI coding assistance; reviewed by the author.

The openssl backend of scripts/secrets.sh always let openssl prompt
for the passphrase. With --keychain SERVICE, or
STRATOS_SECRETS_KEYCHAIN=SERVICE, it now reads it from the macOS
Keychain item with that service and account "passphrase", and hands
it to openssl on fd 3, never in argv or the environment. encrypt,
decrypt, run-e2e and check all use it; the sops backend is unchanged.

The cipher and options are unchanged and openssl takes the first line
of the fd as the prompt would, so files stay interchangeable with ones
encrypted at the prompt. With neither set, the behaviour is as
before. A missing item, or no security command, stops the script
with an error instead of falling back to the prompt.

docs/secrets-management.md and the script header document the
convention: service stratos-e2e-secrets, account passphrase, shared
by every --env file unless another service is named.
scripts/tests/secrets-keychain.test.mjs drives the script with a fake
security command on PATH.

@norman-abramovitz norman-abramovitz left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@norman-abramovitz
norman-abramovitz merged commit 79b3970 into cloudfoundry:develop Oct 23, 2026
24 checks passed
@nabramovitz
nabramovitz deleted the norm/feat/secrets-keychain branch October 23, 2026 01:09
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.

2 participants