[CP-768] feat(auth): add login with endpoint-inferred Auth0 issuer by qdrant-cloud-bot · Pull Request #219 · qdrant/qcloud-cli · GitHub
Skip to content

[CP-768] feat(auth): add login with endpoint-inferred Auth0 issuer - #219

Open
qdrant-cloud-bot wants to merge 11 commits into
mainfrom
feat/oauth-auth-login
Open

qdrant-cloud-bot wants to merge 11 commits into
mainfrom
feat/oauth-auth-login

Conversation

@qdrant-cloud-bot

@qdrant-cloud-bot qdrant-cloud-bot commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Add qcloud auth discover|login|logout|status|token.
  • Login URL is not a new config field: it comes from QDRANT_CLOUD_ENDPOINT / --endpoint (grpc.<cluster>.qdrant.io → login.<cluster>.qdrant.io).
  • Prefer the gateway’s unauthenticated RFC 9728 document at https://api.<cluster>.qdrant.io/.well-known/oauth-protected-resource when OAuth is enabled; fall back to hostname inference when it is not.
  • Browser PKCE loopback (default) and --device. The loopback listener uses the first free port of 48271, 48272 and 48273: Auth0 matches a loopback callback's port exactly (a random port gets "Callback URL mismatch"), so the three http://127.0.0.1:<port>/callback URLs are registered on the CLI's Auth0 application. tokens in credentials.yaml (0600). API keys still win when set. gRPC sends Authorization: Bearer after login.
Env Endpoint Inferred login
development grpc.development-cloud.qdrant.io:443 https://login.development-cloud.qdrant.io/
staging grpc.staging-cloud.qdrant.io:443 https://login.staging-cloud.qdrant.io/
production grpc.cloud.qdrant.io:443 https://login.cloud.qdrant.io/

The "Qdrant Cloud CLI" client id is built in per login URL (internal/oauth/clientid.go): each Auth0 tenant generates its own, and a native app's id is public. Development is set; staging and production are TBD until their apps exist, and ask for --client-id / QDRANT_CLOUD_OAUTH_CLIENT_ID meanwhile. qcloud auth discover needs no client id.

Test plan

  • qcloud auth discover --endpoint grpc.development-cloud.qdrant.io:443 (inference when PRM is down)
  • Unit tests for PRM override, login token store, Bearer interceptor
  • golangci-lint + go test on affected packages
  • Once OAuth is enabled on development: qcloud auth login --endpoint grpc.development-cloud.qdrant.io:443 (no --client-id)
  • After api-gw OAuth is on: discover should report source protected-resource metadata

Discover the login URL from QDRANT_CLOUD_ENDPOINT (grpc.<cluster> →
login.<cluster>), preferring unauthenticated API gateway protected-resource
metadata when OAuth is enabled.
@qdrant-cloud-bot
qdrant-cloud-bot requested a review from a team October 10, 2026 06:34
@qdrant-cloud-bot
qdrant-cloud-bot requested a review from a team as a code owner October 10, 2026 06:34
Comment thread docs/reference/qcloud.md
Comment thread docs/reference/qcloud_auth.md Outdated
Comment thread docs/reference/qcloud_auth.md Outdated
Comment thread docs/reference/qcloud_auth.md Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No mention of Auth0

Comment thread docs/reference/qcloud_auth.md Outdated
Present browser login and API keys as alternatives, drop Auth0 and non-prod hosts from generated help.
@qdrant-cloud-bot qdrant-cloud-bot changed the title feat(auth): add login with endpoint-inferred Auth0 issuer [CP-768] feat(auth): add login with endpoint-inferred Auth0 issuer Oct 12, 2026
qdrant-cloud-bot and others added 8 commits October 19, 2026 11:04
* [CP-768] fix(auth): send audience on device-code login

Auth0 does not apply the resource parameter on /oauth/device/code, so that request must use audience. The poll stays a plain device-code grant, backs off on slow_down, and the loopback callback checks iss when Auth0 sends it.

* test(auth): keep require out of http handlers in device login test

golangci-lint (testifylint go-require, wsl_v5) flagged the device-login test.
A form parse error now returns 400 from the handler, which still fails the login.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Robert-Stam <robert.stam@qdrant.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Auth0 matches a loopback callback's port exactly, so a random port fails
with Callback URL mismatch. Try 48271, 48272 and 48273 in order; each is
registered on the CLI's Auth0 application.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Each Auth0 tenant generates its own client id for the native app, and a
native app's id is public, so ship them keyed by issuer: users no longer
pass --client-id. Development is set; staging and production are TBD
until their apps exist, and ask for --client-id meanwhile.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A self-contained page (inline Qdrant mark and terminal icon, no fonts,
scripts or other requests, light and dark) for success and failure,
instead of plain text. The failure detail is HTML-escaped; strict CSP.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ogin

Same grid background, wordmark above a white card, title and tiles as
the Auth0 Universal Login pages. Still self-contained: the grid image
and logos are inline, the system font replaces the web font.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… was not used

On development, discover fell back to endpoint inference while curl got
the metadata; the reason was swallowed.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ail_verified

iam-service's ExchangeToken requires email_verified in the Auth0 access
token. The custom-token-claims Action sets it, but Auth0 silently drops
it: email_verified is a reserved OpenID Connect claim name. With the
email scope Auth0 adds it itself, as for the Cloud console. Found on
development: invalid_grant: email not verified in JWT payload.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

This branch has not been deployed

No deployments
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.

2 participants