You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs-site/src/content/_docs-contract.md
+7-4Lines changed: 7 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -16,7 +16,7 @@ Use only these hosts in public examples:
16
16
-`https://codex-pooler.example.com`, for deployed product examples
17
17
-`https://docs.codex-pooler.com`, for the public docs site canonical URL
18
18
19
-
Do not use private hostnames, cluster names, pod names, tenant names, real account identifiers, real repository evidence paths, or private service URLs in public docs.
19
+
Do not use private hostnames, cluster names, pod names, tenant names, real account identifiers, raw OpenAI user subjects, real repository evidence paths, or private service URLs in public docs.
20
20
21
21
## Route Vocabulary
22
22
@@ -99,6 +99,7 @@ Allowed public claims:
99
99
-`upstream`: A Codex account identity or assignment that Codex Pooler can route eligible work to
100
100
-`Pool API key`: A bearer credential used by runtime clients for `/backend-api` and `/v1` requests. It represents a Pool, not one upstream account
101
101
-`MCP token`: An operator-owned bearer credential used only for `/mcp`. It is separate from Pool API keys and browser sessions
102
+
-`subject reference`: A sanitized fingerprint of an upstream OpenAI user subject. Public docs may describe this reference, but must never include raw subject values
102
103
-`backend API`: The Codex backend compatibility surface rooted at `/backend-api`, especially `/backend-api/codex/*`
103
104
-`/v1`: The narrow OpenAI-compatible SDK surface rooted at `/v1`. It is compatibility over Codex routing, not full OpenAI parity
104
105
-`metadata-only logging`: Request, route, accounting, audit, and MCP records may keep identifiers, route names, counts, statuses, timings, model names, safe error codes, and sanitized summaries. They must not store or show raw payloads or credentials
@@ -114,7 +115,7 @@ Use placeholders that are clearly fake and generic:
114
115
- Email-like examples: `operator@example.com`
115
116
- Model ids: use documented sample ids only when the surrounding page explains that the Pool must expose them
116
117
117
-
Never include raw tokens, raw prompts, request bodies, response bodies, file bodies, audio bodies, image bodies, cookies, `auth.json`, access tokens, refresh tokens, raw idempotency keys, raw upload URLs, internal evidence snippets, internal logs, private hostnames, real account ids, or real user identifiers.
118
+
Never include raw tokens, raw prompts, request bodies, response bodies, file bodies, audio bodies, image bodies, cookies, `auth.json`, access tokens, refresh tokens, raw idempotency keys, raw upload URLs, internal evidence snippets, internal logs, private hostnames, callback URLs, real account ids, raw OpenAI user subjects, or real user identifiers.
118
119
119
120
If a docs example needs an Authorization header, write `Authorization: Bearer <pool-api-key>` for runtime routes or `Authorization: Bearer <operator-mcp-token>` for `/mcp`.
120
121
@@ -142,6 +143,7 @@ Safe fields to mention:
142
143
- HTTP method and status class
143
144
- Pool label or placeholder
144
145
- Upstream label or placeholder
146
+
- Sanitized upstream subject reference or fingerprint
@@ -151,7 +153,7 @@ Forbidden fields and examples:
151
153
- Raw prompts and completions
152
154
- Request bodies, response bodies, multipart bodies, websocket frames, file bytes, audio bytes, image bytes, data URLs, and transcripts
153
155
- Bearer tokens, Pool API keys, MCP tokens, cookies, access tokens, refresh tokens, `auth.json`, TOTP secrets, SMTP secrets, signing secrets, and raw idempotency keys
154
-
- Internal incident procedures, cluster names, pod names, private hostnames, real account identifiers, raw emails, and private IP addresses
156
+
- Internal incident procedures, cluster names, pod names, private hostnames, real account identifiers, raw OpenAI user subjects, raw emails, and private IP addresses
155
157
156
158
## Source Map For Public Route Claims
157
159
@@ -167,6 +169,7 @@ Use these tracked sources as the source of truth for public route claims. Do not
| Realtime exclusion |`lib/codex_pooler_web/router.ex`, `test/support/compatibility_matrix.ex`, `test/codex_pooler_web/route_surface_test.exs`, `test/codex_pooler_web/controllers/v1/route_auth_test.exs`|`/v1/realtime` and OpenAI Realtime SDK websocket or session routes are not supported |
169
171
| MCP endpoint |`lib/codex_pooler_web/router.ex`, `test/codex_pooler_web/route_surface_test.exs`, `test/codex_pooler_web/controllers/mcp_contract_test.exs`, `test/codex_pooler_web/controllers/mcp_controller_test.exs`|`/mcp` is a root metadata-only, read-only operator endpoint using operator MCP bearer tokens, not Pool API keys or browser sessions |
172
+
| Upstream identity linking |`lib/codex_pooler/upstreams/lifecycle/identity_lifecycle.ex`, `lib/codex_pooler/upstreams/token_linking.ex`, `lib/codex_pooler/upstreams/auth/codex_auth.ex`, `lib/codex_pooler/upstreams/auth/codex_auth_json.ex`, `lib/codex_pooler_web/live/admin/read_models/upstream_accounts_read_model.ex`, `lib/codex_pooler_web/live/admin/read_models/upstream_cockpit_read_model.ex`, `test/codex_pooler/upstreams/oauth_browser_linking_test.exs`, `test/codex_pooler/upstreams/oauth_device_linking_test.exs`, `test/codex_pooler/upstreams/oauth_relink_test.exs`, `test/codex_pooler/upstreams_test.exs`, `test/codex_pooler_web/live/admin/pages/upstreams_live_test.exs`, `test/codex_pooler_web/live/admin/pages/upstream_cockpit_live_test.exs`| OAuth links, relinks, and auth.json imports can use an OpenAI user subject, when returned, to separate same-account and same-workspace upstream credentials. Public docs may mention only sanitized subject references or fingerprints, never raw subjects |
170
173
| Privacy and redaction |`README.md`, `test/codex_pooler_web/controllers/runtime/compatibility_contract_test.exs`, `test/codex_pooler_web/controllers/mcp_contract_test.exs`, `test/codex_pooler_web/controllers/mcp_controller_test.exs`| Public docs must keep prompts, bodies, bearer tokens, cookies, `auth.json`, upstream secrets, and private identifiers out of examples and evidence |
171
174
172
175
## Author Checklist
@@ -178,5 +181,5 @@ Before publishing or editing a public page:
178
181
3. Include narrow `/v1` compatibility language when mentioning OpenAI SDKs
Copy file name to clipboardExpand all lines: docs-site/src/content/docs/operators/upstreams.mdx
+21-11Lines changed: 21 additions & 11 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -14,7 +14,7 @@ Use this page when you need to answer:
14
14
5. how recent token usage compares with observed quota windows
15
15
6. which account actions are available without exposing raw credentials
16
16
17
-
The page is metadata-only after linking or import. It shows operator labels, workspace and plan badges, safe status labels, quota-window evidence, token counters, assignment counts, and links to related logs. It does not show prompts, responses, files, websocket frames, bearer tokens, refresh tokens, provider cookies, OAuth provider payloads, or stored Codex `auth.json` contents.
17
+
The page is metadata-only after linking or import. It shows operator labels, workspace and plan badges, safe status labels, quota-window evidence, token counters, assignment counts, sanitized subject references when needed, and links to related logs. It does not show prompts, responses, files, websocket frames, bearer tokens, refresh tokens, provider cookies, OAuth provider payloads, raw OpenAI user subjects, or stored Codex `auth.json` contents.
@@ -167,6 +167,8 @@ The upload accepts small auth files only. The current UI states a 64 KB limit.
167
167
168
168
After import, Codex Pooler becomes the refresh-token authority for that account lineage. Do not keep using the same `auth.json` from another Codex install, machine, or automation. Provider refresh-token rotation can invalidate one copy and move the account into `reauth_required`.
The dialog footer keeps docs on the left and the submit actions on the right. `Cancel` closes without importing. `Import auth.json` stores the credential material through encrypted upstream secret storage.
171
173
172
174
## OpenAI OAuth Upstream Linking
@@ -175,28 +177,36 @@ OpenAI OAuth upstream linking is an authenticated admin workflow. Use
175
177
`OAuth` on `/admin/upstreams` to link a new OpenAI upstream account to a selected Pool. Use
176
178
`/admin/upstreams/:id` to relink or reconnect the exact upstream identity shown
177
179
in the cockpit. Relink checks the returned account and workspace claims against
178
-
the target identity before replacing encrypted credential material.
180
+
the target identity before replacing encrypted credential material. When OpenAI
181
+
returns a user subject, Codex Pooler also uses that subject to keep same-account,
182
+
same-workspace upstream credentials distinct.
183
+
184
+
Browser account choice is controlled by the active OpenAI or Google browser
185
+
session. Codex Pooler can start the authorization flow, but it cannot force the
186
+
provider account chooser by itself. Sign in to the intended provider account, or
187
+
use a separate browser profile, before completing the link or relink.
179
188
180
189
The browser manual callback workflow is:
181
190
182
191
1. open the OAuth link or relink dialog
183
192
2. choose `Browser`
184
193
3. open the generated OpenAI authorization URL
185
194
4. complete OpenAI authorization in the browser
186
-
5. paste the resulting local callback URL back into the admin dialog
195
+
5. paste the resulting returned browser URL back into the admin dialog
187
196
6. submit the callback form and wait for the success or safe error state
188
197
7. use `Close` after the dialog reports that the account was linked or relinked
189
198
190
-
The local callback URL is consumed only by the already-authenticated admin page,
191
-
and there is no hosted OAuth callback route, no public `/auth/callback`, and no
199
+
The returned browser URL is consumed only by the already-authenticated admin page,
200
+
and there is no hosted OAuth callback route, no public callback endpoint, and no
192
201
`/api/admin/*` or dashboard JSON API for this workflow.
193
202
194
203
Use the device-code fallback when browser authorization is not practical. The
195
204
dialog shows the user code and verification URL while the flow is pending, and
196
205
the page polls only while the operator keeps the dialog open. Device-code
197
-
authorization must be enabled for Codex on the OpenAI account or workspace. If
198
-
device authorization is unavailable or denied, use the browser workflow or ask
199
-
the workspace admin to enable Codex device-code login.
206
+
authorization must be enabled for Codex on the OpenAI account or workspace. It
207
+
may be unavailable or denied by account or workspace policy. If device
208
+
authorization is unavailable or denied, use the browser workflow or ask the
209
+
workspace admin to enable Codex device-code login.
200
210
201
211
Immediately after a successful link, the new account is not guaranteed to route
202
212
traffic. Codex Pooler creates the initial Pool assignment and enqueues account
@@ -206,7 +216,7 @@ before any user request is routed, and runtime routing excludes it until token
206
216
refresh succeeds or the credentials are relinked.
207
217
208
218
Operators should never paste callback URLs, authorization codes, tokens, cookies,
209
-
raw auth.json, OpenAI provider payloads, or local credential files into docs,
219
+
returned browser URLs, raw auth.json, OpenAI provider payloads, raw user subjects, or local credential files into docs,
210
220
tickets, logs, or evidence. The admin UI may show the one-time authorization URL
211
221
or device user code during a pending flow, but persisted flow summaries, audit
212
222
metadata, request logs, tests, and docs stay metadata-only.
<td>Relink with the same OpenAI accountand workspace shown in the cockpit.</td>
280
+
<td>Relink with the same OpenAI account, workspace, and sanitized subject reference shown in the cockpit. If a different person in the same workspace should be added, link or import that user lineage as a separate upstream identity.</td>
0 commit comments