Repository navigation
fix(cli): read secret values from stdin #85
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 9 commits
Commits
Show all changes
29 commits
Select commit
Hold shift + click to select a range
e8b2569
test(cli): prohibit secrets in process argv
seonghobae e14bc64
test(cli): define bounded no-echo secret input
seonghobae ba11d16
fix(cli): ingest secrets without process argv exposure
seonghobae 0ed6e28
test(cli): route legacy secret command through stdin
seonghobae 2a71066
docs(security): define CLI secret input boundary
seonghobae b01965c
docs(cli): remove plaintext secret argv examples
seonghobae dbcb99c
docs(changelog): record safe CLI secret ingestion
seonghobae 882e43c
docs(security): classify RED PR evidence accurately
seonghobae e88fe90
test(cli): fail closed on getpass echo fallback
seonghobae 44ffbe5
fix(cli): refuse echoed interactive secret fallback
seonghobae 7be44e8
test(cli): match fail-closed echo diagnostic
seonghobae 3f394f3
docs(cli): document fail-closed echo fallback
seonghobae 818aa5e
docs(changelog): record fail-closed secret prompt
seonghobae a3f6fe8
docs(cli): scope secret non-disclosure claim
seonghobae 20e7fb2
test(cli): prevent rejected argv secret disclosure
seonghobae 6729687
fix(cli): redact rejected argv values
seonghobae c771a68
docs(cli): record argv diagnostic redaction
seonghobae e68d645
docs(cli): document parser diagnostic confidentiality
seonghobae 9cca9f1
test(cli): reject non-LF secret line boundaries
seonghobae bd342cc
fix(cli): reject non-LF secret line boundaries
seonghobae 2c961d7
test(docs): require complete secret line boundary
seonghobae e1158f1
docs(cli): define complete secret line boundary
seonghobae 4d474f9
docs(cli): record complete secret line boundary
seonghobae 6418ae9
merge(main): reconcile secret-input hardening with exact-source gover…
seonghobae efe95d9
Merge protected main into agent/secret-stdin-cli
seonghobae cdf03c3
Merge protected main into agent/secret-stdin-cli
seonghobae 82110ed
Merge branch 'main' into agent/secret-stdin-cli
opencode-agent[bot] 331af12
Merge branch 'main' into agent/secret-stdin-cli
opencode-agent[bot] cae78e7
Merge branch 'main' into agent/secret-stdin-cli
opencode-agent[bot] File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| # CLI secret-input boundary | ||
|
|
||
| ## Problem | ||
|
|
||
| `config set-secret` is an operator credential-ingestion boundary. A secret value | ||
| must not be supplied as a positional command-line argument because process | ||
| arguments are an observable invocation surface on common operating systems and | ||
| can also be retained by shell tooling. The secret-store encryption boundary does | ||
| not mitigate exposure that happens before the value reaches PostgreSQL. | ||
|
|
||
| ## Contract | ||
|
|
||
| The command accepts only the secret key in process arguments: | ||
|
|
||
| ```text | ||
| python -m pg_llm_batch config set-secret gateway_api_key.default | ||
| ``` | ||
|
|
||
| The value is acquired separately: | ||
|
|
||
| - when standard input is an interactive terminal, `getpass.getpass()` requests | ||
| one value without echoing typed characters; | ||
| - when standard input is non-interactive, exactly one bounded logical line is | ||
| read from standard input so an existing secret-management process can pipe a | ||
| value without placing it in the `pg_llm_batch` process argument vector; | ||
| - one terminal LF or CRLF is removed from non-interactive input; | ||
| - empty, multiline, carriage-return-containing, and values longer than 65,536 | ||
| characters fail closed before `SecretStore` is constructed or written; and | ||
| - errors, success output, logs, and tests never include the supplied plaintext. | ||
|
coderabbitai[bot] marked this conversation as resolved.
Resolved
|
||
|
|
||
| The non-interactive path intentionally does not define or require a particular | ||
| external secret manager. Deployment owners may connect their existing | ||
| credential source to standard input without changing the repository's secret | ||
| storage or bootstrap-key contract. | ||
|
|
||
| ## Verification | ||
|
|
||
| `tests/test_cli_secret_input_security.py` proves that plaintext is rejected from | ||
| process arguments, TTY input uses the no-echo primitive rather than an ordinary | ||
| stdin read, piped input is bounded and single-line, common terminal line endings | ||
| are normalized, and unsafe shapes fail closed. `tests/test_bootstrap_cli.py` | ||
| keeps the existing CLI routing test while providing its fixture value through | ||
| stdin. | ||
|
|
||
| The development sequence is intentionally test-first. PR CI run `31298176124` | ||
| was triggered from RED source head `e8b256992b34a8651ab5a2f0cef350d5fbde4b75` | ||
| but, under the current protected-main workflow, checked GitHub synthetic merge | ||
| commit `519ada6d67a01e66b877fc48d0b0ae5691a428d9`. It failed the two initial | ||
| secret-input contracts on Python 3.10, 3.12, and 3.14 because the old parser | ||
| still accepted a positional secret and required it when stdin-only invocation | ||
| was attempted. This is valid fail-first development evidence for the behavior, | ||
| but it is not exact-source-head acceptance evidence. No predecessor or | ||
| synthetic-merge-only result is counted as post-fix acceptance. | ||
|
coderabbitai[bot] marked this conversation as resolved.
Resolved
|
||
|
|
||
| ## References | ||
|
|
||
| MITRE. (2025). *CWE-214: Invocation of process using visible sensitive | ||
| information*. Common Weakness Enumeration. | ||
| https://cwe.mitre.org/data/definitions/214.html | ||
|
|
||
| Python Software Foundation. (2026). *getpass — Portable password input*. | ||
| Python 3.14 documentation. | ||
| https://docs.python.org/3/library/getpass.html | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.