After the Phase A sandbox (#8), the only secret a review subprocess can reach is its own provider key: the CLI needs that key to call the model, so it sits in the subprocess's own environment and cat /proc/self/environ (or the codex auth file) recovers it. A prompt-injected reviewer that complies could emit its own key into the verdict, which is posted publicly.
What already contains this:
- minimal per-provider env: a reviewer never sees the other provider's key, the App token, or
GH_TOKEN (only its own key).
- no key on disk during review (keys are unlinked after the runner reads them); codex auth lives in an unguessable per-run
CODEX_HOME.
- adversarial test showed claude refuses such injection and nothing leaked.
So the blast radius is one provider key, only if the model complies with injection to print its own credential, and only that one key. Not closed, though.
Real fixes (onerous, deferred):
- run each reviewer as a separate unprivileged OS user (so it can't read its own process env via a helper), or
- a local auth proxy: give the CLI a dummy token + a localhost base-url; the real key lives in a process the reviewer's uid can't read.
Low priority given the containment above; tracking so it isn't forgotten.
After the Phase A sandbox (#8), the only secret a review subprocess can reach is its own provider key: the CLI needs that key to call the model, so it sits in the subprocess's own environment and
cat /proc/self/environ(or the codex auth file) recovers it. A prompt-injected reviewer that complies could emit its own key into the verdict, which is posted publicly.What already contains this:
GH_TOKEN(only its own key).CODEX_HOME.So the blast radius is one provider key, only if the model complies with injection to print its own credential, and only that one key. Not closed, though.
Real fixes (onerous, deferred):
Low priority given the containment above; tracking so it isn't forgotten.