Skip to content

Fix: redact shell-snapshot credential leak on relay auth path - #196

Closed
SaraAbidHussain wants to merge 1 commit into
sapientinc:mainfrom
SaraAbidHussain:fix/redact-shell-snapshot-key
Closed

SaraAbidHussain wants to merge 1 commit into
sapientinc:mainfrom
SaraAbidHussain:fix/redact-shell-snapshot-key

Conversation

@SaraAbidHussain

Copy link
Copy Markdown
Contributor

Summary

Fixes #84. features.shell_snapshot=false was only applied on the
ChatGPT subscription auth path (_SUBSCRIPTION_RUNTIME_OVERRIDES,
gated behind if subscription: in
praxist/plugins/agent_runtimes/codex_sdk/adapter.py). The relay/
API-key path (needs_relay(provider)) never picked it up, so
Codex's shell-snapshot capture stayed on while the raw provider key
sat in that path's process env (_client_process_env) — leaking it
into runtime_state/.../shell_snapshots/*.sh.

The smallest fix is to split features.shell_snapshot=false into a
new _ALWAYS_ON_SAFETY_OVERRIDES tuple applied unconditionally,
rather than extending the whole subscription-only bundle (which
also sets mcp_servers={} — that would break MCP tools on the
relay path, since they're actively used there via
mcp_configuration).

Scope

  • Affected modules or public contracts: praxist/plugins/agent_runtimes/codex_sdk/adapter.py only — no public contract changes.
  • Compatibility considerations: none; this only restricts an internal Codex config flag that was already used for the subscription path.
  • Task-agnostic rationale: shell-snapshot capture is a Codex SDK feature unrelated to task-specific behavior, so disabling it everywhere is safe.

Verification

  • uv run python -m unittest discover -s tests -q — 3081 tests, 2 pre-existing unrelated failures (test_signal_set_records_permission_errors_and_process_lookup, test_all_praxist_modules_reload_under_coverage), no new failures.
  • uv run python scripts/run_test_coverage.py unit --fail-under 90 --fail-under-statements 95 — 92.29% total / 94.03% statement. The statement threshold isn't met, but only because tests/product_usage/* fails to collect due to missing optional deps (fastapi, sqlalchemy) not installed by the default dev sync — a pre-existing environment gap unrelated to this change.
  • uv run python scripts/run_test_coverage.py integration — ran clean.
  • uv run python -m compileall -q praxist tests templates examples scripts — clean.
  • uv run python scripts/build_docs_site.py — clean.
  • git diff --check — clean.
  • Extended test_deepseek_uses_private_relay_configuration_and_closes_both to assert features.shell_snapshot=false is present for the relay path. Verified the test catches the regression: reverted the fix locally, confirmed the test failed with AssertionError: 'features.shell_snapshot=false' not found in (...), then reapplied the fix and confirmed it passes.

Checklist

  • The change is focused and does not include unrelated generated files.
  • Tests cover the affected behavior.
  • Documentation, templates, examples, and skills were updated where needed. (not applicable — internal config flag, no user-facing docs)
  • No credentials, private task data, or research-run artifacts are included.
  • New dependencies and copied assets include their source and license terms. (no new dependencies)
  • I have read .github/CONTRIBUTING.md and the contribution terms in LICENSE.md.

This addresses the root cause only. The run-completion scrub pass suggested in the issue is a reasonable defense-in-depth addition, happy to follow up with that as a separate PR if useful.

features.shell_snapshot=false was only applied for the ChatGPT
subscription auth path. The relay/API-key path never got this
override, so Codex's shell-snapshot capture stayed enabled while
the raw provider key sat in the process env — leaking it into
run_dir/.../shell_snapshots/*.sh.

Fixes sapientinc#84
@Glen-SP

Glen-SP commented Sep 17, 2026

Copy link
Copy Markdown
Collaborator

Thank you, @SaraAbidHussain, for this fix and the clear root-cause analysis.

We have reproduced the leak and confirmed your diagnosis.
We have transferred your commit into the maintainer validation branch
validation/credential-redaction,
with your authorship retained.

Our maintenance process is described here:
https://github.com/sapientinc/PRAXIST?tab=contributing-ov-file#what-happens-after-submission

The branch now goes to the maintainers' real-task validation stage, required here
because this touches credentials and runtime invocation.

We are closing this source PR only because the change has moved into validation; this is not a rejection.
Issue #84 stays open for updates, and this discussion and attribution remain available.

@Glen-SP

Glen-SP commented Sep 23, 2026

Copy link
Copy Markdown
Collaborator

Update: this shipped. Your change is on main in 5b50658, merged via #203, with
co-author credit.

One finding from validation: openai-codex 0.147.0 ignores
features.shell_snapshot=false, so snapshots were still written with the key.
The merge adds a second change that gives the Codex child a placeholder instead
of the key on relay routes; your override is kept as defence in depth.

Thank you for your contribution, @SaraAbidHussain

@SaraAbidHussain

Copy link
Copy Markdown
Contributor Author

Thanks for the update, @Glen-SP. Glad to know it’s merged! I really appreciate the validation and the extra check around the codex 0.147.0 behavior. Good catch, and thanks again for the contribution credit!

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.

[Bug]: Peer runtime shell snapshots capture the provider API key into run artifacts

2 participants