Skip to content

MCP enterprise-managed auth rejects valid ID-JAGs that omit the optional resource claim (e.g. Okta) #59014

Open

Description

@daviddanialy

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 without resource, fails with this error.
  • Okta Cross App Access issued ID-JAGs without resource, even when the token exchange sent resource=. 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?

  1. Set [features].use_xaa = true and sign in with a ChatGPT account.
  2. Configure an MCP server with enterprise-managed auth, using an IdP that omits resource from the ID-JAG, such as Okta.
  3. 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

  1. added
    bugSomething isn't working
    CLIIssues related to the Codex CLI
    mcpIssues related to the use of model context protocol (MCP) servers
    authIssues related to authentication and accounts
    on Nov 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    CLIIssues related to the Codex CLIauthIssues related to authentication and accountsbugSomething isn't workingmcpIssues related to the use of model context protocol (MCP) servers

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions