One of the easiest mistakes to make when learning Codex CLI is thinking that Codex can use every secret your project knows about.
It cannot.
Codex is just a process running inside a shell session.
That sounds simple, but it explains a lot of confusing failures.
In a recent session, the setup looked fine at first glance. There was a secrets file on disk. The project had a known place where environment values lived. The workflow expected an auth token called `ENV_TOKEN`.
So the first instinct was natural: the secret file exists, so auth should be available.
But then we checked the actual runtime:
`python3 -c "import os; print(bool(os.getenv('ENV_TOKEN')))"`
It printed `False`.
That was the real answer.
The file existed. The current process did not have the variable.
If you are new to Codex, this distinction matters because Codex does not magically read every `.env`, `.envrc`, profile script, or secrets folder on your machine. It inherits the environment from the shell that starts it. Then, when Codex runs a command, that command inherits from the Codex process.
So the chain looks roughly like this:
Your shell starts Codex.
Codex starts a command.
That command checks `os.getenv()`.
If the value was not loaded into the shell before Codex started, the later command may never see it.
This is why a project can look configured but still fail inside Codex.
You may have a file like `~/secrets/project.env`. You may have `direnv` installed. You may know that the project normally works in your terminal.
But none of that proves the Codex CLI process has the variable right now.
The process environment is the thing that counts.
This is especially easy to miss with tools like `direnv`, because they make local development feel automatic. You `cd` into a repo, the environment loads, and everything feels like part of the machine.
But it is not part of the machine.
It is part of that shell session.
And when an agent, script, subprocess, task runner, or non-interactive command gets involved, you have to be much more explicit about what environment it actually received.
For beginners, the practical rule is this:
Before debugging the API client, verify the environment inside the same runtime boundary that will run the command.
Not in a different terminal.
Not by checking whether the secrets file exists.
Not by assuming `direnv` handled it.
Check the variable from the process path that matters.
For example, if Codex is about to run a Python script that needs `ENV_TOKEN`, first ask Codex to run:
`python3 -c "import os; print(bool(os.getenv('ENV_TOKEN')))"`
If that prints `False`, the problem is not yet the Python script.
It is not yet the API.
It is not yet the update workflow.
The problem is that the process is unauthenticated.
That changes the fix.
The fix is not merely documenting where the secret file lives. That is useful, but it is incomplete.
The fix is documenting how the secret gets loaded before Codex starts, and how to verify that Codex can see it.
For example:
Run Codex from a shell where the project environment has already been loaded.
If the repo uses `direnv`, make sure `direnv allow` has been run and the shell has actually loaded the `.envrc`.
Before running the workflow, verify the required token from inside the Codex command environment.
That is a much stronger operating habit than saying, "the file is there."
A file on disk is only a source.
An environment variable in the current process is runtime state.
Codex works with runtime state.
This small difference explains many local automation failures. A command fails with an auth error. The project owner says the secret exists. The agent sees the file path. Everyone starts looking at the wrong layer.
But the useful question is much narrower:
Does this process have the variable it needs, right now?
If the answer is no, fix that first.
Once the environment is actually present, then it makes sense to debug the code, the request, the API response, or the workflow logic.
This is one of those lessons that feels basic after you see it clearly.
But it is also one of the lessons that makes Codex much easier to use.
Codex is powerful, but it is still bound by ordinary process rules. It can only pass along the environment it was given. It can only run commands with the permissions and variables available to that session.
So when a Codex workflow needs secrets, make the contract explicit:
Start Codex from the right shell.
Load the project environment first.
Verify the required variables from inside the runtime.
Then run the automation.
That small check can save a lot of confused debugging.
-----------
If you find this content useful, please share it with this link: [https://patrickmichael.co.za/subscribe](https://patrickmichael.co.za/subscribe)