(Work in progress; last updated 2026-10-02 12:39 JST) On September 29, at DevDay 2026, OpenAI officially announced Sign in with ChatGPT (SIWC). I would like to check the details myself and write an article, but I do not have the time right now. So I am posting below a working draft that I asked ChatGPT itself to put together. If you spot any errors, please let me know on X.

SIWC is the OpenID Connect Provider / OAuth Authorization Server functionality that OpenAI has begun offering. In practice, however, the same brand covers the following 2 capabilities.

  1. Identity Sign-in
    An essentially standard flow using a ChatGPT account: OpenID Connect Authorization Code + PKCE.
  2. ChatGPT plan usage
    A mechanism that lets external OSS and supported applications use the allowance included in ChatGPT subscriptions such as Plus and Pro through the Responses API with an OAuth Access Token.

The latter is particularly distinctive. More than an extension of “logging in with ChatGPT,” it is a mechanism for passing ChatGPT subscriber identity + delegated inference entitlement to external applications via OAuth. OpenAI itself explicitly identifies Identity and plan usage as separate permissions. 1

OpenAI began rolling out Identity functionality to selected partner sites and plugins on September 23, 2026, and formally announced the offering, including ChatGPT plan usage, on September 29 at DevDay 2026.

1. Identity Sign-in

1.1 The Identity part is essentially ordinary OpenID Connect

OpenAI’s production Discovery Document is publicly available. 2.

Its main metadata is as follows.

ItemValue
Issuerhttps://auth.openai.com
Authorization Endpointhttps://auth.openai.com/api/accounts/authorize
Token Endpointhttps://auth.openai.com/api/accounts/oauth/token
UserInfo Endpointhttps://auth.openai.com/api/accounts/oauth/userinfo
Revocation Endpointhttps://auth.openai.com/api/accounts/oauth/revoke
JWKShttps://auth.openai.com/.well-known/jwks.json
response_typecode only
grant_typeauthorization_code, refresh_token
PKCES256
subject typepublic
ID Token signingRS256
token endpoint authclient_secret_basic, client_secret_post, none

In other words, the basic structure is:

OIDC
  └─ OAuth 2.0 Authorization Code
       └─ PKCE S256

For a website using Identity alone, the Authorization Request in OpenAI’s own example is almost exactly a typical OIDC request.

GET https://auth.openai.com/api/accounts/authorize?
    client_id=oaiapp_...
    &redirect_uri=https%3A%2F%2Fexample.com%2Fcallback
    &response_type=code
    &scope=openid%20profile%20email
    &state=...
    &nonce=...
    &code_challenge=...
    &code_challenge_method=S256

The scopes are:

openid
profile
email

profile requests name, picture, and similar claims, while email requests email and email verification claims. Discovery also lists standard OIDC Claims, including email_verified. 3


1.2. Validating the ID Token

The RP validates the ID Token using the JWKS, as usual.

OpenAI explicitly requires checking:

iss
aud
exp
nonce
sub
signature

aud is the RP’s client_id, iss is:

https://auth.openai.com

4

For the identity key at the RP, OpenAI recommends retaining:

issuer + client_id + sub

Another important point is its instruction:

Do not automatically link to an existing account based solely on email.

An email match is not considered proof of account ownership. This is sound design.

The subject type in Discovery is:

"subject_types_supported": ["public"]

(Source) https://auth.openai.com/.well-known/openid-configuration

Thus, pairwise subjects are not currently advertised.


1.3. Identity-only sign-in does not use an Access Token

This is a somewhat interesting design choice.

For SIWC on an ordinary website, OpenAI states:

For identity-only sign-in, the required artifact is id_token. An OpenAI access token or refresh token should not be required.

5.

Although a UserInfo endpoint is advertised in Discovery, the standard SIWC web login example does not depend on UserInfo. I have not checked yet, so I do not know what happens if you call it with an access token. I understand the desire not to return an Access Token for identity-only sign-in—a need that comes up in various places—even though RFC 6749 makes it REQUIRED and therefore requires it to be returned. I think creating a new Grant Type in the OAuth WG would probably be a good approach. For now, though, I suspect the token is returned simply because it has to be (this needs checking). So where is the Access Token used? I will discuss that later.


