Skip to content

OpenCode breaks after PAT rotation — stale token in content-filter proxy #106

Closed

Description

@dgokeeffe

Problem

OpenCode stops working in CODA after PAT rotation. All API calls fail with 401 Unauthorized.

Root Cause

Three layers of process isolation conspire to keep stale tokens alive:

  1. PTY environment is frozen at spawn time — When a terminal session is created, subprocess.Popen(env=os.environ.copy()) snapshots the parent's environment. The parent process updates os.environ["DATABRICKS_TOKEN"] on rotation, but the child bash process (and anything launched from it) never sees the update.

  2. OpenCode caches credentials at startup — OpenCode reads ~/.local/share/opencode/auth.json once when launched and holds the token in memory for the lifetime of the TUI process. Even though cli_auth._update_opencode() writes the new token to disk every rotation, OpenCode never re-reads it.

  3. Content-filter proxy forwards stale auth headers — The proxy at localhost:4000 (which all OpenCode traffic passes through) copies the Authorization header from OpenCode and forwards it verbatim to Databricks. Since OpenCode sends the stale token, the proxy sends the stale token.

When PAT rotation runs (pat_rotator._rotate_once()), it:

  • Mints a new 4-hour token
  • Revokes the old token via /api/2.0/token/delete
  • Updates os.environ, ~/.databrickscfg, and all CLI auth files on disk

The revocation is what makes this fatal — the old token doesn't just expire naturally, it's immediately invalidated. OpenCode's next API call hits a 401.

Affected Components

Component Token Source Updated on Rotation? Re-reads at Runtime?
Databricks CLI ~/.databrickscfg Yes (file) Yes (per invocation)
Claude Code ~/.claude/settings.json Yes (file) Likely yes
OpenCode auth.json + env var Yes (file), No (env) No — cached at startup
Content-filter proxy Forwarded header N/A N/A — pass-through

Fix

PR #105 — Make the content-filter proxy read the current token from ~/.databrickscfg (which the PAT rotator always keeps current) and override the Authorization header before forwarding to Databricks. 30-second file read cache to avoid per-request I/O.

This is the right layer to fix it because:

  • The proxy already intercepts all OpenCode → Databricks traffic
  • No changes needed to OpenCode itself
  • Works for any future CLI tool routed through the proxy
  • .databrickscfg is the canonical token source, always updated by the rotator

Activity

  1. datasciencemonkey commented on Apr 9, 2026

    @datasciencemonkey
    Owner

    Fixed in v0.16.7 via two changes:

    1. PR fix: inject fresh proxy token + strip DATABRICKS_HOST from shell env #107 — content-filter proxy now reads fresh tokens from ~/.databrickscfg (30s cache) instead of using the stale env snapshot. This covers OpenCode and all AI requests routed through the proxy.
    2. PR chore: update default codex model to databricks-gpt-5-3-codex #108 — shell sessions strip DATABRICKS_HOST from env so the Databricks SDK falls through to ~/.databrickscfg (which has both host and fresh token). This fixes databricks current-user me and all CLI auth.

    All three root causes from the issue are addressed:

    • PTY frozen env → stripped so CLI reads config file
    • Proxy stale token → _get_fresh_token() with configparser
    • CLI auth.json → cli_auth.update_cli_tokens() already handled by PAT rotator
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

No labels
No labels

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions