Repository navigation
fix(provider): ask for an OAuth client ID when Coral cannot register one - #2580
Merged
Merged
Conversation
createProvider accepted an OAuth configuration that named no client for a service without Dynamic Client Registration or a Client ID Metadata Document, and for device authorization. It returned needs_sign_in, and the person's sign-in then failed with "Coral is not available." It now refuses the call at `authentication.client` and ends the Setup it prepared. Reef sends a Setup an older Coral confirmed that way back to configuration, disables the sign-in button, and shows Reef's own reason for a 400 or 409 instead of saying Coral is unavailable.
iaptsiauri
force-pushed
the
fix/reef-oauth-signin-without-application
branch
from
October 21, 2026 12:26
7ef7c43 to
ca8de7f
Compare
Contributor
There was a problem hiding this comment.
Review completed against the latest diff
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
simonwhitaker
pushed a commit
that referenced
this pull request
Oct 22, 2026
🤖 I have created a release *beep* *boop* --- ## [1.2.0](v1.1.0...v1.2.0) (2026-10-22) ### Features * **activity:** record authored source locations for calls and outputs ([#2535](#2535)) ([2d735ca](2d735ca)) * **activity:** show persistent Program source beside selected records ([#2569](#2569)) ([f403819](f403819)) * add the Claude recipe and read gzipped OpenAPI documents ([#2513](#2513)) ([07c27a2](07c27a2)) * **catalog:** share named TypeScript types across a Provider ([#2482](#2482)) ([256e37d](256e37d)) * **desktop:** run the runtime on a Postgres database named in desktop.json ([#2485](#2485)) ([96465a0](96465a0)) * **functions:** type coral.providers, coral.workspace and coral.functions at Saved Function save ([#2526](#2526)) ([a465850](a465850)) * **provider:** create the Coral Built-in Provider at coral.workspace in every new Workspace ([#2349](#2349)) ([06e65ca](06e65ca)) * **provider:** store an agent's createProvider request on its Setup ([#2593](#2593)) ([92847d2](92847d2)) * **provider:** update every Workspace's Built-in Provider catalog at boot ([#2355](#2355)) ([24615d9](24615d9)) * **reef:** add NextDNS provider recipe ([#2509](#2509)) ([e44880e](e44880e)) * **reef:** calmer providers table and a flush app shell ([#2462](#2462)) ([ffe279c](ffe279c)) * **reef:** improve the UI on small screens ([#2531](#2531)) ([75e020a](75e020a)) * **reef:** make the providers rail vertical tabs with an All providers entry ([#2552](#2552)) ([08d007a](08d007a)) * **reef:** providers page UI tweaks ([#2562](#2562)) ([7ca218e](7ca218e)) * **reef:** put the list pages' main action back in the top bar as a primary button ([#2546](#2546)) ([761ea6d](761ea6d)) * **reef:** read ^, $ and * in every filter field ([#2520](#2520)) ([d322356](d322356)) * **reef:** refuse a provider display name another provider uses ([#2518](#2518)) ([fdcd473](fdcd473)) * **reef:** review provider configuration changes in a dialog ([#2579](#2579)) ([24417e9](24417e9)) * **reef:** show search indexing failures on a Provider and its Operations ([#2504](#2504)) ([6cffed0](6cffed0)) * **reef:** show your recent activity summary on the workspace overview ([#2574](#2574)) ([0d1dba5](0d1dba5)) * **reef:** title list pages in their toolbar, with the main action beside it ([#2525](#2525)) ([fd44b72](fd44b72)) * **reef:** UI tweaks to provider's page ([#2566](#2566)) ([62204ca](62204ca)) * **reef:** unify Activity detail panels and action reviews ([#2544](#2544)) ([409d062](409d062)) * return only declared successes from Operation calls ([#2517](#2517)) ([0270bf1](0270bf1)) * **run:** enforce the Fan-out Limit inside the Run Owner ([#2571](#2571)) ([cb53419](cb53419)) * **run:** introduce the Run Owner for Program requests ([#2524](#2524)) ([245d19d](245d19d)) * **run:** let coral.workspace.createProvider configure and publish the Provider itself ([#2352](#2352)) ([088faaf](088faaf)) * **run:** let createProvider configure sign-in and link to Reef's sign-in step ([#2353](#2353)) ([8d5495c](8d5495c)) * **run:** list a workspace's providers with coral.workspace.listProviders ([#2374](#2374)) ([179c43a](179c43a)) * **run:** make the Run Owner survive uncertain commits and lost leases ([#2541](#2541)) ([3a1fad1](3a1fad1)) * **run:** name Tasks and Runs with four-word identifiers ([#2558](#2558)) ([c82259a](c82259a)) * **run:** prepare a Provider from a Program with coral.workspace.createProvider ([#2351](#2351)) ([e7e56fd](e7e56fd)) * **run:** reshape the Dispatch Fence into one batched check per chunk commit ([#2550](#2550)) ([120c9d3](120c9d3)) * **run:** route approval decisions and cancellation through the Run Owner ([#2577](#2577)) ([77bcbf5](77bcbf5)) * **run:** summarize your recent activity in a Workspace ([#2573](#2573)) ([bf4c75e](bf4c75e)) * **search:** show a Saved Function's result fields in its signature line ([#2522](#2522)) ([41365f6](41365f6)) * **search:** trace each reconcile pass and its steps ([#2456](#2456)) ([0594094](0594094)) * **ui:** add option to create a correctly-configured Slack app during Slack provider setup ([#2585](#2585)) ([8c3a883](8c3a883)) * **ui:** move Add provider to the providers toolbar ([#2591](#2591)) ([e1ee4cb](e1ee4cb)) ### Bug Fixes * **app:** sweep device authorization leases every 15 s ([#2452](#2452)) ([1a4e4ae](1a4e4ae)) * **auth:** drop the unverified client name note from the approval page ([#2578](#2578)) ([ddf5aa4](ddf5aa4)) * **catalog:** derive each Built-in Operation's contract from the types Coral parses ([#2582](#2582)) ([534e636](534e636)) * **catalog:** import OpenAPI Providers whose Operations request different OAuth scopes ([#2401](#2401)) ([3acfe55](3acfe55)) * **catalog:** keep keyword names in Operation Call Paths ([#2506](#2506)) ([b20795b](b20795b)) * **catalog:** never make an Operation unavailable for search material ([#2465](#2465)) ([f83c909](f83c909)) * **catalog:** stop rejecting createProvider request headers by name ([#2589](#2589)) ([39e54b9](39e54b9)) * **provider:** ask for an OAuth client ID when Coral cannot register one ([#2580](#2580)) ([baefe9e](baefe9e)) * **provider:** bind each Setup to its starter and hide Coral from Members ([#2480](#2480)) ([6011a64](6011a64)) * **reef:** align the catalog table with the first rail entry ([#2484](#2484)) ([fb59758](fb59758)) * **reef:** calm the Activity badge and keep it while the stream reconnects ([#2468](#2468)) ([1b66639](1b66639)) * **reef:** frame the providers table again and lower the top bar ([#2472](#2472)) ([87e41ee](87e41ee)) * **reef:** pin third-party recipe OpenAPI documents to a commit ([#2510](#2510)) ([b4e9280](b4e9280)) * **reef:** replace loose help text with info tips and banners ([#2461](#2461)) ([695500a](695500a)) * **reef:** round the page's corners beside the sidebar ([#2503](#2503)) ([a1fef64](a1fef64)) * **reef:** shorten OAuth scope chips that share a URL prefix ([#2455](#2455)) ([5ae67ec](5ae67ec)) * **reef:** suggest a provider's namespace from its document name, not its host ([#2565](#2565)) ([8d77893](8d77893)) * **run:** name every argument to correct in an invalid_input failure ([#2354](#2354)) ([07bd727](07bd727)) * **run:** reject a credential beside createProvider's bearer method and report unreachable sources as upstream_incomplete ([#2542](#2542)) ([590eab7](590eab7)) * **run:** report an MCP JSON-RPC rejection as invalid_input or upstream_rejected ([#2402](#2402)) ([749770b](749770b)) * **search:** load each Generation's schema graph once per search ([#2448](#2448)) ([445d945](445d945)) * **search:** retry a failed Saved Function only after one interval ([#2460](#2460)) ([a61ab3a](a61ab3a)) * **search:** return no hits for a query without a letter or digit ([#2561](#2561)) ([bb0a4f0](bb0a4f0)) * **search:** start the write limit at the lock and build rows before the write ([#2575](#2575)) ([06ad55d](06ad55d)) * **search:** stop a self-referential Promise result from overflowing the stack ([#2543](#2543)) ([1d4f257](1d4f257)) * **search:** stop retrying an index write that fails the same way every time ([#2548](#2548)) ([e3b6d15](e3b6d15)) ### Performance Improvements * **catalog:** dedup credential destinations once per build, not per Operation ([#2555](#2555)) ([0afbcf5](0afbcf5)) * **catalog:** project each named TypeScript type once per Provider ([#2443](#2443)) ([153c273](153c273)) * **search:** drop schema text from the phrase test ([#2559](#2559)) ([cfdbafa](cfdbafa)) * **search:** index each word of schema text once ([#2547](#2547)) ([d1123fb](d1123fb)) * **search:** prepare search entries in the indexer after commit ([#2467](#2467)) ([1ab6765](1ab6765)) * **search:** recount only Workspaces whose rows changed ([#2457](#2457)) ([777cfb3](777cfb3)) * **search:** skip unchanged rows when an index write runs again ([#2459](#2459)) ([43b5188](43b5188)) * **search:** write only the statistics rows that changed ([#2458](#2458)) ([8e2832c](8e2832c)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). --------- Co-authored-by: coral-release-bot[bot] <269256696+coral-release-bot[bot]@users.noreply.github.com> Co-authored-by: release-please[bot] <release-please[bot]@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
An agent could call
createProviderwith an OAuth Provider Configuration that names no OAuth application, for a service Coral cannot register one with (no Dynamic Client Registration or Client ID Metadata Document, such as Google), or for device authorization. Coral returnedneeds_sign_in. The person's sign-in then failed, and Reef showed only "Coral is not available."createProvidernow refuses the call, and the agent can correct it:createProvider prepare Setup, confirm Provider Configuration SetupPublishability Coral → publish + Person, and the sign-in has no OAuth application + → end the Setup + → invalid_input at `authentication.client`: + "Coral cannot register an OAuth application with this service; + register one with the service and give its `client_id`" Person → needs_sign_in + Reef linkAn older Coral server can still confirm such a configuration. Reef handles that case:
The configuration hint now reads "Enter the client ID of your OAuth application in configuration before you sign in."
isOAuthMethodandautomaticApplicationAllowedreplace four inline copies of those checks in Reef.TestModules::accounts()replaces four copies of the filesystem-vault setup in thecoral-runtests.Evidence
The new tests ran against
main's source (tests from this branch), then against this branch:Before:
cargo test -p coral-run --lib an_invalid_argument_names_what_to_correctfails. The OAuth case with no client returns{"status": "needs_sign_in", "url": "…/providers/new?setup=…"}, notinvalid_input.After: passes for both the authorization-code case and the device-code case. Each denial also asserts it published nothing and canceled every Setup it prepared.
Before: Reef Vitest fails 9 cases:
model.test.ts: the agent's link for an MCP, API or device sign-in Coral cannot set up opensdiscovery/operations, notconfigurationaccount-step.test.tsx: "Sign in with Gmail" is enabled for the shared account and for your own accountmanagement-error.test.tsx: a 400 or 409 shows "Coral is unavailable"oauth-application.test.tsx: the old hint copyAfter: all 66 cases in those four files pass.
Gates on this branch, rebased on
main:make rust-checkspasses, 1469 of 1469 (6 skipped).npm run check,typecheck,npm test(1644 + 661 pass) andbuildpass.test:serverhas 15 pass and 1 fail, inscripts/bundle-server.test.mjs('hello bundle'vs'hello staged'). This PR does not touch that file. feat(reef): make the providers rail vertical tabs with an All providers entry #2552 reported the same failure.make postgres-tests. No repository code changes.Merge Danger
Door: two-way
No schema, stored data or API shape changes. Revert restores the old
needs_sign_inanswer.Blast Radius: provider-setup
Agents that call
createProviderwith OAuth and noclientfor a service without automatic registration now getinvalid_input, not a Reef link. That link led to a sign-in that could not start. Management pages that end in a 4xx other than 401, 403 or 404 now say the request failed, not that Coral is unavailable.