A few days ago, AWS released OpenAI's GPT-5.6 on Amazon Bedrock, and I'm going to show you how to configure the Codex CLI so you can use these models directly through the Bedrock API, with the credentials you already have.
Depending on your configuration, Codex might already work with GPT models on Bedrock - out of the box. Try this:
codex \
-c model_providers.amazon-bedrock.aws.region="us-east-1" \
-c model_provider="amazon-bedrock" \
-c model="openai.gpt-5.6-terra"
If this starts the Codex CLI and responds to your prompts, you're ready to go! And if you don't want to pass -c
flags every time, add the following two lines to the top of ~/.codex/config.toml
:
model_providers.amazon-bedrock.aws.region = "us-east-1"
model_provider = "amazon-bedrock"
If it didn't work, or if you want to use a Bedrock API Key instead of the traditional AWS credentials, read on.
Otherwise, have fun! And drop a comment about which one you like better: Codex with GPT-5.6 Sol, or Claude Code with Fable?
The Codex CLI ships with a built-in Bedrock provider. To be able to use it, you need the AWS CLI, installed and configured with the required permissions.
The examples in this post use
export
to set environment variables, which works on macOS and Linux. On Windows, replace it withset
in the Command Prompt or$env:
in PowerShell.
Test the AWS CLI
aws sts get-caller-identity --output=yaml
If the AWS CLI is installed, it should return the following information (press q
to return to the shell):
Account: [Your Account ID]
Arn: [Your User or Role ARN]
UserId: [Your User ID]
In case of an error, follow the AWS CLI quickstart or troubleshooting guide.
Check your permissions
Your AWS configuration needs permission to call bedrock-mantle
, the Bedrock endpoint that serves various models using the OpenAI-compatible Responses and Chat Completions APIs. The quickest way to get access is to attach the AWS-managed policy AmazonBedrockLimitedAccess (arn:aws:iam::aws:policy/AmazonBedrockLimitedAccess
) to the user or role you want to use. It covers both the classic bedrock-runtime
API and bedrock-mantle
, including bearer-token calls.
Test Codex
Make sure you have installed the Codex CLI, then run:
codex exec \
--skip-git-repo-check \
-c model_providers.amazon-bedrock.aws.region="us-east-1" \
-c model_provider="amazon-bedrock" \
"Hello"
The
--skip-git-repo-check
flag is there because outside a git repository or trusted folder,codex exec
refuses to run. When running the command inside a git repo, you can omit the line.
If this returns a model response like the one below, you've successfully talked to a GPT model on Bedrock.
OpenAI Codex v0.144.5
--------
...
model: openai.gpt-5.5
provider: amazon-bedrock
...
--------
user
Hello
codex
Hello. What would you like to work on?
tokens used
9,580
The 9,580 tokens for a one-word prompt show that Codex sends its own system prompt and tool definitions with the request, which amounts to ~9,400-9,500 tokens of overhead before your content. Keep it in mind when you estimate costs and context budget.
The provider
line confirms you're talking to Bedrock rather than to OpenAI directly, and the model
line shows the model it used. In this example that's GPT-5.5, Codex's default at the time of writing.
To use a different model, configure it as part of the command:
codex exec \
--skip-git-repo-check \
-c model_providers.amazon-bedrock.aws.region="us-east-1" \
-c model_provider="amazon-bedrock" \
-c model="openai.gpt-5.6-terra" \
"Hello"
If codex exec
fails with a permission error, go back one step and check that the AmazonBedrockLimitedAccess policy is attached. For everything else, see the gotchas at the end of this post.
You don't need the AWS credential chain to talk to Bedrock. You can use a Bedrock API Key as a plain bearer token, which is the way to go on a machine where the AWS CLI isn't installed or configured, like a CI runner or a fresh container. There are two ways to generate one: the Amazon Bedrock console, which requires no setup at all, and the aws-bedrock-token-generator
library for the command line.
AWS_BEARER_TOKEN_BEDROCK
environment variable:
export AWS_BEARER_TOKEN_BEDROCK="bedrock-api-key-..."
Important:The key is scoped to the AWS Region you're currently in, so switch regions in the console first if necessary. The key expires when your console session expires, with a maximum of 12 hours.
AWS provides the aws-bedrock-token-generator
library for Python and JavaScript, which derives a bearer token from the credentials your AWS CLI is configured with. This option requires the AWS CLI, installed and configured (test it with aws sts get-caller-identity
as shown above).
Python:
Install the token generator for Python with pip
:
pip install aws-bedrock-token-generator
Then generate a key and store it in AWS_BEARER_TOKEN_BEDROCK
:
export AWS_REGION=us-east-1
export AWS_BEARER_TOKEN_BEDROCK=$(python3 << 'EOF'
from aws_bedrock_token_generator import provide_token
print(provide_token())
EOF
)
JavaScript:
Install the token generator for JavaScript with npm
:
npm install @aws/bedrock-token-generator
Then generate a key and store it in AWS_BEARER_TOKEN_BEDROCK
:
export AWS_REGION=us-east-1
export AWS_BEARER_TOKEN_BEDROCK=$(node --input-type=module << 'EOF'
import { getTokenProvider } from '@aws/bedrock-token-generator';
console.log(await getTokenProvider()());
EOF
)
Both the Python and JavaScript token generators use the default credential provider chain, so they pick up whatever profile or session your AWS CLI is using. The key is scoped to a single AWS Region, and it expires when the underlying credentials expire, capped at 12 hours.
Since generating a token is computationally inexpensive and free of charge, you can call provide_token()
before each request instead of caching it.
The key is a bearer token you can use directly against the bedrock-mantle
API, even before Codex enters the picture. Here's GPT-5.6 Luna via the OpenAI-compatible Responses API:
curl -X POST \
"https://bedrock-mantle.$AWS_REGION.api.aws/openai/v1/responses" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $AWS_BEARER_TOKEN_BEDROCK" \
-d '{
"model": "openai.gpt-5.6-luna",
"input": "Hello",
"max_output_tokens": 512
}'
The same key works with the Bedrock Runtime API, and with every other model your permissions allow:
curl -X POST \
"https://bedrock-runtime.$AWS_REGION.amazonaws.com/model/us.anthropic.claude-sonnet-5/converse" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $AWS_BEARER_TOKEN_BEDROCK" \
-d '{
"messages": [
{"role": "user", "content": [{"text": "Hello"}]}
]
}'
With AWS_REGION
set and the key stored in AWS_BEARER_TOKEN_BEDROCK
, you can point Codex at Bedrock directly. The two environment variables along with two -c
flags are the whole setup:
export AWS_REGION=us-east-1
export AWS_BEARER_TOKEN_BEDROCK="bedrock-api-key-..."
codex exec \
--skip-git-repo-check \
-c model_provider="amazon-bedrock" \
-c model="openai.gpt-5.6-luna" \
"say pong"
Both variables are standard AWS names rather than Codex inventions, so there's nothing to wire up: Codex checks AWS_BEARER_TOKEN_BEDROCK
before falling back to the SDK credential chain, and AWS_REGION
tells it which region's endpoint to call. This works on a machine with no AWS CLI and no Codex configuration at all.
At the time of writing, the GPT-5.6 models don't run in every AWS Region, and they don't all run in the same ones. Everything in this post is region-scoped, API keys included, so pick your region from this table and use it consistently:
| Model | Model ID | Regions |
|---|---|---|
| Sol | openai.gpt-5.6-sol |
|
| us-east-1, us-east-2 | ||
| Terra | openai.gpt-5.6-terra |
|
| us-east-1, us-east-2, us-west-2 | ||
| Luna | openai.gpt-5.6-luna |
|
| us-east-1, us-east-2, us-west-2 |
All three models are available in us-east-1
and us-east-2
, which makes either of them an easy default while you're getting started. Asking a region that doesn't have your model returns an HTTP 404, e.g. The model 'openai.gpt-5.6-sol' does not exist
.
Over time, the models will likely be rolled out to additional regions. You can check model availability...
Via the model cards - Each model's page in the Amazon Bedrock documentation for GPT-5.6 Sol, Terra, and Luna shows the current region table. Check it there before you configure anything.
From the command line - With AWS_BEARER_TOKEN_BEDROCK
set, ask the bedrock-mantle
Models API what a region actually hosts. Set the region you want to check:
export AWS_REGION=us-east-1
Then, with jq
:
curl -s "https://bedrock-mantle.$AWS_REGION.api.aws/v1/models" \
-H "Authorization: Bearer $AWS_BEARER_TOKEN_BEDROCK" \
| jq -r '.data[].id' | sort
Depending on the region, you'll see dozens of models from various providers:
anthropic.claude-fable-5
anthropic.claude-haiku-4-5
...
openai.gpt-5.6-luna
openai.gpt-5.6-sol
openai.gpt-5.6-terra
...
If you don't have jq
installed, grep
works as a fallback:
curl -s "https://bedrock-mantle.$AWS_REGION.api.aws/v1/models" \
-H "Authorization: Bearer $AWS_BEARER_TOKEN_BEDROCK" \
| grep "gpt-5.6"
In this case, a match prints the whole response, since the body is a single line of JSON. If you get an empty result, the models you grep for aren't available in the selected region.
Note: The
bedrock-mantle
in these URLs is the newer of Bedrock's two inference endpoints. The classicbedrock-runtime
endpoint servesInvokeModel
andConverse
, whilebedrock-mantle
serves the OpenAI-compatible Responses and Chat Completions APIs. The GPT-5.6 models run exclusively on mantle, which explains a surprise I had when I initially tried to find them:aws bedrock list-foundation-models
doesn't list them (see the gotchas below).
The three GPT-5.6 models are genuinely different products rather than size tiers of one model.
| Sol | Terra | Luna | |
|---|---|---|---|
| Model ID | openai.gpt-5.6-sol |
||
openai.gpt-5.6-terra |
|||
openai.gpt-5.6-luna |
|||
| Best for | coding, security, research | everyday production work | high-volume, low-latency |
Sol is the flagship, built for frontier reasoning and agentic coding. Terra is the balanced model for everyday production work, and the one I'd try first for most Codex sessions. Luna is built for classification, summarization, and routing, which makes it a good fit for codex exec
in a pipeline.
In the interactive CLI, switching is one command:
› /model
Select Model and Effort
› 1. openai.gpt-5.5
2. openai.gpt-5.4
3. openai.gpt-5.6-sol
4. openai.gpt-5.6-terra
5. openai.gpt-5.6-luna
A short note on cost and context: output pricing drops significantly across the family (Sol $33, Terra $16.50, Luna $6.60 per million output tokens, with input pricing scaling the same way, per the Bedrock pricing page), and all three share a 272K context window. Remember that Codex's own overhead of roughly ~9,400-9,500 tokens rides along on every request.
The following two lines make every Codex session use Bedrock automatically:
model_providers.amazon-bedrock.aws.region = "us-east-1"
model_provider = "amazon-bedrock"
To pin a model as well, add a third line:
model = "openai.gpt-5.6-terra"
Write these as flat dotted keys at the top of ~/.codex/config.toml
, before any entries with a [...]
header.
Authentication stays exactly as before: the API key in AWS_BEARER_TOKEN_BEDROCK
, or your AWS credential chain. With the region defined in the config file, you don't even need to set AWS_REGION
.
Start with Terra and see how it handles your actual work before you decide the flagship merits paying roughly double the price. The Codex and Bedrock guide covers provider configuration in more detail, and the model cards hold the current region tables, which are the first thing to check when a model 404s on you.
And if you want to use Codex for work with AWS, don't forget to install the new Agent Toolkit for AWS, with specialized tools, skills, and knowledge for AWS, available as a native Codex plugin:
codex plugin marketplace add aws/agent-toolkit-for-aws
codex plugin add aws-core --marketplace agent-toolkit-for-aws
Now go run with it and have fun! And drop a comment about which one you like better: Codex with GPT-5.6 Sol, or Claude Code with Fable?
aws bedrock list-foundation-models
won't show the GPT-5.6 models
They're served by the bedrock-mantle
endpoint, which the AWS CLI doesn't cover. Only OpenAI's OSS models show up on bedrock-runtime
. Use the Models API call above to see what a region actually hosts.
A region where the model isn't available returns a 404
The body reads The model 'openai.gpt-5.6-sol' does not exist
. Dropping the openai.
prefix from the model ID produces the identical error (The model 'gpt-5.6-sol' does not exist
), so check both before assuming an access problem.
The token generator library needs working AWS credentials
Without them, provide_token()
raises RuntimeError: No AWS credentials found. Check your environment or credential provider.
The library only derives keys, it doesn't authenticate you.
Run aws sts get-caller-identity
first; if that fails, troubleshoot your AWS CLI configuration.
Valid credentials can still lack Bedrock permissions
If your calls fail with an AccessDeniedException even though aws sts get-caller-identity
works, your user or role is missing Bedrock permissions. Attach the AWS-managed policy AmazonBedrockLimitedAccess (arn:aws:iam::aws:policy/AmazonBedrockLimitedAccess
) to the user or role. It covers both the bedrock-runtime
and bedrock-mantle
APIs, including bearer-token calls.
The token generator needs an explicit AWS Region
provide_token()
raises ValueError: Region must be provided or set via the AWS_REGION environment variable.
unless AWS_REGION
is set or you pass the region as an argument. It doesn't fall back to the region in your CLI profile the way most AWS SDK calls do, which is why the examples above set AWS_REGION
explicitly.
API keys are region-scoped too
A short-term key generated for one region doesn't work against another region's endpoint. Generate it for the region you picked from the availability table.
In Codex, auth failures look like network problems first
With a missing, expired, or invalid key, Codex doesn't report the cause up front. It retries five times (ERROR: Reconnecting... 1/5
through 5/5
) before printing the real error.
An invalid or expired key ends in unexpected status 401 Unauthorized: Invalid bearer token
with the endpoint URL; no key and no other AWS credentials ends in stream disconnected before completion: failed to load AWS credentials: the credential provider was not enabled
, whether or not the AWS CLI is even installed.
When you see the reconnect counter, check AWS_BEARER_TOKEN_BEDROCK
before suspecting your network. Short-term keys expire after 12 hours at most, so a session that worked this morning can fail after lunch.