If you use OpenAI Codex on Windows, you may eventually run into an interesting problem: the Codex desktop application and Codex CLI can share configuration.
That is convenient when you want both to behave the same way. It becomes a problem when you want two completely different setups.
That was exactly my situation.
I wanted:
Codex GUI→ My normal ChatGPT Business account→ Normal OpenAI authentication→ GPT-6 AstraCodex CLI→ Separate API/token authentication→ Custom API provider→ GPT-6 Sol
Initially, trying to configure the CLI broke the GUI. The GUI started returning:
401 Unauthorized: Invalid tokenurl: https://vibi.top/v1/responses
After some troubleshooting, I found the cause and created a clean solution: give the GUI and CLI separate Codex home directories.
This article explains both the technical reason and the practical setup.
The Problem: GUI and CLI Were Sharing Configuration
On my Windows machine, the normal Codex configuration was stored under:
C:\Users\user\.codex
Inside it was:
config.toml
My configuration contained a custom model provider:
model_provider = "OpenAI"[model_providers.OpenAI]name = "OpenAI"base_url = "https://vibi.top/v1"wire_api = "responses"requires_openai_auth = true
The important line was:
base_url = "https://vibi.top/v1"
I had intended this configuration for my CLI API setup.
But the Codex desktop application was reading the same configuration.
So instead of the GUI using my normal ChatGPT account, its requests were being redirected to:
https://vibi.top/v1/responses
The server rejected the credential being presented, resulting in:
401 UnauthorizedInvalid token
The GUI wasn’t necessarily broken.
Its configuration was pointing it at the wrong backend.
The Solution: Separate CODEX_HOME
The key concept is simple.
Instead of making the GUI and CLI share:
C:\Users\user\.codex
I separated them:
Windows PC
│
┌───────┴───────┐
│ │
Codex GUI Codex CLI
│ │
▼ ▼
C:\Users\user C:\Users\user
\.codex \.codex-cli
│ │
▼ ▼
ChatGPT login API token
│ │
▼ ▼
OpenAI Custom provider
This is the most important idea in the entire setup.
The CLI doesn’t need to use the same Codex home directory as the desktop application.
Step 1: Back Up the Existing Codex Environment
Before changing anything, I backed up my existing .codex directory.
In Cmder/CMD:
mkdir "%USERPROFILE%\Documents\Codex-Safe-Backup"xcopy "%USERPROFILE%\.codex" "%USERPROFILE%\Documents\Codex-Safe-Backup\.codex" /E /H /I /Y
I also separately copied config.toml:
copy "%USERPROFILE%\.codex\config.toml" "%USERPROFILE%\Documents\Codex-Safe-Backup\config.toml"
This gave me:
C:\Users\user\Documents\Codex-Safe-Backup
Why bother?
Because .codex contained considerably more than one configuration file on my machine. It included authentication information, sessions, state databases, plugins, histories, worktrees and other Codex data.
If an experiment went wrong, I wanted the original state available.
Important: this is a local backup. It isn’t automatically a cloud backup unless that location is being synchronized by something such as OneDrive.
Step 2: Restore the GUI to the Normal OpenAI Provider
I wanted the desktop GUI to use my normal ChatGPT Business account.
Therefore, I removed the custom provider that redirected OpenAI traffic to the third-party endpoint.
Instead of this:
model_provider = "OpenAI"[model_providers.OpenAI]name = "OpenAI"base_url = "https://vibi.top/v1"wire_api = "responses"requires_openai_auth = true
I configured the normal provider:
model_provider = "openai"
Notice something subtle:
OpenAI ❌openai ✅
In my setup, using OpenAI after removing the custom provider produced:
failed to load configuration:Model provider `OpenAI` not found
Using the built-in provider identifier fixed that problem.
My GUI configuration then started with something similar to:
model_provider = "openai"model = "gpt-6-astra"review_model = "gpt-6-astra"model_reasoning_effort = "medium"
Step 3: Don’t Reconfigure the GUI for the CLI
At this point I had:
mkdir "%USERPROFILE%\.codex-cli"
working correctly.
I didn’t want to touch it again.
Instead, I created another directory exclusively for the CLI:
mkdir "%USERPROFILE%\.codex-cli"
Now there were two locations:
C:\Users\user\.codexC:\Users\user\.codex-cli
Think of these as two separate profiles.
.codex belongs to my normal desktop setup.
.codex-cli belongs to my token-based CLI setup.
Step 4: Tell the CLI to Use Its Own Home
In Cmder I ran:
set CODEX_HOME=%USERPROFILE%\.codex-cli
Then I checked it:
echo %CODEX_HOME%
The result was:
C:\Users\user\.codex-cli
This is the crucial step.
I wasn’t changing directories with cd.
I was telling Codex where its home/configuration directory should be for that terminal environment.
That’s an important distinction:
cd→ changes the working directory of the shellCODEX_HOME→ changes where Codex looks for its own configuration/state
Those are two different concepts.
Step 5: Create the CLI-Only Configuration
I opened:
notepad "%CODEX_HOME%\config.toml"
My token-based configuration looked like this:
model_provider = "vibi"model = "gpt-6-sol"model_reasoning_effort = "medium"network_access = "enabled"[model_providers.vibi]name = "Vibi"base_url = "https://vibi.top/v1"wire_api = "responses"env_key = "VNAI_KEY"
Now this configuration exists under:
C:\Users\user\.codex-cli\config.toml
instead of the GUI’s:
C:\Users\user\.codex\config.toml
That’s what prevents the configurations from fighting each other.
Step 6: Keep the Actual Token Outside config.toml
Another useful detail is this:
env_key = "VNAI_KEY"
That does not mean:
env_key = "sk-my-secret-token..."
env_key is the name of the environment variable containing the credential.
I therefore set the actual credential in Cmder:
set VNAI_KEY=YOUR_API_TOKEN
Codex then effectively does:
config.toml │ │ env_key = "VNAI_KEY" ▼Environment │ │ VNAI_KEY = actual secret ▼API authentication
This also means I don’t need to put the secret directly into config.toml.
And obviously, don’t publish your real API key in a blog post.
Use something like:
YOUR_API_TOKEN
in examples.
Step 7: Launch Codex CLI
With both environment variables configured:
set CODEX_HOME=%USERPROFILE%\.codex-cliset VNAI_KEY=YOUR_API_TOKEN
I launched:
codex
Codex started with the CLI-specific configuration.
I tested:
hi
and received a normal response.
At that point I had achieved the setup I wanted.
The Final Architecture
My machine now effectively works like this:
WINDOWS
│
┌───────────────┴────────────────┐
│ │
▼ ▼
CODEX DESKTOP CODEX CLI
│ │
│ │
▼ ▼
%USERPROFILE%\.codex %USERPROFILE%\.codex-cli
│ │
│ │
config.toml config.toml
│ │
▼ ▼
model_provider="openai" model_provider="vibi"
│ │
▼ ▼
ChatGPT Business Custom API
authentication token
│ │
▼ ▼
GPT-6 Astra GPT-6 Sol
The two applications can coexist because they no longer have to consume the same provider configuration.
The Mistake That Caused the Original Problem
My original setup effectively looked like this:
Shared .codex
│
custom base_url
│
vibi.top
/ \
/ \
GUI CLI
I wanted only the CLI to use the custom provider.
But because the provider configuration was in the shared Codex home, the desktop application picked it up too.
The result was:
GUI ↓Custom provider ↓Wrong/incompatible credential ↓401 Unauthorized
The solution wasn’t to keep changing tokens.
It was to separate configuration scopes.
Temporary vs Permanent Environment Variables
There is another important Windows detail.
When I use:
set CODEX_HOME=%USERPROFILE%\.codex-cli
inside CMD/Cmder, it applies to that environment/session.
Likewise:
set VNAI_KEY=YOUR_API_TOKEN
can be kept scoped to the terminal session.
That’s actually useful here.
I don’t necessarily want Windows globally telling every Codex process:
CODEX_HOME=.codex-cli
because then I risk pointing the GUI at the CLI configuration again.
For this setup, isolation is the whole point.
One Important Security Lesson
During troubleshooting it’s tempting to paste API keys everywhere just to get things working.
Don’t.
Use:
env_key = "VNAI_KEY"
and:
set VNAI_KEY=YOUR_API_TOKEN
instead of embedding the actual credential in configuration examples, screenshots, GitHub repositories, tutorials or blog posts.
If a real token is accidentally published, revoke/rotate it.
What I Learned
The biggest lesson wasn’t really about one API provider.
It was about configuration isolation.
GUI applications and command-line applications can look like completely separate programs while still consuming the same underlying configuration.
Once I understood that, the solution became straightforward:
Don't make two different authentication systemsfight over one configuration.Give each one its own configuration.
My final setup gives me the best of both worlds:
And if I want to experiment with the CLI later, I can modify:
C:\Users\user\.codex-cli
without touching the working desktop configuration in:
C:\Users\user\.codex
For anyone trying to run Codex Desktop and a differently authenticated Codex CLI on the same Windows machine, that separation is the key idea.
Summary
I successfully configured two independent OpenAI Codex setups on the same Windows PC without them interfering with each other:
Codex GUI/Desktop uses my normal ChatGPT Business account, while Codex CLI runs separately using a token/API-based provider.
The key was configuration isolation:
Codex GUI→ C:\Users\user\.codex→ ChatGPT Business authenticationCodex CLI→ C:\Users\user\.codex-cli→ Separate CODEX_HOME→ API/token authentication
This prevents custom CLI API settings, tokens, base URLs, and models from changing or breaking the Codex desktop application.
If you’re trying to set up Codex GUI + token-based Codex CLI on the same computer and need help configuring it, you can contact me on WhatsApp:
💬 Chat with me on WhatsAppI can help you understand the setup and configure the two environments separately.