Skip to content

Add Repo.credential_dir for shared codex ChatGPT Plus/Pro auth - #397

Merged
tildesrc merged 1 commit into
mainfrom
panopticon/codex-credential-dir
Aug 24, 2026
Merged

Add Repo.credential_dir for shared codex ChatGPT Plus/Pro auth#397
tildesrc merged 1 commit into
mainfrom
panopticon/codex-credential-dir

Conversation

@tildesrc

Copy link
Copy Markdown
Contributor

Summary

  • Adds Repo.credential_dir — a name (relative to the secrets dir) pointing at a host directory the runner mounts read-write into every container at /panopticon/credentials
  • The codex adapter (container/cli/codex.py) symlinks auth.json from the mounted dir into $CODEX_HOME on start, keeping rotating ChatGPT Plus/Pro refresh tokens in sync across concurrent tasks
  • Sets cli_auth_credentials_store = "file" in config.toml so codex uses file-based storage instead of the OS keyring (which isn't present in containers)
  • Adds CredentialDirField widget to the dashboard repo form, validation in the task service (_validate_credential_dir), and volume mount logic in the local runner
  • Alembic migration adds nullable credential_dir column to the repo table
  • docs/auth.md now documents all three codex credential tiers (API key, access token, Plus/Pro subscription) and explains why symlinks work for codex (in-place truncate-write via FileAuthStorage::save) but not Claude (atomic rename — ADR 0012)
  • 16 new tests: service validation, runner volume mounting, wire_credentials, auth_missing_detail (credential-dir path), config cli_auth_credentials_store

🤖 Generated with Claude Code

Comment thread docs/auth.md Outdated
Comment on lines +144 to +145
with a container-local regular file — documented in ADR 0012 as the failure mode that drove the
switch to the non-rotating `CLAUDE_CODE_OAUTH_TOKEN`.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
with a container-local regular file — documented in ADR 0012 as the failure mode that drove the
switch to the non-rotating `CLAUDE_CODE_OAUTH_TOKEN`.
with a container-local regular file.

Introduces `Repo.credential_dir` — a name relative to the secrets dir
that the runner mounts read-write into every container for that repo at
`/panopticon/credentials`. The codex adapter symlinks `auth.json` from
there into `$CODEX_HOME` on container start, keeping rotating ChatGPT
Plus/Pro tokens in sync across concurrent tasks on the same host.

- `core/models.py`: `Repo.credential_dir` field
- `core/dirs.py`: `credential_dir_path()` + `relativize_credential_dir()`
- `taskservice/store_sqlalchemy.py`: new `credential_dir` column
- `taskservice/service.py`: `_validate_credential_dir()` in create/update
- `sessionservice/local_runner.py`: mount `--volume …:/panopticon/credentials:rw`
- `sessionservice/spawner.py`: pass `credential_dir` to runner
- `container/cli/codex.py`: `wire_credentials()` (symlink / API-key JSON),
  `cli_auth_credentials_store = "file"` in config, updated `auth_missing_detail`
- `client.py`, `terminal/dashboard.py`: plumb `credential_dir` through the API
  client and the repo form (CredentialDirField widget)
- `migrations/`: Alembic migration adding nullable `credential_dir` column
- `docs/auth.md`: full Codex auth section explaining all three tiers and
  why symlinks work for codex (in-place truncate-write) but not Claude
  (atomic rename — see ADR 0012)
- New tests: service validation, runner volume mounting, wire_credentials
  (symlink, API-key JSON, dangling symlink guard, no-op), auth_missing_detail
  (credential-dir path), config.toml `cli_auth_credentials_store`

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@tildesrc
tildesrc force-pushed the panopticon/codex-credential-dir branch from a6612c6 to e7bd29c Compare August 24, 2026 16:52
@tildesrc
tildesrc merged commit a91661e into main Aug 24, 2026
3 checks passed
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.

1 participant