1.4. Public client / Confidential client

Both are supported.

Public client

Token Endpoint Authentication is:

none

PKCE is used.

POST /api/accounts/oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
&code=...
&redirect_uri=...
&client_id=...
&code_verifier=...

Confidential client

The currently documented example uses:

client_secret_basic

Even confidential clients retain PKCE. 6.

Discovery itself advertises:

client_secret_basic
client_secret_post
none

These are the 3 supported methods. 7.


2. ChatGPT plan usage: Using OpenAI models through a subscription

2.1 Obtaining an access token for ChatGPT plan usage

As mentioned at the beginning, Sign in with ChatGPT includes a feature called “ChatGPT plan usage”. This delegates, via OAuth, authority from the user’s ChatGPT plan for an external application to call the OpenAI Responses API. With this, the external application (client) can specify an OpenAI model and perform various tasks: using tools to read the web or read and write files, reasoning, and producing output.

flowchart TD
    A["Application"]
    B["Responses API"]
    C["Model"]
    D["Web search"]
    E["Files"]
    F["Code"]
    G["Computer"]
    H["MCP server"]

    A --> B
    B --> C

    C --> D
    C --> E
    C --> F
    C --> G
    C --> H

It is therefore useful to understand it as:

Responses API = the basic primitive for agent execution using OpenAI models

An access token is needed for this delegation. With SIWC, the client obtains one by requesting the following scope values in the Authentication Request. 8.

openid
profile
email
offline_access
resource.invoke
chatgpt.tokens.use.direct

In addition, it must include:

resource=https://api.openai.com/v1

in both the Authorization Request and the Token Request.

This takes the form of RFC 8707 Resource Indicators for OAuth 2.0 9. RFC 8707 uses resource to specify the target Resource Server with an absolute URI.

Conceptually, then:

           OpenAI Authorization Server
             auth.openai.com
                    │
                    │ Access Token
                    ▼
              External OSS app
                    │
                    │ Bearer AT
                    ▼
          OpenAI Resource Server
          api.openai.com/v1

The Access Token’s aud is also:

"aud": "https://api.openai.com/v1"

10. It is not the UserInfo Endpoint.


2.2 An Access Token example

The payload published by OpenAI looks conceptually like this.

{
  "sub": "...",
  "aud": "https://api.openai.com/v1",
  "client_id": "oaiapp_...",
  "scope":
    "chatgpt.tokens.use.direct email offline_access openid profile resource.invoke",

  "https://api.openai.com/auth": {
    "per_user_salt": "...",
    "encrypted_auth_metadata": "..."
  },

  "iss": "https://auth.openai.com",
  "iat": 1790032532,
  "exp": 1790036132,
  "jti": "...",
  "nbf": 1790032532
}

In other words, the Access Token is also a JWT.

The lifetimes are:

  • Access Token: 1 hour
  • Refresh Token: 30 days
  • Refresh Token rotation on every refresh
  • Each new Refresh Token receives a fresh 30-day lifetime

The current documentation does not use sender-constraining mechanisms such as DPoP. The token is sent to the Responses API using the usual header:

Authorization: Bearer <ACCESS_TOKEN>

11.


2.3 Using a ChatGPT subscription through the Responses API

For example:

POST https://api.openai.com/v1/responses
Authorization: Bearer <SIWC_ACCESS_TOKEN>
Content-Type: application/json

{
  "model": "...",
  "input": [...],
  "store": false,
  "stream": true
}

For SIWC plan usage, OpenAI currently requires:

store: false
stream: true

12.

Thus, this is more than simply replacing a regular API key with an OAuth token.

Some Responses API features are also restricted. For example, the current preview does not support:

  • background
  • persistent conversation
  • previous_response_id over HTTP
  • hosted MCP/connectors
  • image generation
  • file search
  • Code Interpreter
  • native computer use

among other features. 13

It is therefore also somewhat different from an API subscription accessed through OAuth.


3. SIWC-specific extensions

3.1 A 4th client registration method: dynamic_agent_client

