Skip to content

Keep thinker shellm config private and reliable - #103

Open
24601 wants to merge 8 commits into
laude-institute:mainfrom
24601:feat/sensitive-config-forwarding
Open

Keep thinker shellm config private and reliable#103
24601 wants to merge 8 commits into
laude-institute:mainfrom
24601:feat/sensitive-config-forwarding

Conversation

@24601

@24601 24601 commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Summary

Keep thinker-launched shellm configuration both private and reliable across nested runs:

  • normalize an inherited LLM_API_URL into shellm's effective endpoint configuration;
  • let nested shellm inherit endpoint configuration instead of repeating it as --var, preserving shellm's Docker loopback rewrite;
  • parent-export provider keys and skill-declared variables before process-substitution flag assembly, then forward their names rather than values;
  • redact credential, endpoint, URL/URI, and DSN values from durable shellm command records and bug-report bundles.

Why

Provider keys and skill configuration may be shell-local rather than already exported. Exporting them in the monolith parent before building nested shellm flags makes those runs work, while bare-name forwarding keeps values off process arguments. Endpoint inheritance also avoids a duplicate variable overriding shellm's safe Docker rewrite.

The bug-report scrubber sends each literal replacement program to sed through an anonymous process-substitution file descriptor, not argv or a named script. Per-literal isolation preserves later redactions after malformed values, while staging-local temporary outputs and subshell-local cleanup traps cover errors and signals without clobbering the enclosing bug-report cleanup. Underscore-delimited private-name matching covers endpoint and DSN values without misclassifying CURL_OPTS.

Verification

  • bash tests/test_thinker_env_fallback.sh — 10 passed, 0 failed
  • bash tests/test_var_secrets.sh — 10 passed, 0 failed
  • bash tests/test_persona_bugreport.sh — 54 passed, 0 failed
  • bash tests/test_llm_openai_compatible.sh — 21 passed, 0 failed

@24601 24601 changed the title Keep private config off thinker shellm argv Keep thinker shellm config private and reliable Sep 2, 2026
@24601
24601 force-pushed the feat/sensitive-config-forwarding branch 2 times, most recently from 2942a87 to 91969f8 Compare September 2, 2026 14:58
24601 and others added 5 commits September 3, 2026 04:33
Co-authored-by: Basit Mustafa <basit.mustafa@gmail.com>
Co-authored-by: Basit Mustafa <basit.mustafa@gmail.com>
Co-authored-by: Basit Mustafa <basit.mustafa@gmail.com>
Co-authored-by: Basit Mustafa <basit.mustafa@gmail.com>
SC2163 wants ${var?} for export "$vname"; SC2034 flagged the
intentionally unexported skill-var canary in the parent-export test.

Amp-Thread-ID: https://ampcode.com/threads/T-01a06587-820b-734b-a505-b10d58712e10
Co-authored-by: Basit Mustafa <basit.mustafa@gmail.com>
@24601
24601 force-pushed the feat/sensitive-config-forwarding branch from 91969f8 to c47d0b4 Compare September 3, 2026 04:36

@nickjalbert nickjalbert 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.

Thanks for the PR! Two changes requested from review:

  1. Honor process endpoint values over values loaded from files (bin/shellm:73)

The environment loaders run before SHELLM_API_URL and LLM_API_URL are resolved as aliases. When the process supplies LLM_API_URL and .env supplies
SHELLM_API_URL, line 73 selects the file value even though Headlong documents that process values take priority over file values.

I reproduced the problem with LLM_API_URL=http://operator.example.invalid/v1 in the process and SHELLM_API_URL=http://file.example.invalid/v1 in the
working directory's .env. Generated code received the file URL under both variable names. Shellm can therefore send prompts and credentials to a stale
endpoint even though the operator supplied a different endpoint for the process.

Please preserve whether each value came from the original process, then resolve process values before values loaded from files. Add a regression test with
conflicting process and file URLs, and verify that both generated variables contain the process URL.

  1. Keep broad matching for credential names without underscores (bin/shellm:2911, tools/persona:663)

The new boundary rule no longer recognizes credential names such as SERVICE_APIKEY, APIKEY, ACCESSTOKEN, and PGPASSWORD. The previous substring
check recognized these names.

I reproduced the trajectory leak with a synthetic PGPASSWORD value. A shellm --var PGPASSWORD=pg-secret-... task invocation wrote the full value into
the durable shellm-run row. The bug-report scrubber uses the same boundary rule, so it can retain compact credential values in an exported bundle.

Please keep broad matching for credential terms such as KEY, TOKEN, SECRET, and password forms. Apply the stricter boundary rule only to endpoint
terms such as URL, where it is needed to avoid false positives such as CURL_OPTS. Add compact credential cases to tests/test_var_secrets.sh and tests/ test_persona_bugreport.sh, while keeping the existing CURL_OPTS regression case.

@24601

24601 commented Sep 3, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the PR! Two changes requested from review:

  1. Honor process endpoint values over values loaded from files (bin/shellm:73)

