Skip to content

feat(api): drop OAuth device-flow endpoints + schemas from spec#531

Merged
DorianZheng merged 1 commit into
mainfrom
feat/spec-drop-oauth-endpoints
May 15, 2026
Merged

feat(api): drop OAuth device-flow endpoints + schemas from spec#531
DorianZheng merged 1 commit into
mainfrom
feat/spec-drop-oauth-endpoints

Conversation

@DorianZheng

Copy link
Copy Markdown
Member

Summary

PR #527 added /v1/oauth/device_code, /v1/oauth/token, /v1/oauth/revoke endpoints + their request/response schemas to the spec. On review, those spec entries are redundant and contract-drifting — this PR removes them.

Why

No code consumers in the BoxLite tree read OAuth schemas from the spec:

Caller Reads OAuth schemas?
Python SDK (PyBoxliteRestOptions) No — only api_key exposed
Node SDK (JsBoxliteRestOptions) No — only apiKey exposed
Go / C SDK No — no REST surface at all
Rust SDK (refresh_oauth()) No — hand-coded RFC 8628 forms
CLI (commands::auth::device::login()) No — hand-coded RFC 8628 forms

Industry alignment — none of these put OAuth in their spec: Stripe, GitHub, DigitalOcean, Anthropic, OpenAI. Only identity-provider products (Auth0, Okta) co-locate. Their business is auth; ours isn't.

Two sources of truth. The wire format is fully defined by IETF RFCs:

  • RFC 8628 §3.1 — device authorization request/response
  • RFC 6749 §4.4 / §6 — token exchange + refresh
  • RFC 7009 — token revocation

Restating in OpenAPI adds maintenance churn with no precision gain.

Contract-drift fix. PR #530's BoxliteOAuthController in apps/api returns 503 temporarily_unavailable on every /v1/oauth/* route because the real OAuth server isn't built. With the endpoints out of the spec, the gateway no longer promises something it can't deliver. (PR #530 has been amended in parallel to drop that controller too — see commit 673d7550.) When the @node-oauth/node-oauth2-server backend lands, that work will add both the controller and the spec paths in one coherent commit.

What stays

  • Single BearerAuth security scheme (with the four-token-source description)
  • GET /v1/me and Principal schema
  • info.description note explaining the CLI's two paths (API key vs --web device flow) and pointing readers at the IETF RFCs for the wire format
  • Server-side RFC 8628 implementations (Axum reference server, Python reference server) — they remain in PR feat(server): device flow stubs (Axum + Python) + NestJS controllers #530 for local-dev testing of boxlite auth login --web

Test plan

  • python3 -c "import yaml; yaml.safe_load(open('openapi/rest-sandbox-open-api.yaml'))" passes
  • Spec contains no /oauth/* paths, no OAuth schemas (schema count: 30 → schemas with oauth: [])
  • CI spec lint clean
  • CLI end-to-end against Axum reference server still works (boxlite serve + boxlite auth login --web --url http://localhost:8080)

PR #527 added /v1/oauth/device_code, /v1/oauth/token, /v1/oauth/revoke
endpoints + their request/response schemas to the spec. On review, those
spec entries turn out to be redundant and contract-drifting:

Zero code consumers in the BoxLite tree read the OAuth schemas:
- Python/Node SDKs expose only api_key (PyBoxliteRestOptions /
  JsBoxliteRestOptions). Go/C SDKs have no REST surface at all.
- The Rust SDK's refresh_oauth() in src/boxlite/src/rest/client.rs
  posts hand-coded RFC 8628 forms — never reads the spec.
- The CLI's commands::auth::device::login() hand-codes RFC 8628 forms.

Industry alignment — none of these put OAuth endpoints in their spec:
Stripe, GitHub, DigitalOcean, Anthropic, OpenAI. Only identity-provider
products (Auth0, Okta) co-locate. Their business is auth; ours isn't.

The wire format is fully defined by published IETF RFCs:
  - RFC 8628 §3.1 — device authorization request/response
  - RFC 6749 §4.4 / §6 — token exchange + refresh
  - RFC 7009         — token revocation

Restating those in OpenAPI adds maintenance churn with no precision
gain — implementers follow the RFC either way.

Contract-drift fix: PR #530's BoxliteOAuthController in apps/api returns
503 temporarily_unavailable on every /v1/oauth/* route because the real
OAuth server isn't built. With the endpoints out of the spec, the
gateway no longer promises something it can't deliver. When the
@node-oauth/node-oauth2-server backend lands, that work will add both
the controller and the spec paths in one coherent commit.

Spec changes:
- Remove /v1/oauth/device_code, /v1/oauth/token, /v1/oauth/revoke paths
- Remove DeviceAuthorizationRequest/Response, OAuthTokenRequest/Response,
  OAuthRevokeRequest, OAuthError schemas
- Update info.description to point at the IETF RFCs for the wire format
- BearerAuth.description: keep the four-token-source list; soften
  blo_/blr_ prefix descriptions to reference the RFCs not specific paths
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant