
Windows の ChatGPT デスクトップアプリ with Bedrock を設定したら CreateInference の権限エラーになったときの確認ポイント
はじめに
Windows の ChatGPT デスクトップアプリの接続先を Amazon Bedrock にして利用したところ、エラーになり実行できませんでした。Codex には Amazon Bedrock 向けのプロバイダーとして Runtime と Mantle の 2 つがあります。今回は Runtime を使うつもりで、aws login で使う IAM ユーザーには Runtime 用の権限だけを付けていました。エラーメッセージは、Mantle の bedrock-mantle:CreateInference が許可されていないというもの。それはそうなのだけど、と思いつつ切り分けたときの備忘録です。
結論
- エラーの URL とアクション名が
bedrock-mantleなら、Codex の接続先は Runtime でなく Mantle - Runtime を使うつもりなら、IAM の権限を見直す前に
config.tomlのmodel_providerを確認する - 今回は
model_providerがamazon-bedrock(Mantle)になっていた。amazon-bedrock-runtimeへ手動で書き換えて直った
エラーメッセージ
ChatGPT デスクトップアプリを起動し、画面で AWS プロファイルに default を選んで接続しました。事前に config.toml へ Bedrock 用の設定を書いていたため、AWS プロファイルの選択画面は出ない想定でした。すでに何かがおかしい。
テストメッセージを送ると、5 回再接続を試したあとにエラーメッセージが表示されました。