With ordinary OAuth, a client is either registered in advance or registered through an RFC 7591 Dynamic Client Registration Endpoint. In the OpenID context, OpenID Federation has recently become another option.

SIWC’s OSS flow follows neither approach.

The initial Authorization Request uses a special pseudo-client:

client_id=dynamic_agent_client

It also includes:

agent_name_hint
ext_agent_host_id

14

For example:

GET https://auth.openai.com/api/accounts/authorize?

 client_id=dynamic_agent_client
 &agent_name_hint=OpenClaw
 &ext_agent_host_id=urn:uuid:...
 &response_type=code
 &redirect_uri=http://127.0.0.1:1455/auth/callback

 &scope=openid profile email
        offline_access
        resource.invoke
        chatgpt.tokens.use.direct

 &resource=https://api.openai.com/v1

 &state=...
 &nonce=...
 &code_challenge=...
 &code_challenge_method=S256

The callback then takes this form:

?code=...
&state=...
&client_id=oaiapp_xxxxx

At this point, the actual client_id is issued.[notes] OpenAI Developers – Sign in with ChatGPT – Registration and sign-in[/notes]

For the subsequent Token Endpoint request, do not send:

dynamic_agent_client

Instead, send the newly issued:

oaiapp_xxxxx


This is clearly different from RFC 7591 Dynamic Client Registration.

With RFC 7591, the typical flow is:

POST registration_endpoint
       ↓
client_id
client_secret...

The SIWC OSS flow is:

sequenceDiagram
    autonumber

    participant C as OSS Client / Agent
    participant B as Browser
    participant AS as OpenAI Authorization Endpoint
    participant U as User

    C->>C: Generate state, nonce,<br/>code_verifier / code_challenge

    C->>B: Open authorization URL
    B->>AS: GET /api/accounts/authorize<br/>client_id=dynamic_agent_client<br/>response_type=code<br/>redirect_uri=http://127.0.0.1:PORT/callback<br/>scope=openid profile email ...<br/>code_challenge=...<br/>code_challenge_method=S256

    AS->>U: Authenticate user
    U-->>AS: Authentication completed

    AS->>U: Show consent / application registration
    U-->>AS: Approve

    Note over AS: Create/register a concrete client<br/>and issue client_id = oaiapp_...

    AS-->>B: HTTP Redirect to redirect_uri<br/>?code=AUTH_CODE<br/>&state=STATE<br/>&client_id=oaiapp_...

    B-->>C: GET /callback<br/>code=AUTH_CODE<br/>state=STATE<br/>client_id=oaiapp_...

    Note over C: Store issued oaiapp_... client_id<br/>Use it for the token request,<br/>not dynamic_agent_client

It is therefore appropriate to view this as:

user-mediated dynamic registration embedded into an Authorization Request

RFC 7591-compatible Dynamic Client Registration would not be an appropriate label.


3.2 ext_agent_host_id

This is another interesting OpenAI extension.

Separate from the OSS client, there is the concept of an:

agent host

For example, the model is:

flowchart TD
    A["One SIWC client registration"]
    B["client_id"]

    A --> B

    B --> C["Laptop"]
    B --> D["VM"]

    C --> E["ext_agent_host_id A"]
    D --> F["ext_agent_host_id B"]

15.

OpenAI currently allows the following host IDs:

Recommended

urn:ietf:params:oauth:jwk-thumbprint:...

RFC 9278 JWK Thumbprint URI

Alternatives

urn:uuid:<uuid>

or

did:key:...

16

A crucial point, however, is that currently:

Even when a JWK Thumbprint is used, OpenAI does not verify possession of the private key.

17

Therefore:

JWK thumbprint host ID
 ≠ proof-of-possession
 ≠ DPoP
 ≠ client authentication

At present, it is simply a stable host identifier.


4. As a native app flow, it follows RFC 8252 quite closely

OSS desktop applications and clients use:

http://127.0.0.1:{port}/auth/callback

localhost is not used; the required IP literal is 127.0.0.1. Only the port number may change between sign-ins. 18.

This is consistent with Loopback Interface Redirection in RFC 8252. RFC 8252 itself defines:

http://127.0.0.1:{port}/...

and requires native apps to use PKCE.


