Repository navigation
Description
What version of Codex CLI is running?
codex-cli 0.165.0
What subscription do you have?
ChatGPT account sign-in. Not plan-specific.
Which model were you using?
N/A. The failure happens during MCP authorization.
What platform is your computer?
macOS, arm64
What issue are you seeing?
Codex's MCP enterprise-managed authorization rejects ID-JAGs that omit the resource claim. The exchange fails in the rmcp package with malformed ID-JAG claims before the ID-JAG is redeemed.
The claim is optional: ID-JAG draft-04 §3.1 lists it as OPTIONAL, and MCP EMA §4.3 only constrains it "if present".
We've confirmed each half separately, but haven't yet run Codex against a real Okta tenant:
- Codex 0.165.0 with
[features].use_xaa = true, against a test IdP issuing an ID-JAG withoutresource, fails with this error. - Okta Cross App Access issued ID-JAGs without
resource, even when the token exchange sentresource=. Claims seen:jti, iss, aud, iat, exp, sub, email, client_id, sub_profile, scope, act, sub_id.
Any ID-JAG without resource fails this check, whichever IdP issued it, so Codex can't use the Okta ID-JAGs we've seen.
What steps can reproduce the bug?
- Set
[features].use_xaa = trueand sign in with a ChatGPT account. - Configure an MCP server with enterprise-managed auth, using an IdP that omits
resourcefrom the ID-JAG, such as Okta. - Connect to the server. The exchange fails at the identity provider stage with
malformed ID-JAG claims.
To reproduce without an IdP, remove resource from claims() in ema_exchange_tests.rs.
What is the expected behavior?
The exchange validates aud and redeems the ID-JAG at the resource authorization server.
Additional information
Root cause: codex-rs/Cargo.toml pins rmcp to 98a54789 (=3.5.1). At that commit, IdJagClaims.resource in transport/auth/enterprise.rs is a required field, so deserialization fails when it's absent. codex-rs/rmcp-client/src/ema_exchange.rs calls this path through exchange_id_jag.
Fixed upstream in modelcontextprotocol/rust-sdk#1406. An omitted claim is accepted and the ID-JAG stays bound to the resource AS by aud. A claim that is present must still match exactly, and an explicit null is still rejected.
Requested fix: Bump rmcp to 3.9.0 once it's released (modelcontextprotocol/rust-sdk#1403). c1646887 has the fix if you'd rather move the git pin now. 3.9.0 contains 98a54789, so the scope selection from #54653 is kept. A regression test for an ID-JAG without resource would also help.
We build Speakeasy, an MCP gateway. I wrote the upstream fix and can help test.
Activity