Repository navigation
[Feature]: add least-privilege GET /v1/catalog for remote Codex clients #809
Description
Area
Authentication / catalog distribution / remote clients
Goal
Allow a remote Codex client to download OpenCodex's generated Codex model catalog using the same least-privilege credential class it already uses for inference.
The client must not need the management credential merely to obtain model metadata.
This is primarily needed for centrally hosted and multi-machine deployments such as #95.
Current state
OpenCodex already exposes the generated catalog through:
GET /api/catalog
but that endpoint is intentionally part of the management plane.
The management credential can also access sensitive administrative operations such as:
- provider configuration;
- OAuth/account management;
- server settings;
- management mutations;
- proxy shutdown.
Giving that credential to every remote inference client violates least privilege.
The accepted implementation direction is therefore not to weaken admission for /api/catalog.
Instead, add a separate read-only data-plane catalog route.
Accepted route
Add:
GET /v1/catalog
with optional:
HEAD /v1/catalog
using the existing data-plane authentication boundary.
A client that can already call:
POST /v1/responses
should be able to fetch:
GET /v1/catalog
using the same data-plane credential.
That credential must continue to receive 401 / denial for management routes.
Security boundary
The /api/* management namespace remains unchanged.
Do not add a special case such as:
data-plane token
-> allowed through /api/catalog
The desired separation is:
Data plane
/v1/responses
/v1/chat/completions
/v1/messages
/v1/models
/v1/catalog
Management plane
/api/*
A data-plane credential that can read /v1/catalog must still be unable to access, for example:
GET /api/config
GET /api/providers
POST /api/oauth/login
POST /api/codex-auth/login
POST /api/stop
or any other management-only route.
Payload contract
GET /v1/catalog should reuse the same authoritative generated catalog payload and sanitization/redaction rules as:
GET /api/catalog
Do not create an independently generated second catalog.
The two routes should expose equivalent catalog content subject only to differences that are intentionally specific to their transport/auth surface.
The data-plane response must not expose:
- provider API keys;
- OAuth credentials;
- management tokens;
- account identifiers;
- raw provider configuration;
- internal filesystem paths;
- other management-only state.
Method restrictions
The data-plane catalog surface is read-only.
Allowed:
GET
HEAD
Not allowed:
POST
PUT
PATCH
DELETE
No catalog mutation API should be introduced under /v1.
Response behavior
Preserve the useful catalog-distribution metadata already provided by the management route where applicable, including:
- bounded response size;
- content type;
- cache-related headers;
- version/skew metadata;
- deterministic errors when the catalog cannot be materialized.
If the existing management route exposes a Codex-version header, preserve that contract where the corresponding information is available.
Do not fabricate a version when the proxy has no authoritative runtime version.
Remote-client workflow
A centrally hosted OpenCodex deployment should support:
curl -fsS \
-H "x-opencodex-api-key: $DATA_PLANE_KEY" \
https://proxy.example.com/v1/catalog \
> "${CODEX_HOME:-$HOME/.codex}/opencodex-catalog.json"The same credential can then be used for inference:
curl -fsS \
-H "x-opencodex-api-key: $DATA_PLANE_KEY" \
https://proxy.example.com/v1/responses \
...while the management credential remains only on the operator's trusted machine.
Admission tests
Regression coverage must prove both halves of the boundary.
Positive
A valid data-plane credential can:
GET /v1/catalog
HEAD /v1/catalog
and receives the expected generated catalog metadata.
Negative
The same credential cannot access:
/api/*
including representative reads and mutations.
Also verify that:
- missing credentials fail when data-plane auth is required;
- invalid credentials fail;
- management-only credentials do not accidentally redefine the data-plane contract unless already intentionally accepted there;
- unsupported methods against
/v1/catalogare rejected.
Catalog parity
Tests should establish that the data-plane route and management route consume the same catalog authority.
A change to catalog generation should not require maintaining two independent serialization implementations.
Relevant properties include:
- model entries;
- reasoning metadata;
- context metadata;
- routed aliases;
- ownership fields;
- sanitization;
- response bounds.
Documentation
Update the credential/surface documentation so the boundary is explicit.
The credential table should reflect conceptually:
| Credential class | Allowed surface |
|---|---|
| Data plane | inference endpoints plus read-only /v1/models and /v1/catalog |
| Management plane | /api/* |
| GUI session | management API only, subject to GUI-session restrictions |
Also document the multi-machine catalog-download workflow.
Relationship to #709
#709 implemented the generated catalog read on the management surface.
This issue does not replace or remove:
GET /api/catalog
The management route remains useful for the Dashboard/operator surface.
This issue adds the least-privilege remote-client projection of that same catalog.
Relationship to #95
#95 tracks the broader centrally hosted / multi-user OpenCodex deployment.
This issue addresses one concrete blocker from that deployment model:
remote clients need the Codex catalog
without receiving management privileges
It does not attempt to solve the rest of #95.
Out of scope
This issue does not require:
- exposing
models_cache.json; - moving the management API under
/v1; - granting data-plane credentials general
/api/*access; - remote provider configuration;
- remote OAuth management;
- distributing management credentials to client machines;
- introducing a second catalog-generation implementation.
Acceptance criteria
-
GET /api/catalogexists on the management plane. - Maintainer-approved architecture uses a separate data-plane route rather than weakening
/api/*authentication. -
GET /v1/catalogexists. -
HEAD /v1/catalogis supported if consistent with the existing read surface. - Existing data-plane credentials can read the route.
- Catalog content comes from the same authoritative generator/payload contract as
/api/catalog. - No credentials, provider configuration, or management-only state are exposed.
- Non-read methods are rejected.
- A data-plane credential still cannot access any
/api/*route. - Positive and negative admission tests cover the credential boundary.
- Response size/cache/version behavior remains bounded and documented.
- Credential/surface documentation is updated.
- Remote/multi-machine catalog-download workflow is documented.
- Accepted implementation is merged into
dev.
Related
- Serve the generated Codex model catalog over the management API for remote clients #709 — management-plane generated catalog endpoint.
- [Roadmap] Centrally hosted multi-user OpenCodex with tenant isolation #95 — centrally hosted / multi-machine OpenCodex use case.
Activity
github-actions commentedon Jul 31, 2026
Automated translation bookkeeping — detected language: English.
Ingwannu commentedon Aug 1, 2026
Accepted. The least-privilege use case is valid, but we should not carve a data-token exception into the /api/* management prefix.
The implementation direction is a separate read-only data-plane route (for example GET /v1/catalog) protected by the existing data-plane admission helper. It should reuse the same generated catalog payload and redaction rules as GET /api/catalog, remain GET/HEAD only, expose no configuration or credentials, retain response size/cache/version headers, and include negative tests proving the credential still cannot access any /api/* route or mutation.
Please open the PR against dev with that route split and update the credential table in structure/05_gui-and-management-api.md plus the public reference docs.
Wibias commentedon Aug 8, 2026
Parent use case: #95
This issue tracks the least-privilege catalog-distribution gap that remains for centrally hosted / multi-machine OpenCodex deployments.
[-]Follow-up to #709: let a client credential read GET /api/catalog without management privileges[/-][+][Feature]: add least-privilege GET /v1/catalog for remote Codex clients[/+]LeoWang331 commentedon Aug 12, 2026
I'm working on a narrowly scoped implementation of the accepted data-plane /v1/catalog design. I'll open a dev-targeted draft PR after the first reviewable, green vertical slice so progress and scope are visible.
lidge-jun commentedon Aug 19, 2026
리뷰 · 우선순위 66 / 80
현재
dev에서 생성된 카탈로그를 받는 HTTP 경로는GET /api/catalog뿐입니다.src/server/management/model-routes.ts에 있고 관리 평면입니다./v1/catalog는 소스에서 검색되지 않습니다. 원격 Codex 클라이언트가 모델 메타데이터를 받으려면 관리 자격 증명이 필요하고, 그 자격 증명은 설정·OAuth·종료까지 엽니다.이슈가 원하는 것은 추론과 같은 데이터 플레인 자격 증명으로 읽기 전용 카탈로그를 받는 것입니다. 수락된 방향은
/api/catalog입장을 느슨하게 하는 예외가 아니라GET /v1/catalog(선택적 HEAD)입니다. 데이터 플레인 토큰은/api/config,/api/providers, OAuth 로그인,/api/stop에서 계속 401이어야 합니다. #95의 중앙 호스팅에서 이 경계가 깨지면 테넌트 격리가 시작도 못 합니다.네이티브 신뢰성보다 위생과 원격/서비스 배포가 점수입니다. 페이로드는
/api/catalog와 같은 생성본·레드액션을 재사용해야 합니다. 두 번째 카탈로그를 만들면 모델 목록이 갈라집니다. 키, OAuth, 관리 토큰이 데이터 플레인 응답에 나오면 안 됩니다.LeoWang331이 좁은 슬라이스를 작업 중이라고 했으니, 그 PR은 입장 헬퍼 재사용, GET/HEAD만, 관리 경로 부정 테스트가 있어야 합니다. Windows 원격 클라이언트와 리버스 프록시 뒤에서 같은 데이터 플레인 헤더가 동작해야 합니다.
해결방안은 기존 카탈로그 직렬화를
/v1/catalog에 붙이고, 데이터 플레인 입장만 쓰며,/api/*는 그대로 두는 것입니다. 패치는 추측하지 않으며, 현재 트리에 데이터 플레인 카탈로그 라우트는 없습니다.이 댓글은 grok-bot이 작성했습니다
docs: point remote catalog fetch at the data-plane /v1/catalog route
4 remaining items
fix(remote): reconcile the phase-one catalog contract with the landed…
fix(remote): reconcile the phase-one catalog contract with the landed…
feat(server): serve the hub's provider, login and roster state on the…
feat(client): read hub state over the data plane, and never degrade t…
feat(server): serve the hub's provider, login and roster state on the…
feat(client): read hub state over the data plane, and never degrade t…
feat(server): serve the hub's provider, login and roster state on the…
feat(client): read hub state over the data plane, and never degrade t…
feat(server): add least-privilege GET /v1/catalog for remote Codex cl…
fix(remote): reconcile the phase-one catalog contract with the landed…
feat(server): add least-privilege GET /v1/catalog for remote Codex cl…
fix(remote): reconcile the phase-one catalog contract with the landed…
feat(server): serve the hub's provider, login and roster state on the…
feat(client): read hub state over the data plane, and never degrade t…