5. Returning login and id_token_hint

After registration, subsequent sign-ins can use:

client_id=<issued oaiapp_...>
ext_agent_host_id=...
id_token_hint=<previous ID Token>
login_hint=user@example.com

Interestingly, OpenAI explicitly states that a previous ID Token, even if expired, can be used as id_token_hint. 19.

This does not depart from OpenID Connect Core 1.0.

OIDC Core itself describes:

id_token_hint as a hint indicating a current or past authenticated session

and recommends accepting an ID Token issued by the OP even after its exp time, provided it represents a recent session.

This part is therefore a very OIDC-like implementation.


6. There are some inconsistencies in the Discovery metadata

From a standardization perspective, this is currently the part that concerns me most.

The Discovery document’s:

"scopes_supported": [
  "openid",
  "profile",
  "email",
  "offline_access"
]

does not include:

resource.invoke
chatgpt.tokens.use.direct

OpenAI

Yet the official SIWC documentation explicitly requires:

offline_access
resource.invoke
chatgpt.tokens.use.direct

20.

This is not necessarily fatal from a specification perspective, but it means:

The SIWC plan-usage capability cannot be discovered from Discovery metadata alone.

It would therefore be better to add this information.

Similarly, it uses:

resource=https://api.openai.com/v1

in the style of RFC 8707, but there is no SIWC-specific discovery metadata for the plan-usage capability.

At present, therefore, both of the following must be consulted:

OIDC discovery
   +
out-of-band OpenAI SIWC profile documentation


7. ChatGPT plugins involve two layers of OAuth

Integration with a ChatGPT plugin has an even more interesting structure.

OpenAI describes it as follows:

ChatGPT
   │
   │ outer OAuth
   ▼
Plugin / external application
   │
   │ inner SIWC/OIDC
   ▼
OpenAI Authorization Server

21.

Outer transaction

ChatGPT → Plugin:

/oauth/authorize
  ?response_type=code
  &client_id=CHATGPT_CONNECTOR_CLIENT_ID
  &redirect_uri=...
  &scope=...
  &state=...
  &code_challenge=...
  &code_challenge_method=S256
  &resource=...
  &login_hint=...
  &target_flow=chatgpt_siwc

Inner transaction

Plugin → OpenAI:

openid profile email

using SIWC with these scopes.

The plugin validates the OpenAI ID Token, identifies the local account, and then resumes the outer OAuth transaction. 22.

The important point is:

SIWC does not replace the plugin’s own OAuth Authorization Server.

It sits inside the flow as an inner layer of identity federation.


8. Identity and authorization are deliberately separated

Putting it all together:

flowchart TD
    A["OpenAI / ChatGPT account"]

    A -->|"OIDC Authentication<br/>openid profile email"| B["Application"]

    B -->|"Application's own session"| C["Local session"]

    B -->|"Optional authorization<br/>chatgpt.tokens.use.direct<br/>resource.invoke"| D["OAuth Access Token"]

    D -->|"Bearer token"| E["OpenAI Responses API"]

Identity sign-in alone does not pass along:

  • ChatGPT conversations
  • memory
  • files
  • billing data
  • API key

or similar data. OpenAI Help Center

Also, without chatgpt.tokens.use.direct, a valid ID Token alone does not enable inference using a ChatGPT plan. OpenAI Developers

This separation is a significant design choice.


9. A security perspective

The current profile can be summarized from an OAuth/OIDC security perspective as follows:

ItemSIWC
Authorization Code○
PKCE S256○ / Effectively required
state○
OIDC nonce○
Exact redirect URI○
Native app external browser○
Loopback redirect○
refresh rotation○
RFC 8707 style resource○
Sender-constrained ATNot documented
DPoPNot documented
mTLSNot documented
PARAbsent from Discovery
JARrequest unsupported
Pairwise subNo; public only
Dynamic registrationOpenAI-specific approach

Discovery also states:

"request_uri_parameter_supported": false,
"request_parameter_supported": false

Thus, JAR/request objects are not currently used. This can be seen in the current https://auth.openai.com/.well-known/openid-configuration.


10. Design points deserving particular attention

From a standardization perspective, I would pay particular attention to the following 4 points.

