(編集中:最終更新 2026-10-02 12:39 JST)OpenAIが9月29日のDevDay 2026でSign in with ChatGPT (SIWC) を正式発表しました。で、自分で手でチェックしたりして記事を書きたいところですが、ちょっと今時間が取れません。なので、ChatGPT自身にまとめてもらった下敷きを以下に貼っておきます。間違いなど発見したらXでおしえて教えてください。
SIWCは、OpenAI が提供し始めた OpenID Connect Provider / OAuth Authorization Server 機能です。ただし、実際には次の2つの機能が同じブランドの下にあります。
- Identity Sign-in
ChatGPTアカウントを使った、ほぼ標準的な OpenID Connect Authorization Code + PKCE。 - ChatGPT plan usage
Plus/Pro等のChatGPT契約に含まれる利用枠を、外部のOSS/対応アプリから OAuth Access TokenでResponses APIに持ち出して使う仕組み。
後者がかなり特徴的です。これは「ChatGPTでログイン」の延長というより、ChatGPT subscriber identity + delegated inference entitlement をOAuthで外部アプリに渡す仕組みです。OpenAI自身も Identity と plan usage を別 permission と明記しています。 1
OpenAIは2026年9月23日に一部partner site/pluginへのIdentity機能のrolloutを開始し、9月29日のDevDay 2026でChatGPT plan usageを含む形を正式に発表しています。
Identity Sign-in
Identity部分はほぼ普通のOpenID Connect
OpenAIのproduction Discovery Documentは実際に公開されています 2。
主要なmetadataは次の通りです。
| 項目 | 値 |
|---|---|
| Issuer | https://auth.openai.com |
| Authorization Endpoint | https://auth.openai.com/api/accounts/authorize |
| Token Endpoint | https://auth.openai.com/api/accounts/oauth/token |
| UserInfo Endpoint | https://auth.openai.com/api/accounts/oauth/userinfo |
| Revocation Endpoint | https://auth.openai.com/api/accounts/oauth/revoke |
| JWKS | https://auth.openai.com/.well-known/jwks.json |
| response_type | code のみ |
| grant_type | authorization_code, refresh_token |
| PKCE | S256 |
| subject type | public |
| ID Token signing | RS256 |
| token endpoint auth | client_secret_basic, client_secret_post, none |
つまり基本形は、
OIDC
└─ OAuth 2.0 Authorization Code
└─ PKCE S256
です。
WebサイトでIdentityだけを使う場合のAuthorization Requestは、OpenAI自身の例ではほぼそのまま典型的OIDCです。
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
Scopeは
openid
profile
email
です。
profile ではname/picture等、email ではemailおよびemail verification claimを要求します。Discoveryにも email_verified を含む標準的なOIDC Claimsが列挙されています。3
ID Tokenの検証
RP側は通常どおりID TokenをJWKSで検証します。
OpenAIは明示的に、
iss
aud
exp
nonce
sub
signature
を確認するよう要求しています。
aud はRPの client_id、iss は
https://auth.openai.com
です。 4
RPでのidentity keyについてOpenAIは、
issuer + client_id + sub
を保持することを推奨しています。
また重要なのは、
emailだけで既存アカウントに自動リンクしてはいけない
としている点です。email matchはaccount ownershipの証明とはみなしていません。これは正しい設計です。
Discovery上のsubject typeは、
"subject_types_supported": ["public"]
(出所) https://auth.openai.com/.well-known/openid-configuration
です。したがって現時点ではpairwise subjectをadvertiseしていません。
Identity-onlyではAccess Tokenを使わない
ここは少し面白い設計です。
通常のWebサイトのSIWCでは、OpenAIは、
identity-only sign-inでは必要なartifactは
id_token。OpenAI access tokenやrefresh tokenを要求しないように
としています5。
UserInfo endpointはDiscoveryされていますが、標準SIWC Web loginのサンプルはUserInfoを前提としていません。まだ確認していないので、ここをaccess tokenで叩いたらどうなるかまだわかりません。Identity-onlyではAccess Tokenは返したくない(けどRFC 6749ではREQUIREDだから返さなければならない)というニーズはそこここであるので気持ちはわかります。多分、OAuth WGで新しいGrant Typeを作るのが良いのだと思います。ただ、現状では返却しなければならないので返却する、ということになっているのではないかと思います(←ここ、要確認)。では、Access Tokenはどこで使われるのかというと…これは後述します。
Public client / Confidential client
両方あります。
Public client
Token Endpoint Authenticationは:
none
で、PKCEを使います。
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
現在文書化されている例は:
client_secret_basic
です。
しかもconfidential clientでもPKCEを維持します6。
Discovery自体には、
client_secret_basic
client_secret_post
none
の3方式がadvertiseされています7。
ChatGPT plan usage: サブスクリプションを使ってOpenAIのモデルを使う
ChatGPT plan usage 用のアクセストークンの取得
さて、冒頭に述べたように、Signin with ChatGPTには”ChatGPT plan usage” というものがあります。これは、外部アプリがOpenAI Responses APIを呼び出すための権限を、ユーザーのChatGPT planからOAuthでdelegationするためのものです。これを使えば、当該外部アプリ(client)は、OpenAIのモデルを指定して様々なこと(toolを使ってWebを読んだりファイルを読み書きしたり、思考したり、その結果を出力したり)ができるようになります。
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ですので、
Responses API = OpenAIモデルを使ったagent executionの基本primitive
と理解するのが良いと思われます。
さて、このdelegationをするためにaccess tokenが必要なわけですが、SIWCではクライアントはAuthentication requestで以下のscopeを要求することによって取得します8。
openid
profile
email
offline_access
resource.invoke
chatgpt.tokens.use.direct
また、これだけでなく、
resource=https://api.openai.com/v1
もAuthorization RequestとToken Requestに付けなければいけません。
これは形としては RFC 8707 Resource Indicators for OAuth 2.0 9 です。RFC 8707は resourceに絶対URIで対象Resource Serverを指定する仕組みです。
したがって概念的には、
OpenAI Authorization Server
auth.openai.com
│
│ Access Token
▼
External OSS app
│
│ Bearer AT
▼
OpenAI Resource Server
api.openai.com/v1
となります。
Access Tokenの aud も、
"aud": "https://api.openai.com/v1"
です10。Userinfo Endpointではありません。
Access Tokenの例
OpenAIが公開しているpayloadは概念的にこうなっています。
{
"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
}
つまりAccess TokenもJWTです。
寿命は、
- Access Token: 1時間
- Refresh Token: 30日
- RefreshごとにRefresh Token rotation
- 新Refresh Tokenには再度30日のlifetime
です。
現時点の文書ではDPoP等のsender-constrainingは使われておらず、Responses APIには通常の
Authorization: Bearer <ACCESS_TOKEN>
として送ります11。
Responses APIでChatGPT subscriptionを消費する
例えば、
POST https://api.openai.com/v1/responses
Authorization: Bearer <SIWC_ACCESS_TOKEN>
Content-Type: application/json
{
"model": "...",
"input": [...],
"store": false,
"stream": true
}
です。
OpenAIはSIWC plan usageについて現在、
store: false
stream: true
を必須にしています 12。
つまりこれは通常のAPI keyをOAuth tokenに差し替えただけではありません。
Responses APIの一部機能にも制限があり、例えば現previewでは、
background- persistent
conversation previous_response_idover HTTP- hosted MCP/connectors
- image generation
- file search
- Code Interpreter
- native computer use
等が利用できません。13
したがって API subscriptionをOAuth化したものとも少し違います。
SIWC独自拡張
第4のclient登録方式: dynamic_agent_client
通常のOAuthならclientを事前登録するか、RFC 7591 Dynamic Client Registration Endpointを使います。OpenIDのコンテキストでは、最近ではOpenID Federationを使うというのもあります。
SIWCのOSS flowはそのどちらとも違います。
最初のAuthorization Requestで、
client_id=dynamic_agent_client
という特殊なpseudo-clientを使います。
さらに、
agent_name_hint
ext_agent_host_id
を付けます。14
例えば:
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
そしてcallbackが、
?code=...
&state=...
&client_id=oaiapp_xxxxx
となり、ここで正式なclient_idが発行されます15。要は、authorization request ど同時にclient regsitrationもやってしまう感じですね。
その後Token Endpointには、
dynamic_agent_client
ではなく、この新しく発行された
oaiapp_xxxxx
を送ります。
これはRFC 7591 Dynamic Client Registrationとは明確に異なります。
RFC 7591なら典型的には、
POST registration_endpoint
↓
client_id
client_secret...
です。
SIWC OSS flowは、
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です。
したがって、
user-mediated dynamic registration embedded into an Authorization Request
と見るのが適切です。
RFC 7591互換のDynamic Client Registrationとは呼ばない方がよいでしょう。
ext_agent_host_id
これも興味深いOpenAI extensionです。
OSS clientとは別に、
agent host
という概念があります。
例えば、
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"]というモデルです16。
host IDにはOpenAIは現在、
推奨
urn:ietf:params:oauth:jwk-thumbprint:...
RFC 9278 JWK Thumbprint URI
代替
urn:uuid:<uuid>
または
did:key:...
を認めています17
ただし極めて重要なのは、現時点では、
JWK Thumbprintを使ってもprivate key possessionをOpenAIは検証していない
という点です18
したがって、
JWK thumbprint host ID
≠ proof-of-possession
≠ DPoP
≠ client authentication
です。
現状は単なるstable host identifierです。
Native AppとしてはRFC 8252にかなり沿っている
OSS desktop/clientでは、
http://127.0.0.1:{port}/auth/callback
を使います。
localhost は使わず、IP literalの 127.0.0.1 を要求しています。ポート番号だけはsign-inごとに変更可能です19。
これはRFC 8252のLoopback Interface Redirectionと整合しています。RFC 8252自身も、
http://127.0.0.1:{port}/...
を定義し、native appでPKCEを使うことを要求しています。
Returning loginと id_token_hint
一度登録すると次回から、
client_id=<issued oaiapp_...>
ext_agent_host_id=...
id_token_hint=<previous ID Token>
login_hint=user@example.com
を使えます。
興味深いことに、OpenAIは以前の expired ID Tokenでも id_token_hint として使えると明記しています20。
これはOpenID Connect Core 1.0から外れているわけではありません。
OIDC Core自身、
id_token_hintはcurrent or past authenticated sessionを示すhint
であり、OPが発行したものであれば、exp を過ぎていてもrecent sessionだった場合は受け入れることを推奨しています。
したがってこの部分はかなりOIDCらしい実装です。
Discovery metadataには若干不整合がある
標準化の観点からは、現在一番気になる部分です。
Discovery documentの:
"scopes_supported": [
"openid",
"profile",
"email",
"offline_access"
]
には、
resource.invoke
chatgpt.tokens.use.direct
がありません。 OpenAI
しかし公式SIWC documentationは明確に、
offline_access
resource.invoke
chatgpt.tokens.use.direct
を要求しています21。
これは仕様上必ずしも致命的ではありませんが、
Discovery metadataだけからSIWC plan-usage capabilityを発見できない
ことになります。なので、追加したほうが良いでしょう。
同様に、
resource=https://api.openai.com/v1
をRFC 8707的に使っていますが、SIWC固有のplan usage capability discovery metadataはありません。
したがって現状は、
OIDC discovery
+
out-of-band OpenAI SIWC profile documentation
を両方読む必要があります。
ChatGPT Pluginの場合はOAuthが二重になる
ChatGPT pluginとの統合はさらに面白い構造です。
OpenAIの説明では、
ChatGPT
│
│ outer OAuth
▼
Plugin / external application
│
│ inner SIWC/OIDC
▼
OpenAI Authorization Server
です22。
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
によるSIWC。
Plugin側はOpenAI ID Tokenを検証してlocal accountを特定し、その後Outer OAuthを再開します23。
したがって、
SIWCはPlugin自身のOAuth Authorization Serverを置き換えるものではない
というのが重要です。
Identity federationのinner layerとして入ります。
IdentityとAuthorizationは意図的に分離されている
全体を整理すると:
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だけでは、
- ChatGPT conversations
- memory
- files
- billing data
- API key
などは渡りません。 OpenAI Help Center
また chatgpt.tokens.use.direct がなければ、有効なID Tokenを取得していてもChatGPT planを使ったinferenceはできません。 OpenAI Developers
このseparationは設計上かなり重要です。
セキュリティ面で見ると
現時点のprofileをOAuth/OIDCセキュリティの観点から整理すると、
| 項目 | SIWC |
|---|---|
| Authorization Code | ○ |
| PKCE S256 | ○ / 実質必須 |
state | ○ |
OIDC nonce | ○ |
| Exact redirect URI | ○ |
| Native app external browser | ○ |
| Loopback redirect | ○ |
| refresh rotation | ○ |
RFC 8707 style resource | ○ |
| Sender-constrained AT | 文書上なし |
| DPoP | 文書上なし |
| mTLS | 文書上なし |
| PAR | Discovery上なし |
| JAR | request unsupported |
Pairwise sub | なし、publicのみ |
| Dynamic registration | OpenAI独自方式 |
Discoveryではさらに、
"request_uri_parameter_supported": false,
"request_parameter_supported": false
なのでJAR/request object系は現在使いません。これは、現状の https://auth.openai.com/.well-known/openid-configuration から見て取ることができます。
特に注目すべき設計上のポイント
私なら標準化の観点では次の4点を特に見ます。
① 「Sign-in」と「AI entitlement」の分離
これは良い設計です。
authentication != authorization != subscription entitlement
が比較的はっきりしています。
② ChatGPT subscriptionがOAuth Resource Accessになる
chatgpt.tokens.use.direct は単なるAPI scopeではなく、実質、
「このChatGPT subscriberの契約枠をこのclientから消費してよい」
というdelegationです。
従来のOAuthが想定していた「user data/API action」から、economic entitlement delegation にscopeの意味が広がっています。
これはAgentic Paymentsやdelegated authorityの観点でもかなり興味深いです。
③ client registrationがuser-bound
OSS flowではissued client_id が、
user + selected workspace
にbindされています24
これは従来の、
client_id = software application/deployment
というOAuthモデルとはかなり違います。
むしろ、
client_id ≈ user-authorized agent registration
です。
④ Host identityをOAuthに追加している
さらに、
client
user
workspace
host
を別々に扱っています。
これはAgentic AIで今後重要になる、
Principal
Agent
Client
Runtime
Device/Host
のidentity separationにかなり近い構造です。
一方、気になる点もある
プロトコル設計としては、この部分です。
User
│
│ owns
▼
ChatGPT subscription
│
│ delegates entitlement
▼
Client
│
│ runs on
▼
Agent Host
│
│ Bearer AT
▼
Responses Resource Server
ところが現在、
ext_agent_host_id
は存在するものの、host private key possessionは検証されません。
したがって現在のhost identificationは、
identification
であって、
cryptographic binding
ではありません25。
さらにAccess TokenはBearerです。
高価値の作業を指せる場合には将来的にここを、
JKT / DPoP / attested key
等でbindする余地は非常に大きいと思います。FAPI化ですね。
まとめ
Sign in with ChatGPTはOIDCとしてはかなり素直です。
OIDC Authorization Code
+ PKCE S256
+ nonce
+ public sub
+ standard ID Token validation
その上にOpenAI独自profileとして、
dynamic_agent_client
agent_name_hint
ext_agent_host_id
resource.invoke
chatgpt.tokens.use.direct
を載せ、
ChatGPT subscription entitlement
↓ OAuth delegation
Responses API
を実現しています。
特に重要なのは、これは単なる「Sign in with GoogleのChatGPT版」ではないという点です。Identity Provider + subscriber entitlement authorization + agent/client/host registration system の組合せになっています。
標準化的には、RFC 8707 / RFC 8252 / OpenID Connect Coreにかなり乗りながら、Dynamic Client Registrationとagent-host bindingだけ独自拡張していると整理すると理解しやすいです。
脚注
- OpenAI, DevDay 2026 の振り返り
- OpenAI OIDC Discovery Document
- OpenAI Developers
- OpenAI Developers: On your website
- 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
- OpenAI Developers – Signin with ChatGPT – On your website
- OpenAI
- OpenAI Developers: Registrations and signin
- RFC 8707: Resource Indicators for OAuth 2.0 | RFC Editor
- OpenAI Developers
- OpenAI Developers – Signin with ChatGPT – Models and inference
- OpenAI Developers – Signin with ChatGPT – Models and inference
- OpenAI Developers – Sign in with ChatGPT – Preview limitations
- OpenAI Developers: Registration and sign-in
- OpenAI Developers – Sign in with ChatGPT – Registration and sign-in
- OpenAI Developers-Sigin in with ChatGPT-Overview
- OpenAI Developers
- OpenAI Developers – Sign in with ChatGPT – Overview
- OpenAI Developers – Signin with ChatGPT – Registration and sign-in
- OpenAI Developers-SIWC-Registration and sign-in
- OpenAI Developers – Signin with ChatGPT – Registration and sign-in
- OpenAI Developers – In your ChatGPT plugin
- OpenAI Developers – Sign in with ChatGPT – In your ChatGPT plugin
- OpenAI Developers – Signin with ChatGPT – Overview
- OpenAI Developers: SIWC – Overview
