garrytan / garrytan/gstack

`/codex` and `/autoplan` shell out to `codex` with no auth-profile gate or consent prompt

Open
#965 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
133k
Forks
19.9k
Avg merge
18h 46m
Merged PRs (30d)
26

Description

## Problem

The `/codex` skill and `/autoplan` (plan-review phases) shell out to the `codex` CLI with no check for **which account is currently authenticated** in `~/.codex/`. Whatever `codex login` was last run with is what gets used — silently, with no prompt.

Two things compound:

1. **`codex/SKILL.md.tmpl:40-47`** — the only pre-flight is `which codex`. No auth inspection, no per-project config, no `CODEX_HOME` awareness.
2. **`autoplan/SKILL.md.tmpl:70`** — "run codex" is classified as a **mechanical** decision ("one clearly right answer, auto-decide silently"). So during `/autoplan`, `codex exec` fires across multiple plan-review phases with zero user consent.

And the gap is wider than just `/codex` and `/autoplan`. Other skills chain into codex — `/ship` may suggest a codex review, `/plan-eng-review` may reach for it, and nothing stops a future skill from doing the same. "Don't run `/codex`" is not a mitigation a user can reasonably apply, because they'd have to know the full call graph of every gstack skill and intercept every chained prompt. The gate has to live at the invocation layer, not the skill-entry layer, so that every codex call is covered regardless of which skill triggered it.

The net effect: if a user has more than one codex account (common — personal vs. employer-provided, separate orgs, compliance-isolated environments), gstack will happily use whichever one happens to be in `~/.codex/` against any repo, with no way for the user to approve or even know ahead of time.

## Repro

1. `codex login` as account A.
2. `cd` into any repo — including ones where account A's credentials are the *wrong* choice.
3. Run `/autoplan` (or `/codex review`, or any skill that may chain into codex).
4. `codex exec` runs against account A. No prompt, no confirmation, no record of approval. The first the user knows is when they see the output (or a bill).

## Expected

Before the first codex invocation in a project, gstack should prompt the user for which codex auth to use, remember the answer per-project, and route subsequent invocations through `CODEX_HOME` accordingly. `/autoplan` should not treat codex as a silent auto-yes decision. Any skill that chains into codex should surface *which account* the call will use at the point of prompt, so "yes" is informed consent rather than reflex.

## Actual

- `codex/SKILL.md.tmpl:40-47` — binary-presence check only.
- `autoplan/SKILL.md.tmpl:70` — codex classified as mechanical auto-yes.
- No per-project config, no `CODEX_HOME` plumbing anywhere in the codex-calling skills.
- Chained-invocation prompts in other skills (e.g. `/ship`'s "get a codex review?") don't disclose which account will be used.

## Suggested fix (minimal)

The `codex` CLI already supports `CODEX_HOME` as an env var pointing at an alternate auth/config directory. This makes isolation trivial — users who maintain separate codex homes (e.g., `~/.codex-personal/`, `~/.codex-work/`) can have gstack pick the right one per project.

Concretely:

1. **Per-project config file:** `~/.gstack/projects/{slug}/codex.yaml` with one field — `codex_home: `.
2. **Invocation-layer gate (not skill-entry layer):** wherever gstack shells out to `codex`, read the per-project config first. If missing, `AskUserQuestion` listing the `~/.codex*` directories found on the machine (glob), plus "Cancel." Save the chosen path. The prompt *is* the setup flow — no separate `/setup-codex` skill needed. Because the gate is at the invocation layer, every codex call is protected regardless of which skill triggered it.
3. **Before every `codex` invocation** (in `/codex`, `/autoplan` phases 1–4, and anywhere else), export `CODEX_HOME=`.
4. **Transparency at the chained prompt:** any prompt that *may* trigger a codex call (e.g. `/ship`'s "get a codex review?", `/autoplan`'s CEO-review step if re-introduced as opt-in) should name the account that will be used — e.g. *"Run codex using the account approved for this project (``)?"* — so the user's "yes" is informed.
5. **In `autoplan/SKILL.md.tmpl:70`:** remove "run codex (always yes)" from the mechanical examples. Codex invocation should go through the same per-project gate as `/codex` itself, never auto-yes.
6. **Escape hatch for the eval harness:** `GSTACK_CODEX_SKIP_GATE=1` env var to bypass the gate when `test/skill-e2e-*.test.ts` drives codex directly. Test runner sets it; skill prose documents it.

Scope: ~20 lines of template changes, one config file, no new helper binary, no fingerprinting, no global flag. The same pattern likely applies to any other authenticated AI CLI gstack shells out to — worth a follow-up audit.

## Why this matters

Consent and credential isolation are separate issues, and gstack currently has neither for codex:
- **Consent:** a user should know when their codex account is about to be billed and see what prompt is being sent.
- **Isolation:** users with multiple codex accounts need a way to tell gstack which one is approved for which project.
- **Informed "yes":** even when a user does approve codex at a prompt, "yes" should mean yes to a *specific* account, not whichever one happens to be in `~/.codex/` at that moment.

All three are table-stakes for a tool that runs inside user repos and spends money on their behalf.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.