[ENG-4086] feat(catalog,api): declarative surface for multi-step custom auth#371
Merged
Conversation
Extend the custom auth schema so multi-step flows (redirects and/or server-side credential-exchange calls) can be expressed declaratively. Step definitions and handlers live in the connectors library; the catalog only carries the signal + inputs clients need. catalog.yaml: - CustomAuthInput: add fieldType (text/password/select) and options, so the UI can render masked/unmasked/dropdown fields. - Add CustomAuthInputOption (value/label) for select fields. - CustomAuthOpts: add providerInputs (builder-configured inputs, routed to storage by fieldType) and multiStep (tells "multi-step custom" apart from plain static "custom" at a glance; clients route to /custom-auth-connect). api.yaml: - Add POST /custom-auth-connect (sibling of /oauth-connect) to start/continue a flow, with CustomAuthConnectRequest, CustomAuthConnectResponse, and RedirectResponse schemas. Regenerated the derived JSON specs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Comment on lines
+4914
to
+4922
| CustomAuthConnectResponse: | ||
| title: Custom Auth Connect Response | ||
| type: object | ||
| description: Response from /custom-auth/connect. Exactly one of redirect or connection is set. A redirect means the client should open the URL and call again with sessionId + callbackParams; a connection means the flow is complete. | ||
| properties: | ||
| redirect: | ||
| $ref: "#/components/schemas/RedirectResponse" | ||
| connection: | ||
| $ref: "#/components/schemas/Connection" |
There was a problem hiding this comment.
Schema does not enforce "exactly one of redirect or connection" constraint. The description states this but the OpenAPI schema allows both fields to be set, both to be absent, or exactly one. This will allow invalid response objects to pass validation.
CustomAuthConnectResponse:
title: Custom Auth Connect Response
type: object
description: Response from /custom-auth/connect...
oneOf:
- required: [redirect]
properties:
redirect:
$ref: "#/components/schemas/RedirectResponse"
- required: [connection]
properties:
connection:
$ref: "#/components/schemas/Connection"Without this constraint, clients cannot reliably determine the response state and may encounter runtime errors when accessing fields.
Suggested change
| CustomAuthConnectResponse: | |
| title: Custom Auth Connect Response | |
| type: object | |
| description: Response from /custom-auth/connect. Exactly one of redirect or connection is set. A redirect means the client should open the URL and call again with sessionId + callbackParams; a connection means the flow is complete. | |
| properties: | |
| redirect: | |
| $ref: "#/components/schemas/RedirectResponse" | |
| connection: | |
| $ref: "#/components/schemas/Connection" | |
| CustomAuthConnectResponse: | |
| title: Custom Auth Connect Response | |
| type: object | |
| description: Response from /custom-auth/connect. Exactly one of redirect or connection is set. A redirect means the client should open the URL and call again with sessionId + callbackParams; a connection means the flow is complete. | |
| oneOf: | |
| - required: [redirect] | |
| properties: | |
| redirect: | |
| $ref: "#/components/schemas/RedirectResponse" | |
| - required: [connection] | |
| properties: | |
| connection: | |
| $ref: "#/components/schemas/Connection" | |
Spotted by Graphite
Is this helpful? React 👍 or 👎 to let us know.
- CustomAuthConnectResponse: use oneOf to enforce exactly one of redirect/connection. - CustomAuthConnectRequest: clarify provider/customAuth are required only on the first call (sessionId absent), enforced at the app layer; sessionId doc notes the resume case. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Contributor
Author
|
Addressed both review comments in
|
Values are fieldTypeText/fieldTypePassword/fieldTypeSelect instead of text/password/select. A bare "password" value collided with other enums (e.g. Oauth2Opts grantType) and forced oapi-codegen to prefix every enum const in the connectors package, breaking existing references. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
laurenzlong
approved these changes
Jul 13, 2026
| "post": { | ||
| "operationId": "customAuthConnect", | ||
| "summary": "Start or continue a multi-step custom auth flow", | ||
| "description": "Drives a multi-step custom auth flow (browser redirects and/or server-side credential-exchange calls). Call it once with the flow inputs to start; if the response contains a redirect, open it, then call again with the returned sessionId and the provider's callback params to continue. Repeat until the response contains a connection. Used by the prebuilt UI components; only providers whose ProviderInfo has customOpts.multiStep set use this endpoint.\n", |
Collaborator
There was a problem hiding this comment.
Suggested change
| "description": "Drives a multi-step custom auth flow (browser redirects and/or server-side credential-exchange calls). Call it once with the flow inputs to start; if the response contains a redirect, open it, then call again with the returned sessionId and the provider's callback params to continue. Repeat until the response contains a connection. Used by the prebuilt UI components; only providers whose ProviderInfo has customOpts.multiStep set use this endpoint.\n", | |
| "description": "Drives a multi-step custom auth flow (browser redirects and/or server-side credential-exchange calls). Call it once with the flow inputs to start; if the response contains a redirect, open it, then call again with the returned sessionId and the provider's callback params to continue. Repeat until the response contains a connection. Used by the prebuilt UI components; only providers whose ProviderInfo has customOpts.multiStep present can use this endpoint.\n", |
- Reword the endpoint description (multiStep present can use this endpoint). - Document that groupRef/groupName/consumerRef/consumerName are supplied on the first call and ignored on resume (the parked flow's identity is used). - Drop providerWorkspaceRef from CustomAuthConnectRequest: custom auth carries workspace via providerMetadata (and the flow can capture it), so the field is redundant here. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.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.
Extends the custom-auth schema so multi-step flows (browser redirects and/or server-side credential-exchange calls) can be expressed, and adds the endpoint that drives them. Step definitions and handlers live in the connectors library, so there are no function/step schemas here.
catalog.yaml
CustomAuthInput: addfieldType(text/password/select) andoptions; newCustomAuthInputOption(value/label).CustomAuthOpts: addproviderInputs(builder-configured inputs, routed to storage byfieldType) andmultiStep(the flag that tells "multi-step custom" apart from static "custom").api.yaml
POST /custom-auth/connect— start or resume a flow (namespaced sibling of/oauth-connect; inherits global auth like oauth-connect).CustomAuthConnectRequest,CustomAuthConnectResponse(oneOfredirect/connection),RedirectResponse.Regenerated the derived JSON specs.
Review follow-ups (7419dbc)
redirect/connectionviaoneOf.provider/customAuthare required only on the first call (whensessionIdis absent), validated at the app layer.