fix(aws): redact secretsmanager get-secret-value payload#1986
Open
YOMXXX wants to merge 1 commit into
Open
Conversation
filter_secrets_get previously emitted the raw SecretString into
LLM-bound stdout via `format!("Secret: {}", ...)`. Tests at
aws_cmd.rs:2495-2526 had codified this leak as expected behaviour.
This change redacts the SecretString by default and emits only
non-sensitive structural metadata:
- Name (the lookup key the agent asked for)
- SecretString length + sha256 prefix (round-trip verification)
- For JSON secrets, the set of top-level keys (shape, not values)
Two opt-in escape hatches restore the previous behaviour for the
rare-but-real "AWS-rotation shell script" workflow:
- RTK_REVEAL_SECRETS=1 (env)
- --reveal-secret (CLI flag, stripped before forwarding to aws)
A one-shot stderr warning fires once per process the first time
redaction is applied, so the change is not silent.
Refs rtk-ai#1875 (Finding 1)
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Summary
filter_secrets_getpreviously emitted the rawSecretStringinto LLM-bound stdout viaformat!("Secret: {}", ...), and the two tests ataws_cmd.rs:2495-2526codified this leak as expected behaviour. This PR redacts the value by default, exposes only structural metadata (name + length + SHA-256 prefix + JSON-key shape), and adds opt-in escape hatches plus a one-shot stderr warning so the behaviour change is visible.Reproduction
Root cause
src/cmds/cloud/aws_cmd.rs:1514-1541—filter_secrets_getformats the rawSecretStringinto the LLM-bound output viaformat!("Secret: {}", ...). The two tests at lines 2495-2526 had codified the leak as expected behaviour.Fix approach
Name+ aSecretString: <redacted; N bytes; sha256=XXXXXXXX>line + (for JSON-shaped secrets) a sortedkeys: [...]line listing top-level keys. Value is never printed.--reveal-secretflag: detected and stripped in thesecretsmanager get-secret-valuerouter branch (src/cmds/cloud/aws_cmd.rs) so the underlyingawsbinary never sees it. A process-localAtomicBool(REVEAL_SECRET_FLAG) signals the filter; it is cleared at end-of-invocation so subsequent in-process calls (tests, hooks) do not inherit it.RTK_REVEAL_SECRETS=1: independent env-based opt-in checked by the filter directly.std::sync::Onceguarantees the stderr line fires at most once per process even under parallel test execution. Tests are serialised via a privatereveal_env_lock()Mutex (same pattern astracking.rs::test_db_path_env_and_default).Behaviour changes
rtk aws secretsmanager get-secret-value <id>no longer contains the secret value.test_filter_secrets_get,test_filter_secrets_get_plain_text) are updated to assert the new behaviour.No new dependencies (project already uses
sha2). No public Rust API change. Nounwrap()in production code.Test plan
test_filter_secrets_get(modified — asserts redaction, nosecret123/admin, containssha256=)test_filter_secrets_get_plain_text(modified — noplain-text-password)test_filter_secrets_get_invalid_json(unchanged passthrough)test_filter_secrets_get_emits_json_keys(new — JSON shape exposed, values do not)test_filter_secrets_get_reveal_via_env(new —RTK_REVEAL_SECRETS=1restores legacy output; ENV_LOCK-style mutex)test_filter_secrets_get_reveal_via_flag(new —REVEAL_SECRET_FLAG(set by--reveal-secret) restores legacy output)test_filter_secrets_get_token_savings(new — multi-lineaws secretsmanager get-secret-value --output jsonfixture, ≥60% savings target)cargo fmt --allcleancargo clippy --all-targetszero warningscargo test --bin rtk -- --test-threads=8: 1905 passed / 0 failedRefs #1875 (Finding 1)