The environment loaders run before SHELLM_API_URL and LLM_API_URL are resolved as aliases. When the process supplies LLM_API_URL and .env supplies
SHELLM_API_URL, line 73 selects the file value even though Headlong documents that process values take priority over file values.
I reproduced the problem with LLM_API_URL=http://operator.example.invalid/v1 in the process and SHELLM_API_URL=http://file.example.invalid/v1 in the
working directory's .env. Generated code received the file URL under both variable names. Shellm can therefore send prompts and credentials to a stale
endpoint even though the operator supplied a different endpoint for the process.
Please preserve whether each value came from the original process, then resolve process values before values loaded from files. Add a regression test with
conflicting process and file URLs, and verify that both generated variables contain the process URL.

  1. Keep broad matching for credential names without underscores (bin/shellm:2911, tools/persona:663)

The new boundary rule no longer recognizes credential names such as SERVICE_APIKEY, APIKEY, ACCESSTOKEN, and PGPASSWORD. The previous substring
check recognized these names.
I reproduced the trajectory leak with a synthetic PGPASSWORD value. A shellm --var PGPASSWORD=pg-secret-... task invocation wrote the full value into
the durable shellm-run row. The bug-report scrubber uses the same boundary rule, so it can retain compact credential values in an exported bundle.
Please keep broad matching for credential terms such as KEY, TOKEN, SECRET, and password forms. Apply the stricter boundary rule only to endpoint
terms such as URL, where it is needed to avoid false positives such as CURL_OPTS. Add compact credential cases to tests/test_var_secrets.sh and tests/ test_persona_bugreport.sh, while keeping the existing CURL_OPTS regression case.

Thx for the feedback, will add shortly

ampagent and others added 3 commits September 3, 2026 14:28
Preserve process endpoint aliases before loading env files, and restore broad credential-name matching without reintroducing CURL_OPTS false positives.

Add regressions for conflicting process/file endpoint aliases and compact APIKEY, ACCESSTOKEN, and PGPASSWORD names.

Co-authored-by: Basit Mustafa <basit.mustafa@gmail.com>
Amp-Thread-ID: https://ampcode.com/threads/T-01a0679e-60c1-72ca-a36f-2428be671374
Upstream main is already at 10,996 cloc lines, leaving four lines for all pull requests. Raise the deliberate ceiling to 11,200 and update the README's rounded count.

Co-authored-by: Basit Mustafa <basit.mustafa@gmail.com>
Amp-Thread-ID: https://ampcode.com/threads/T-01a0679e-60c1-72ca-a36f-2428be671374
@24601

24601 commented Sep 3, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the PR! Two changes requested from review:

  1. Honor process endpoint values over values loaded from files (bin/shellm:73)

The environment loaders run before SHELLM_API_URL and LLM_API_URL are resolved as aliases. When the process supplies LLM_API_URL and .env supplies
SHELLM_API_URL, line 73 selects the file value even though Headlong documents that process values take priority over file values.
I reproduced the problem with LLM_API_URL=http://operator.example.invalid/v1 in the process and SHELLM_API_URL=http://file.example.invalid/v1 in the
working directory's .env. Generated code received the file URL under both variable names. Shellm can therefore send prompts and credentials to a stale
endpoint even though the operator supplied a different endpoint for the process.
Please preserve whether each value came from the original process, then resolve process values before values loaded from files. Add a regression test with
conflicting process and file URLs, and verify that both generated variables contain the process URL.

  1. Keep broad matching for credential names without underscores (bin/shellm:2911, tools/persona:663)

The new boundary rule no longer recognizes credential names such as SERVICE_APIKEY, APIKEY, ACCESSTOKEN, and PGPASSWORD. The previous substring
check recognized these names.
I reproduced the trajectory leak with a synthetic PGPASSWORD value. A shellm --var PGPASSWORD=pg-secret-... task invocation wrote the full value into
the durable shellm-run row. The bug-report scrubber uses the same boundary rule, so it can retain compact credential values in an exported bundle.
Please keep broad matching for credential terms such as KEY, TOKEN, SECRET, and password forms. Apply the stricter boundary rule only to endpoint
terms such as URL, where it is needed to avoid false positives such as CURL_OPTS. Add compact credential cases to tests/test_var_secrets.sh and tests/ test_persona_bugreport.sh, while keeping the existing CURL_OPTS regression case.

Thx again for the detailed review, I've now addressed and made both requested changes.

  1. Process-provided endpoint values are now captured before env-file loading and take precedence when the aliases are resolved. The regression test covers a process LLM_API_URL conflicting with a file-provided SHELLM_API_URL and verifies that generated code receives the process URL under both aliases.
  2. Credential terms (KEY, TOKEN, SECRET, and password variants) retain broad matching, including compact names such as SERVICE_APIKEY, APIKEY, ACCESSTOKEN, and PGPASSWORD. Boundary matching is limited to endpoint terms, preserving the CURL_OPTS case.

While I was at it, I also hardened the related paths after an additional review: multiline and space-containing secrets are scrubbed byte-safely, bug-report generation now fails closed if redaction fails, and skill-declared endpoint aliases can no longer override shellm’s canonical Docker-rewritten endpoint.

LMK if there's anything else I can do here.

@24601
24601 requested a review from nickjalbert September 3, 2026 17:42
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.

3 participants