---
type: research
title: Token Codex — Claims, Scopes, and JWT Structure
description: The full JWT decoded from the Bearer token used by the desktop app — claims, scopes, and what each field enables
tags: [openai, jwt, oauth, claims, scopes, auth]
timestamp: 2026-08-25
---

# Token Codex — Claims, Scopes, and JWT Structure

Part of [openai-research](openai-research.md). Decoded from the real Bearer token captured by the bezetacil harness (2026-08-25, refreshed token).

## Header

```json
{"alg": "RS256", "kid": "mFnbD4V-KI0EXDyc4Q_vdanThEwG48vaIsuzKSJtn9s", "typ": "JWT"}
```

## Payload (claims)

```json
{
  "aud": ["https://api.openai.com/v1"],
  "client_id": "app_EMoamEEZ73f0CkXaXp7hrann",
  "iss": "https://auth.openai.com",
  "sub": "apple|000232.baec292476e74d26a842c381d383da52.1406",
  "amr": ["urn:openai:amr:apple"],
  "scp": ["openid", "profile", "email", "offline_access",
           "api.connectors.read", "api.connectors.invoke"],
  "session_id": "authsess_ESXHz0E0mXitXU3sRzGjVaoE",
  "sl": true,
  "jti": "4647d2d1…",
  "pwd_auth_time": 1786649686695,
  "https://api.openai.com/auth": {
    "chatgpt_account_id": "aa06cafc-…",
    "chatgpt_account_user_id": "user-3Qsjai6bWwak8NCEgerE8FRj__aa06cafc-…",
    "chatgpt_user_id": "user-3Qsjai6bWwak8NCEgerE8FRj",
    "chatgpt_plan_type": "plus",
    "chatgpt_compute_residency": "no_constraint",
    "localhost": true,
    "poid": "org-hqTROhgAms22weYjAbomRTTY",
    "user_id": "user-3Qsjai6bWwak8NCEgerE8FRj"
  },
  "https://api.openai.com/profile": {
    "email": "…", "email_verified": true, "name": "Alef Oliveira"
  },
  "iat": 1787681149, "nbf": 1787681149, "exp": 1788545149
}
```

## What each claim enables

| Claim | Effect |
|---|---|
| `aud: api.openai.com/v1` | the token talks to the API v1 (the chatgpt.com backends use this aud) |
| `amr: urn:openai:amr:apple` | auth method: Apple ID (Sign in with Apple) |
| `scp: api.connectors.read + invoke` | **connectors scope** — enables the chat submode plugins |
| `scp: offline_access` | refresh token is issued (partial rotation) |
| `localhost: true` | the session is local (desktop app, not web) |
| `sl: true` | session locking active |
| `chatgpt_plan_type: plus` | the plan — model/effort gating derives from this |
| `chatgpt_compute_residency: no_constraint` | no compute region restriction |
| `poid: org-…` | default organization |
| `exp - iat = 10 days` | access token window (the 5-minute preemptive refresh covers with margin) |

## OAuth scopes (the authorize request)

`openid profile email offline_access` + **`api.connectors.read` + `api.connectors.invoke`** — the last two are the connectors scopes that enable the chat submode plugins. The `offline_access` emits the refresh token.

## TypeScript types (the token surface)

```ts
export interface JwtHeader {
  alg: 'RS256'
  kid: string                // 'mFnbD4V-…' — 31 chars
  typ: 'JWT'
}
export type AmrMethod = 'urn:openai:amr:apple' | string
export type ScopeName = 'openid' | 'profile' | 'email' | 'offline_access'
                     | 'api.connectors.read' | 'api.connectors.invoke' | string
export type PlanType = 'plus' | 'pro' | 'free' | 'unknown' | string
export type ComputeResidency = 'no_constraint' | string

/** The `https://api.openai.com/auth` claim (nested, capitalized URL key). */
export interface OpenAIAuthClaim {
  chatgpt_account_id: string                  // 'aa06cafc-…'
  chatgpt_account_user_id: string             // 'user-…__aa06cafc-…'
  chatgpt_user_id: string                     // 'user-…'
  chatgpt_plan_type: PlanType
  chatgpt_compute_residency: ComputeResidency
  localhost: boolean                          // desktop app session (not web)
  poid: string                                // default org id ('org-…')
  user_id: string                             // 'user-…'
}

/** The access-token payload — the SAME shape for the app-server session and
 *  the A1 live authToken; the session_id is the WAF-recognized identity. */
export interface AccessTokenPayload {
  aud: ['https://api.openai.com/v1']
  client_id: 'app_EMoamEEZ73f0CkXaXp7hrann'
  iss: 'https://auth.openai.com'
  sub: `apple|${number}.${string}`            // 'apple|000232.baec…1406'
  amr: AmrMethod[]
  scp: ScopeName[]
  session_id: string                          // 'authsess_…' — per login session
  sl: boolean
  jti: string
  pwd_auth_time: number
  ['https://api.openai.com/auth']: OpenAIAuthClaim
  ['https://api.openai.com/profile']: {
    email: string
    email_verified: boolean
    name: string
  }
  iat: number
  nbf: number
  exp: number                                 // iat + 10 days (864000s)
}
export const AccessTokenLifetimeSeconds = 10 * 24 * 3600   // exp - iat observed
```

## Cross-references

- [auth-and-link-session](auth-and-link-session.md) — the OAuth flow and refresh
- [chat-submode-protocol](chat-submode-protocol.md) — where the token is used
- [attestation-flow](attestation-flow.md) — the integrity mechanism that validates the device