① Separation of “sign-in” and “AI entitlement”

This is good design.

authentication != authorization != subscription entitlement

This distinction is relatively clear.

② A ChatGPT subscription becomes OAuth Resource Access

chatgpt.tokens.use.direct is more than a mere API scope. In effect, it delegates the following authority:

“This client may consume the allowance under this ChatGPT subscriber’s plan.”

The meaning of the scope expands from the “user data/API action” envisioned by traditional OAuth to economic entitlement delegation.

This is also very interesting from the perspective of Agentic Payments and delegated authority.

③ Client registration is user-bound

In the OSS flow, the issued client_id is bound to:

user + selected workspace

23

This differs considerably from the conventional OAuth model:

client_id = software application/deployment

It is closer to:

client_id ≈ user-authorized agent registration

④ Host identity is added to OAuth

Furthermore, the following are handled separately:

client
user
workspace
host

This structure is quite close to the separation of identities that will become important for Agentic AI:

Principal
Agent
Client
Runtime
Device/Host


11. There are also some concerns

From a protocol design perspective, this is the relevant part:

        User
         │
         │ owns
         ▼
 ChatGPT subscription
         │
         │ delegates entitlement
         ▼
       Client
         │
         │ runs on
         ▼
     Agent Host
         │
         │ Bearer AT
         ▼
 Responses Resource Server

At present, however, although:

ext_agent_host_id

exists, possession of the host’s private key is not verified.

Current host identification is therefore:

identification

rather than:

cryptographic binding

24.

Furthermore, the Access Token is a bearer token.

For high-value tasks, I think there is considerable scope for introducing a binding here in the future using mechanisms such as:

JKT / DPoP / attested key

In other words, moving toward FAPI.


13. Summary

Sign in with ChatGPT is a fairly straightforward OIDC implementation.

OIDC Authorization Code
+ PKCE S256
+ nonce
+ public sub
+ standard ID Token validation

On top of that, OpenAI adds its own profile:

dynamic_agent_client
agent_name_hint
ext_agent_host_id
resource.invoke
chatgpt.tokens.use.direct

to enable:

ChatGPT subscription entitlement
       ↓ OAuth delegation
Responses API

The key point is that this is more than just “the ChatGPT version of Sign in with Google.” It combines Identity Provider + subscriber entitlement authorization + agent/client/host registration system.

From a standardization perspective, it is helpful to view this as a design built largely on RFC 8707 / RFC 8252 / OpenID Connect Core, with proprietary extensions specifically for Dynamic Client Registration and agent-host binding.

Footnotes

  1. OpenAI, DevDay 2026 recap
  2. OpenAI OIDC Discovery Document
  3. OpenAI Developers
  4. OpenAI Developers: On your website
  5. For standard identity-only sign-in, the required artifact is id_token. Don’t require an OpenAI access_token or refresh_token; they aren’t part of the standard identity-only client contract. source: OpenAI Developers
  6. OpenAI Developers – Signin with ChatGPT – On your website
  7. OpenAI
  8. OpenAI Developers: Registrations and signin
  9. RFC 8707: Resource Indicators for OAuth 2.0 | RFC Editor
  10. OpenAI Developers
  11. OpenAI Developers – Signin with ChatGPT – Models and inference
  12. OpenAI Developers – Signin with ChatGPT – Models and inference
  13. OpenAI Developers – Sign in with ChatGPT – Preview limitations
  14. OpenAI Developers: Registration and sign-in
  15. OpenAI Developers-Sigin in with ChatGPT-Overview
  16. OpenAI Developers
  17. OpenAI Developers – Sign in with ChatGPT – Overview
  18. OpenAI Developers – Signin with ChatGPT – Registration and sign-in
  19. OpenAI Developers-SIWC-Registration and sign-in
  20. OpenAI Developers – Signin with ChatGPT – Registration and sign-in
  21. OpenAI Developers – In your ChatGPT plugin
  22. OpenAI Developers – Sign in with ChatGPT – In your ChatGPT plugin
  23. OpenAI Developers – Signin with ChatGPT – Overview
  24. OpenAI Developers: SIWC – Overview

Related posts