[security] fix(personalization): stop replaying exported env var values#151
Merged
tjb-tech merged 1 commit intoHKUDS:mainfrom Apr 17, 2026
Merged
Conversation
Personalization currently captures full `export NAME=value` payloads and re-injects them through local rules into future system prompts. Narrow the environment-variable extraction to the variable name so the feature can still remember environment hints without persisting secret material. Constraint: Keep personalization's environment-hint workflow intact Rejected: Remove env_var extraction entirely | larger behavior change than needed for a first fix Confidence: high Scope-risk: narrow Reversibility: clean Directive: Do not persist raw env var values without a separate sensitivity model and tests Tested: PYTHONPATH=src pytest -q tests/test_personalization/test_extractor.py tests/test_prompts/test_claudemd.py Tested: PYTHONPATH=src ruff check src tests Not-tested: Full pytest suite in this environment (collection fails because optional pyperclip dependency is missing) Related: HKUDS#149
27b1f49 to
334101e
Compare
arik08
pushed a commit
to arik08/MyHarness
that referenced
this pull request
Apr 26, 2026
Personalization currently captures full `export NAME=value` payloads and re-injects them through local rules into future system prompts. Narrow the environment-variable extraction to the variable name so the feature can still remember environment hints without persisting secret material. Constraint: Keep personalization's environment-hint workflow intact Rejected: Remove env_var extraction entirely | larger behavior change than needed for a first fix Confidence: high Scope-risk: narrow Reversibility: clean Directive: Do not persist raw env var values without a separate sensitivity model and tests Tested: PYTHONPATH=src pytest -q tests/test_personalization/test_extractor.py tests/test_prompts/test_claudemd.py Tested: PYTHONPATH=src ruff check src tests Not-tested: Full pytest suite in this environment (collection fails because optional pyperclip dependency is missing) Related: HKUDS#149
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.
Closes #149.
Summary
This PR narrows personalization env-var extraction so exported environment variables are stored by name only, not by raw
NAME=valuepayload.Concretely:
export OPENAI_API_KEY=...is now remembered asOPENAI_API_KEYlocal_rulesWhy
PR #65 introduced personalization so OpenHarness can remember local environment context such as hosts, paths, and endpoints. That feature direction makes sense.
The problem is that the current implementation also captures full exported values. For secrets, that creates a different class of behavior:
facts.jsonrules.mdbuild_runtime_system_prompt(...)outputSo a one-off shell snippet like
export OPENAI_API_KEY=...can become a persistent prompt-side secret disclosure path.Root cause
src/openharness/personalization/extractor.pycurrently captures the fullNAME=valuepayload forexport ...patterns.That makes sense for general parsing, but it is too broad for a personalization feature whose output is persisted and later injected into prompts.
Change
Before / After
Before
export OPENAI_API_KEY=sk-test-secret-> personalization storesOPENAI_API_KEY=sk-test-secretsk-test-secretvia local rules in the system promptAfter
export OPENAI_API_KEY=sk-test-secret-> personalization storesOPENAI_API_KEYValidation
PYTHONPATH=src pytest -q tests/test_personalization/test_extractor.py tests/test_prompts/test_claudemd.pyPYTHONPATH=src ruff check src testsNotes
pytest -qon this local environment is currently blocked by unrelated collection errors caused by a missing optionalpyperclipdependency; I did not change any of the affected command/UI code paths.