エラーの全文は次のとおりです。
unexpected status 403 Forbidden: User: arn:aws:iam::123456789012:user/bedrock-user is not authorized to perform: bedrock-mantle:CreateInference on resource: arn:aws:bedrock-mantle:ap-northeast-1:123456789012:project/default because no identity-based policy allows the bedrock-mantle:CreateInference action, url: https://bedrock-mantle.ap-northeast-1.api.aws/openai/v1/responses, request id: req_xxxxxxxx
リクエストは東京リージョンの Mantle に届き、IAM の権限がなく拒否されていました。Mantle は使うつもりがなかったので、そもそも権限を付けていません。
実行環境
| 項目 | 内容 |
|---|---|
| OS | Windows 11 Enterprise(OS ビルド 26200.9711) |
| クライアント | ChatGPT デスクトップアプリ 26.1023.51421 |
| 認証 | IAM ユーザー + aws login |
| リージョン | 東京(ap-northeast-1) |
| 使いたかった推論プロファイル | Bedrock Runtime の global クロスリージョン推論(global.openai.gpt-6.1-sol など) |
IAM ユーザーには、Runtime の global クロスリージョン推論だけを許可するポリシーを付けています。Claude Code も使う予定なので、対象には Anthropic のモデルも含めていますが、今回の件には関係ありません。
IAM ユーザーの権限、長いので折りたたみ
{
"Version": "2012-10-17",
"Statement": [
{
"Condition": {
"StringEquals": {
"aws:RequestedRegion": "ap-northeast-1"
}
},
"Action": [
"bedrock:InvokeModel",
"bedrock:InvokeModelWithResponseStream"
],
"Resource": [
"arn:aws:bedrock:ap-northeast-1:123456789012:inference-profile/global.openai.gpt-6.1-sol",
"arn:aws:bedrock:ap-northeast-1:123456789012:inference-profile/global.openai.gpt-6-astra",
"arn:aws:bedrock:ap-northeast-1:123456789012:inference-profile/global.openai.gpt-6-luna",
"arn:aws:bedrock:ap-northeast-1:123456789012:inference-profile/global.anthropic.claude-opus-5-5",
"arn:aws:bedrock:ap-northeast-1:123456789012:inference-profile/global.anthropic.claude-sonnet-5-5",
"arn:aws:bedrock:ap-northeast-1:123456789012:inference-profile/global.anthropic.claude-haiku-5-5",
"arn:aws:bedrock:ap-northeast-1:123456789012:inference-profile/global.anthropic.claude-fable-5-1",
"arn:aws:bedrock:ap-northeast-1:123456789012:project/default"
],
"Effect": "Allow",
"Sid": "GlobalCrisProfileAndProject"
},
{
"Condition": {
"StringEquals": {
"aws:RequestedRegion": "ap-northeast-1"
},
"ArnLike": {
"bedrock:InferenceProfileArn": "arn:aws:bedrock:ap-northeast-1:123456789012:inference-profile/global.*"
}
},
"Action": [
"bedrock:InvokeModel",
"bedrock:InvokeModelWithResponseStream"
],
"Resource": [
"arn:aws:bedrock:ap-northeast-1::foundation-model/openai.gpt-6.1-sol",
"arn:aws:bedrock:ap-northeast-1::foundation-model/openai.gpt-6-astra",
"arn:aws:bedrock:ap-northeast-1::foundation-model/openai.gpt-6-luna",
"arn:aws:bedrock:ap-northeast-1::foundation-model/anthropic.claude-opus-5-5",
"arn:aws:bedrock:ap-northeast-1::foundation-model/anthropic.claude-sonnet-5-5",
"arn:aws:bedrock:ap-northeast-1::foundation-model/anthropic.claude-haiku-5-5",
"arn:aws:bedrock:ap-northeast-1::foundation-model/anthropic.claude-fable-5-1"
],
"Effect": "Allow",
"Sid": "GlobalCrisInRegionModel"
},
{
"Condition": {
"StringEquals": {
"aws:RequestedRegion": "unspecified"
},
"ArnLike": {
"bedrock:InferenceProfileArn": "arn:aws:bedrock:ap-northeast-1:123456789012:inference-profile/global.*"
}
},
"Action": [
"bedrock:InvokeModel",
"bedrock:InvokeModelWithResponseStream"
],
"Resource": [
"arn:aws:bedrock:::foundation-model/openai.gpt-6.1-sol",
"arn:aws:bedrock:::foundation-model/openai.gpt-6-astra",
"arn:aws:bedrock:::foundation-model/openai.gpt-6-luna",
"arn:aws:bedrock:::foundation-model/anthropic.claude-opus-5-5",
"arn:aws:bedrock:::foundation-model/anthropic.claude-sonnet-5-5",
"arn:aws:bedrock:::foundation-model/anthropic.claude-haiku-5-5",
"arn:aws:bedrock:::foundation-model/anthropic.claude-fable-5-1"
],
"Effect": "Allow",
"Sid": "GlobalCrisGlobalModel"
},
{
"Action": "bedrock:ListInferenceProfiles",
"Resource": "*",
"Effect": "Allow",
"Sid": "ListInferenceProfiles"
},
{
"Action": "bedrock:GetInferenceProfile",
"Resource": [
"arn:aws:bedrock:ap-northeast-1:123456789012:inference-profile/global.openai.gpt-6.1-sol",
"arn:aws:bedrock:ap-northeast-1:123456789012:inference-profile/global.openai.gpt-6-astra",
"arn:aws:bedrock:ap-northeast-1:123456789012:inference-profile/global.openai.gpt-6-luna",
"arn:aws:bedrock:ap-northeast-1:123456789012:inference-profile/global.anthropic.claude-opus-5-5",
"arn:aws:bedrock:ap-northeast-1:123456789012:inference-profile/global.anthropic.claude-sonnet-5-5",
"arn:aws:bedrock:ap-northeast-1:123456789012:inference-profile/global.anthropic.claude-haiku-5-5",
"arn:aws:bedrock:ap-northeast-1:123456789012:inference-profile/global.anthropic.claude-fable-5-1"
],
"Effect": "Allow",
"Sid": "GetAllowedInferenceProfiles"
},
{
"Action": "bedrock:CallWithBearerToken",
"Resource": "*",
"Effect": "Allow",
"Sid": "BearerTokenAuth"
},
{
"Condition": {
"StringEquals": {
"aws:CalledViaLast": "bedrock.amazonaws.com"
}
},
"Action": [
"aws-marketplace:Subscribe",
"aws-marketplace:Unsubscribe",
"aws-marketplace:ViewSubscriptions"
],
"Resource": "*",
"Effect": "Allow",
"Sid": "MarketplaceSubscribeViaBedrock"
}
]
}
エラーメッセージから接続先を見分ける
2 つのプロバイダーの違いは次のとおりです。
| Mantle | Runtime | |
|---|---|---|
model_provider |
amazon-bedrock |
amazon-bedrock-runtime |
| 接続先 | bedrock-mantle.{region}.api.aws |
bedrock-runtime.{region}.amazonaws.com |
| IAM のアクション | bedrock-mantle:CreateInference |
bedrock:InvokeModel など |
| 推論の範囲 | リージョン内 | global / geo のクロスリージョン推論 |
| モデル ID の例 | openai.gpt-6.1-sol |
global.openai.gpt-6.1-sol、us.openai.gpt-6.1-sol |
| Web 検索 | 使える(web_search = "cached") |
使えない(web_search = "disabled") |
OpenAI の公式ドキュメントでは、新しく設定するなら Runtime を推奨しています。Web 検索が必要な場合は Mantle を使うよう案内されています。
エラーメッセージの url: と perform: のあとを見ると、Codex がどちらにアクセスしているかがわかります。今回は URL が bedrock-mantle.ap-northeast-1.api.aws でした。アクションも bedrock-mantle:CreateInference で、どちらも Mantle です。Runtime 用の権限しか付けていないので、403 になること自体は当然です。この時点で疑うべきは、接続先がなぜ Mantle になっているのかです。
config.toml の接続先を確認する
Codex の設定は %USERPROFILE%\.codex\config.toml と %USERPROFILE%\.codex\.env にあります。ChatGPT デスクトップアプリと Codex CLI は同じファイルを読み込みます。
Get-Content "$env:USERPROFILE\.codex\config.toml"
Get-Content "$env:USERPROFILE\.codex\.env"
確認したいところは以下の 2 つです。
model_providerが使いたい接続先になっているか。Runtime ならamazon-bedrock-runtime.envにAWS_REGIONが書いてあるか
今回の config.toml は、関係する部分を抜き出すと次のようになっていました。
model_provider = "amazon-bedrock"
[model_providers.amazon-bedrock.aws]
profile = "default"
region = "ap-northeast-1"
model_provider が amazon-bedrock(Mantle)になっていて、Runtime 用の設定が入っていませんでした。[model_providers.amazon-bedrock.aws] の profile と region も、Codex の設定リファレンスでは Mantle 用のキーです。
初期設定で model_provider の値を書き換えたはずでした。Mantle 用の設定に戻ったのか、書き込みに失敗していたのか、経緯は特定できていません。エラーに bedrock-mantle が出たら、このファイルを開いて model_provider を確認してください。
対処方法
次の順で直しました。
- タスクトレイのアイコンを右クリックし、
Exitをクリックして ChatGPT デスクトップアプリを完全に終了する config.tomlを Runtime 用に書き直す.envにリージョンを書く- PowerShell で
aws loginを実行する - ChatGPT デスクトップアプリを起動し、OpenAI へのサインインなどを求められずにチャット画面が開くことを確認する
- テストメッセージを送って応答が返ってくることを確認する
config.toml に入れた設定のうち、関係する部分を抜き出すと次のとおりです。
model_provider = "amazon-bedrock-runtime"
model = "global.openai.gpt-6.1-sol"
web_search = "disabled"
model_context_window = 1000000
model_auto_compact_token_limit = 900000
デスクトップアプリはシェルの環境変数を引き継がないことがあるので、リージョンは .env に書きました。
export AWS_REGION=ap-northeast-1
無事、応答が返ってくるようになりました。
まとめ
Codex の Amazon Bedrock 向けプロバイダーには Mantle と Runtime の 2 つがあります。Runtime を使うつもりで 403 のエラーに bedrock-mantle が出たら、ひとまず確認したいところは config.toml の model_provider です。
今回は model_provider が amazon-bedrock(Mantle)になっていました。amazon-bedrock-runtime に書き直してアプリを起動し直すと、応答が返るようになりました。
おわりに
EC2 で起動した Windows Server でテスト済みのクライアント向けの設定を、スクリプトで Windows 11 の実機に流し込みました。ところがどういう訳か config.toml が書き換わらずにトラブりました。何より私が Windows ユーザーではないこともあり、操作に苦労したので書き留めておきました。












