#How to have OPENAI_API_KEY used for embedding but not everything else?
1 messages · Page 1 of 1 (latest)
Yep, that can be expected.
If you set up OpenAI Code via “Codex CLI reuse”, OpenClaw treats ~/.codex/auth.json as the external source of truth. When it refreshes the subscription token, it writes the refreshed credential back there. So that behavior does not mean your subscription is being ignored.
Also, for your thread title question: Codex subscription auth does not cover embeddings. So this split is normal:
- chat/coding →
openai-codex/* - embeddings →
openai/*with a realOPENAI_API_KEY
If you want OpenClaw to stop touching ~/.codex/auth.json, switch from Codex CLI reuse to native OpenClaw Codex OAuth:
openclaw models auth login --provider openai-codex --set-default
That stores the credential in OpenClaw auth profiles instead of reusing Codex CLI storage.
Also worth checking for stale legacy overrides:
openclaw doctor
And please paste:
openclaw --version
openclaw models status
That’ll tell us which auth path you’re actually on.
Docs:
- https://docs.openclaw.ai/start/wizard-cli-reference
- https://docs.openclaw.ai/concepts/model-providers
If this fixed it, please right-click the solution message → Apps → ✅ Mark Solution so Answer Overflow can index it 🎉
I was only able to get it to stop doing this by removing the api key from the openclaw.json. But now it won't be able to do embeddings
Yep, that makes sense.
What you want is this split:
- chat/coding via
openai-codex/*using your Codex subscription - embeddings via a real OpenAI API key
The clean way is to pin the OpenAI key to memory search only, instead of using it as general OpenAI provider auth.
{
agents: {
defaults: {
model: { primary: "openai-codex/gpt-5.4" },
memorySearch: {
provider: "openai",
model: "text-embedding-3-small",
remote: {
apiKey: "sk-...",
},
},
},
},
}
Even better, keep the key in env and just pin the provider:
{
agents: {
defaults: {
model: { primary: "openai-codex/gpt-5.4" },
memorySearch: {
provider: "openai",
model: "text-embedding-3-small",
},
},
},
}
with OPENAI_API_KEY set on the gateway host.
Important bit: if you originally set up Codex using Codex CLI reuse, OpenClaw may still write refreshed Codex creds back to ~/.codex/auth.json. That part is separate from embeddings.
So if your goal is:
- keep embeddings working
- stop touching
~/.codex/auth.json
then do both:
openclaw models auth login --provider openai-codex --set-default
and pin memorySearch to OpenAI as above.
Docs:
- https://docs.openclaw.ai/reference/memory-config
- https://docs.openclaw.ai/help/faq
- https://docs.openclaw.ai/concepts/model-providers
If you want, paste your current openclaw.json redacted and I can point to the exact line to change.
~/.codex ❯ openclaw models status
🦞 OpenClaw 2026.4.12 (66f57a6) — I'm like tmux: confusing at first, then suddenly you can't live without me.
Config : ~/.openclaw/openclaw.json
Agent dir : ~/.openclaw/agents/main/agent
Default : openai-codex/gpt-5.4
Fallbacks (0) : -
Image model : -
Image fallbacks (0): -
Aliases (0) : -
Configured models (1): openai-codex/gpt-5.4
Auth overview
Auth store : ~/.openclaw/agents/main/agent/auth-profiles.json
Shell env : off
Providers w/ OAuth/tokens (2): anthropic (1), openai-codex (2)
- anthropic effective=profiles:~/.openclaw/agents/main/agent/auth-profiles.json | profiles=1 (oauth=0, token=1, api_key=0) | anthropic:manual=token:sk-ant-o...-WocOwAA
- google effective=models.json:AIzaSyB0...5t9cofug | models.json=AIzaSyB0...5t9cofug | source=models.json: ~/.openclaw/agents/main/agent/models.json
- lemonade effective=models.json:l...l | models.json=l...l | source=models.json: ~/.openclaw/agents/main/agent/models.json
- minimax effective=profiles:~/.openclaw/agents/main/agent/auth-profiles.json | profiles=1 (oauth=0, token=0, api_key=1) | minimax:global=sk-api-D...2gW_2V_E
- openai-codex effective=profiles:~/.openclaw/agents/main/agent/auth-profiles.json | profiles=2 (oauth=2, token=0, api_key=0) | openai-codex:default=OAuth, openai-codex:david@t.tech=OAuth (david@.tech)
- openrouter effective=env:sk-or-v1...df1cae3d | env=sk-or-v1...df1cae3d | source=env: OPENROUTER_API_KEY
- perplexity effective=env:sk-or-v1...df1cae3d | env=sk-or-v1...df1cae3d | source=env: OPENROUTER_API_KEY
OAuth/token status
- anthropic
- anthropic:manual static
- openai-codex usage: 5h 98% left ⏱48m · Week 80% left ⏱2d 20h
- openai-codex:david@t.tech) ok expires in 10d
- openai-codex:default ok expires in 10d
Ah, this output helps a lot.
You have two Codex OAuth profiles:
openai-codex:defaultopenai-codex:david@t.tech
When there are multiple profiles, OpenClaw can rotate between them unless you pin the auth order. I suspect openai-codex:default is the CLI-synced one, which is why you keep seeing writes to ~/.codex/auth.json.
So I’d do this:
openclaw models auth order set --provider openai-codex 'openai-codex:david@t.tech' openai-codex:default
That should make the explicit email profile win first.
For embeddings, since your output says Shell env: off, I would not rely on OPENAI_API_KEY from the shell. Put the key under memorySearch only:
{
agents: {
defaults: {
model: { primary: "openai-codex/gpt-5.4" },
memorySearch: {
provider: "openai",
model: "text-embedding-3-small",
remote: {
apiKey: "sk-...",
},
},
},
},
}
So, in short:
- pin
openai-codex:david@t.techfirst - use
memorySearch.remote.apiKeyfor embeddings - keep default model on
openai-codex/gpt-5.4
If you want, run this after setting the order:
openclaw models auth order get --provider openai-codex
Docs:
If this fixed it, please right-click the solution message → Apps → ✅ Mark Solution so Answer Overflow can index it 🎉
The problem isn't that it's writing oauth to codex/auth.json it was that it was writing the api key
Ah, got it, thanks, that’s a different problem.
In that case, I’m pretty sure this is not intended behavior. OpenClaw’s Codex refresh path should only update the OAuth token fields in ~/.codex/auth.json, not add an API key there. It preserves an existing OPENAI_API_KEY field if one is already present, but it should not be the thing inventing it.
So the safest workaround is:
- Do not put the embedding key in the general OpenAI auth slot
- Put it only under memory search config
{
agents: {
defaults: {
model: { primary: "openai-codex/gpt-5.4" },
memorySearch: {
provider: "openai",
model: "text-embedding-3-small",
remote: {
apiKey: "sk-...",
},
},
},
},
}
That keeps the OpenAI key scoped to embeddings, instead of making it look like normal openai/* provider auth.
Also, since your status shows Shell env: off, config is the right place here.
If it still re-adds OPENAI_API_KEY to ~/.codex/auth.json after switching to memorySearch.remote.apiKey, I’d call that a bug and ask you to file an issue with:
openclaw --version- your redacted
openclaw.json - whether
OPENAI_API_KEYwas already present in~/.codex/auth.jsonbefore the run
Issue tracker: https://github.com/openclaw/openclaw/issues
If you want, paste your redacted OpenClaw config and I can show the exact minimal change.
It doesn't put it in there anymore, but now I can't talk to the model
Okay, that means we probably fixed the embedding key leak, but now there’s a separate chat auth/routing issue.
Your earlier models status looked fine for Codex chat, so the next thing I need is the exact error text from the failed message.
Also please paste:
openclaw models auth order get --provider openai-codex
Why I’m asking:
- if the error says
No API key found for provider "openai", it’s hittingopenai/*instead ofopenai-codex/* - if it says
openai-codexwithinvalid_grant/ auth failure, then it’s the Codex profile/order - if it says something else, we can narrow it down fast
So, please send:
- the exact assistant error
- the output of
openclaw models auth order get --provider openai-codex
I think we’re close.
no, it was using codex app ■ unexpected status 401 Unauthorized: Missing bearer or basic authentication in header, url: https://api.openai.com/v1/responses,
Yep, that error is the clue.
It is not using the native Codex OAuth route there. It is hitting the direct OpenAI Responses API:
https://api.openai.com/v1/responses
That usually means you have a stale/legacy models.providers.openai-codex override in openclaw.json, for example api, baseUrl, or old transport config, and it’s shadowing the built-in Codex OAuth path.
What I’d check next:
- Run:
openclaw doctor
- Look in
openclaw.jsonfor a block like:
models: {
providers: {
"openai-codex": {
// api / baseUrl / transport-ish stuff
}
}
}
If you have that, remove that whole openai-codex provider override unless you intentionally need a custom proxy.
- Restart:
openclaw gateway restart
Keep the embedding key only under:
agents.defaults.memorySearch.remote.apiKey
and not under models.providers.openai-codex.
Docs:
If you paste just your models.providers.openai-codex block, I can tell you exactly what to delete.
I was using agents.defaults.embeddedHarness = { runtime: "codex", fallback: "pi" }
Ah, yep, that’s the missing piece.
You were mixing two different paths:
openai-codex/gpt-5.4= Codex OAuth through normal OpenClaw/PIcodex/gpt-5.4= Codex app-server harnessembeddedHarness.runtime: "codex"forces the Codex app-server path
So this combination is the problem:
agents.defaults.embeddedHarness = { runtime: "codex", fallback: "pi" }
If you want subscription auth and only an API key for embeddings, do not force the Codex harness.
Use this shape instead:
{
agents: {
defaults: {
model: { primary: "openai-codex/gpt-5.4" },
embeddedHarness: {
runtime: "auto",
fallback: "pi",
},
memorySearch: {
provider: "openai",
model: "text-embedding-3-small",
remote: {
apiKey: "sk-...",
},
},
},
},
}
Or just remove the embeddedHarness override entirely.
Short version:
- want Codex OAuth subscription →
openai-codex/*, no forcedruntime: "codex" - want Codex app-server harness →
codex/*
That 401 from https://api.openai.com/v1/responses is exactly what I’d expect from forcing the Codex app path without the auth it expects.
Docs:
Glad we found the real culprit 😅
If this fixed it, please right-click the solution message → Apps → ✅ Mark Solution so Answer Overflow can index it.
Why wouldn't the codex harness use oauth? And why would OC write the api key to auth.json?
Because those are two different auth lanes.
openai-codex/*uses OpenClaw’s Codex OAuth providercodex/*+embeddedHarness.runtime: "codex"hands execution to the external Codex app-server
The Codex harness does not use OpenClaw’s openai-codex auth profile machinery. It uses whatever auth the Codex app-server itself can see, usually OPENAI_API_KEY and/or Codex CLI state under ~/.codex/*.
So, if you want OpenClaw-managed Codex OAuth, use:
openai-codex/gpt-5.4- no forced
embeddedHarness.runtime: "codex"
On the second part, OpenClaw should not be inventing OPENAI_API_KEY inside ~/.codex/auth.json. The current Codex-file refresh path only updates the OAuth token fields and preserves any existing top-level fields. So if OPENAI_API_KEY showed up there, one of these is true:
- it was already there before
- the Codex app / Codex CLI wrote it
- you hit a bug
That’s why the clean split is:
- chat:
openai-codex/gpt-5.4 - embeddings:
agents.defaults.memorySearch.remote.apiKey - harness:
autoor just no override
Docs: https://docs.openclaw.ai/plugins/codex-harness
If you can reproduce OpenClaw adding OPENAI_API_KEY to ~/.codex/auth.json from scratch, that’s worth a GitHub issue: https://github.com/openclaw/openclaw/issues
- it wasn't
- possible, but it had to get it from somewhere and if true, OC gave it to it
- also possible
harness should be able to use oauth. the whole issue is that codex app was logged in with oauth and when OC would run all of a sudden it would change to api
I agree with you. It should keep using the Codex app’s OAuth if that’s how Codex is already logged in.
What seems to be happening is:
- the Codex harness is using the Codex app-server auth surface, not OpenClaw’s
openai-codexauth-profile path - once an OpenAI API key is available, the Codex side appears to prefer or switch to API-key mode
- and in your repro, that ends up contaminating
~/.codex/auth.json
So, bluntly, I think this is a bug or design gap, not you misconfiguring it.
Practical reality today:
- if you want stable Codex OAuth subscription auth, use
openai-codex/* - if you force
embeddedHarness.runtime: "codex", you are in the Codex app-server lane, and that auth behavior is clearly not isolated well enough here
So I’d treat this as issue-worthy with this repro:
- Codex app logged in via OAuth
- OpenClaw configured with
embeddedHarness.runtime: "codex" - OpenAI API key present for embeddings
- OpenClaw run causes Codex app to switch to API mode / writes API key into
~/.codex/auth.json
Please file it here: https://github.com/openclaw/openclaw/issues
Short-term workaround, sadly:
- need OAuth for chat →
openai-codex/gpt-5.4, no forced Codex harness - need Codex harness specifically → avoid exposing that process to an OpenAI API key until this is fixed
If you want, I can help you phrase the GitHub issue cleanly in one message.
yes
Yep. I’d file it like this:
Title
Codex harness switches Codex app from OAuth to API-key auth when OpenAI key is present for embeddings
Body
## Version
OpenClaw 2026.4.12
## What I expected
I expected to be able to:
- use the Codex app / Codex harness with my existing Codex OAuth login
- keep an OpenAI API key available only for embeddings
without OpenClaw changing Codex auth mode.
## What happened
When I configured OpenClaw to use the Codex harness and also had an OpenAI API key available for embeddings, the Codex app appeared to switch from OAuth auth to API-key auth.
I also observed `~/.codex/auth.json` being rewritten so that it contained the OpenAI API key, even though Codex had originally been logged in with OAuth.
After that, Codex harness requests started failing with auth behavior consistent with direct API usage instead of the expected OAuth-backed Codex app behavior.
## Repro
1. Log Codex app in with OAuth
2. Configure OpenClaw with:
```json5
agents: {
defaults: {
embeddedHarness: { runtime: "codex", fallback: "pi" }
}
}
- Also configure an OpenAI API key for embeddings
- Run OpenClaw through the Codex harness
- Observe that Codex auth behavior changes and
~/.codex/auth.jsongets updated with the API key
Notes
- If I avoid the Codex harness and use
openai-codex/*, OAuth works as expected