From 4d089436b6f709f5bb02391dd22964ad959db8b6 Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Wed, 8 Jul 2026 17:43:57 -0300 Subject: [PATCH 1/6] fix(openapi): add operationIds, fix broken $ref, add discriminator - Add operationId to every operation (59 total) so SDK generators produce readable method names instead of path-derived ones. - Fix /user/identities/{identityId} 401/403 responses that incorrectly $ref'd a Response object from inside `schema:` instead of ErrorSchema. - Add discriminator to the /factors/{factorId}/challenge response oneOf so typed SDKs can pick the right variant. --- openapi.yaml | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 2 deletions(-) diff --git a/openapi.yaml b/openapi.yaml index c8dd847dc..ba9703b50 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -62,6 +62,7 @@ paths: /token: post: summary: Issues access and refresh tokens based on grant type. + operationId: token tags: - auth parameters: @@ -196,6 +197,7 @@ paths: /logout: post: summary: Logs out a user. + operationId: logout tags: - auth security: @@ -221,6 +223,7 @@ paths: /verify: get: summary: Authenticate by verifying the possession of a one-time token. Usually for use as clickable links. + operationId: verifyRedirect tags: - auth parameters: @@ -254,6 +257,7 @@ paths: $ref: "#/components/responses/AccessRefreshTokenRedirectResponse" post: summary: Authenticate by verifying the possession of a one-time token. + operationId: verifyOtp tags: - auth security: @@ -309,6 +313,7 @@ paths: /authorize: get: summary: Redirects to an external OAuth provider. Usually for use as clickable links. + operationId: authorize tags: - oauth-client security: @@ -356,6 +361,7 @@ paths: /signup: post: summary: Signs a user up. + operationId: signup description: > Creates a new user. tags: @@ -430,6 +436,7 @@ paths: /recover: post: summary: Request password recovery. + operationId: recover description: > Users that have forgotten their password can have it reset with this API. tags: @@ -477,6 +484,7 @@ paths: /resend: post: summary: Resends a one-time password (OTP) through email or SMS. + operationId: resend description: > Allows a user to resend an existing signup, sms, email_change or phone_change OTP. tags: @@ -533,6 +541,7 @@ paths: /magiclink: post: summary: Authenticate a user by sending them a magic link. + operationId: sendMagicLink description: > A magic link is a special type of URL that includes a One-Time Password. When a user visits this link in a browser they are immediately authenticated. tags: @@ -575,6 +584,7 @@ paths: /otp: post: summary: Authenticate a user by sending them a One-Time Password over email or SMS. + operationId: sendOtp tags: - auth security: @@ -634,6 +644,7 @@ paths: /user: get: summary: Fetch the latest user account information. + operationId: getUser tags: - user security: @@ -648,6 +659,7 @@ paths: $ref: "#/components/schemas/UserSchema" put: summary: Update certain properties of the current user account. + operationId: updateUser tags: - user security: @@ -693,6 +705,7 @@ paths: /user/identities/authorize: get: summary: Links an OAuth identity to an existing user. Redirects to an external OAuth provider. + operationId: linkIdentity tags: - user security: @@ -743,6 +756,7 @@ paths: format: uuid delete: summary: Unlinks an identity from the current user. + operationId: unlinkIdentity tags: - user security: @@ -760,7 +774,7 @@ paths: content: application/json: schema: - $ref: "#/components/responses/UnauthorizedResponse" + $ref: "#/components/schemas/ErrorSchema" examples: example: summary: no_authorization @@ -771,7 +785,7 @@ paths: content: application/json: schema: - $ref: "#/components/responses/ForbiddenResponse" + $ref: "#/components/schemas/ErrorSchema" examples: example: summary: bad_jwt @@ -823,6 +837,7 @@ paths: /user/oauth/grants: get: summary: List OAuth grants + operationId: listOauthGrants description: > Retrieves a list of all OAuth grants that the authenticated user has authorized. Only available when OAuth server is enabled. tags: @@ -875,6 +890,7 @@ paths: $ref: "#/components/responses/ForbiddenResponse" delete: summary: Revoke OAuth grant + operationId: revokeOauthGrant description: > Revokes the user's OAuth grant for a specific client. This will: - Mark the consent as revoked @@ -931,6 +947,7 @@ paths: /reauthenticate: post: summary: Reauthenticates the possession of an email or phone number for the purpose of password change. + operationId: reauthenticate description: > For a password to be changed on a user account, the user's email or phone number needs to be confirmed before they are allowed to set a new password. This requirement is configurable. This API sends a confirmation email or SMS message. A nonce in this message can be provided in `PUT /user` to change the password on the account. tags: @@ -953,6 +970,7 @@ paths: /factors: post: summary: Begin enrolling a new factor for MFA. + operationId: enrollFactor tags: - user security: @@ -1016,6 +1034,7 @@ paths: /factors/{factorId}/challenge: post: summary: Create a new challenge for a MFA factor. + operationId: challengeFactor tags: - user security: @@ -1051,6 +1070,12 @@ paths: oneOf: - $ref: '#/components/schemas/TOTPPhoneChallengeResponse' - $ref: '#/components/schemas/WebAuthnChallengeResponse' + discriminator: + propertyName: type + mapping: + totp: '#/components/schemas/TOTPPhoneChallengeResponse' + phone: '#/components/schemas/TOTPPhoneChallengeResponse' + webauthn: '#/components/schemas/WebAuthnChallengeResponse' 400: $ref: "#/components/responses/BadRequestResponse" 429: @@ -1059,6 +1084,7 @@ paths: /factors/{factorId}/verify: post: summary: Verify a challenge on a factor. + operationId: verifyFactor tags: - user security: @@ -1114,6 +1140,7 @@ paths: /factors/{factorId}: delete: summary: Remove a MFA factor from a user. + operationId: unenrollFactor tags: - user security: @@ -1146,6 +1173,7 @@ paths: /callback: get: summary: Redirects OAuth flow errors to the frontend app. + operationId: oauthCallbackGet description: > When an OAuth sign-in flow fails for any reason, the error message needs to be delivered to the frontend app requesting the flow. This callback delivers the errors as `error` and `error_description` query params. Usually this request is not called directly. tags: @@ -1157,6 +1185,7 @@ paths: $ref: "#/components/responses/OAuthCallbackRedirectResponse" post: summary: Redirects OAuth flow errors to the frontend app. + operationId: oauthCallbackPost description: > When an OAuth sign-in flow fails for any reason, the error message needs to be delivered to the frontend app requesting the flow. This callback delivers the errors as `error` and `error_description` query params. Usually this request is not called directly. tags: @@ -1168,6 +1197,7 @@ paths: /sso: post: summary: Initiate a Single-Sign On flow. + operationId: ssoSignIn tags: - sso security: @@ -1234,6 +1264,7 @@ paths: /saml/metadata: get: summary: Returns the SAML 2.0 Metadata XML. + operationId: getSamlMetadata description: > The metadata XML can be downloaded or used for the SAML 2.0 Metadata URL discovery mechanism. This URL is the SAML 2.0 EntityID of the Service Provider implemented by this server. tags: @@ -1268,6 +1299,7 @@ paths: /saml/acs: post: summary: SAML 2.0 Assertion Consumer Service (ACS) endpoint. + operationId: samlAcs description: > Implements the SAML 2.0 Assertion Consumer Service (ACS) endpoint supporting the POST and Artifact bindings. tags: @@ -1307,6 +1339,7 @@ paths: /invite: post: summary: Invite a user by email. + operationId: inviteUserByEmail description: > Sends an invitation email which contains a link that allows the user to sign-in. tags: @@ -1344,6 +1377,7 @@ paths: /admin/generate_link: post: summary: Generate a link to send in an email message. + operationId: adminGenerateLink tags: - admin security: @@ -1426,6 +1460,7 @@ paths: /admin/audit: get: summary: Fetch audit log events. + operationId: adminListAuditLogEntries tags: - admin security: @@ -1521,6 +1556,7 @@ paths: /admin/users: get: summary: Fetch a listing of users. + operationId: adminListUsers tags: - admin security: @@ -1569,6 +1605,7 @@ paths: format: uuid get: summary: Fetch user account data for a user. + operationId: adminGetUser tags: - admin security: @@ -1593,6 +1630,7 @@ paths: $ref: "#/components/schemas/ErrorSchema" put: summary: Update user's account data. + operationId: adminUpdateUser tags: - admin security: @@ -1622,6 +1660,7 @@ paths: $ref: "#/components/schemas/ErrorSchema" delete: summary: Delete a user. + operationId: adminDeleteUser tags: - admin security: @@ -1655,6 +1694,7 @@ paths: format: uuid get: summary: List all of the MFA factors for a user. + operationId: adminListUserFactors tags: - admin security: @@ -1696,6 +1736,7 @@ paths: format: uuid put: summary: Update a user's MFA factor. + operationId: adminUpdateUserFactor tags: - admin security: @@ -1725,6 +1766,7 @@ paths: $ref: "#/components/schemas/ErrorSchema" delete: summary: Remove a user's MFA factor. + operationId: adminDeleteUserFactor tags: - admin security: @@ -1751,6 +1793,7 @@ paths: /admin/sso/providers: get: summary: Fetch a list of all registered SSO providers. + operationId: adminListSsoProviders tags: - admin security: @@ -1770,6 +1813,7 @@ paths: $ref: "#/components/schemas/SSOProviderSchema" post: summary: Register a new SSO provider. + operationId: adminCreateSsoProvider tags: - admin security: @@ -1823,6 +1867,7 @@ paths: format: uuid get: summary: Fetch SSO provider details. + operationId: adminGetSsoProvider tags: - admin security: @@ -1847,6 +1892,7 @@ paths: $ref: "#/components/schemas/ErrorSchema" put: summary: Update details about a SSO provider. + operationId: adminUpdateSsoProvider description: > You can only update only one of `metadata_url` or `metadata_xml` at once. The SAML Metadata represented by these updates must advertize the same Identity Provider EntityID. Do not include the `domains` or `attribute_mapping` property to keep the existing database values. tags: @@ -1893,6 +1939,7 @@ paths: $ref: "#/components/schemas/ErrorSchema" delete: summary: Remove an SSO provider. + operationId: adminDeleteSsoProvider tags: - admin security: @@ -1919,6 +1966,7 @@ paths: /admin/oauth/clients: get: summary: List OAuth clients (admin) + operationId: adminListOauthClients description: > Retrieves a list of all registered OAuth clients. Only available when OAuth server is enabled. tags: @@ -1958,6 +2006,7 @@ paths: $ref: "#/components/responses/ForbiddenResponse" post: summary: Register OAuth client (admin) + operationId: adminCreateOauthClient description: > Manually register a new OAuth client (admin endpoint). Only available when OAuth server is enabled. tags: @@ -2052,6 +2101,7 @@ paths: type: string get: summary: Get OAuth client details (admin) + operationId: adminGetOauthClient description: > Retrieves details of a specific OAuth client. Only available when OAuth server is enabled. tags: @@ -2079,6 +2129,7 @@ paths: $ref: "#/components/responses/ForbiddenResponse" put: summary: Update OAuth client (admin) + operationId: adminUpdateOauthClient description: > Updates an existing OAuth client registration. Only the provided fields will be updated. Only available when OAuth server is enabled. @@ -2154,6 +2205,7 @@ paths: $ref: "#/components/responses/ForbiddenResponse" delete: summary: Delete OAuth client (admin) + operationId: adminDeleteOauthClient description: > Removes an OAuth client registration. Only available when OAuth server is enabled. tags: @@ -2185,6 +2237,7 @@ paths: type: string post: summary: Regenerate OAuth client secret (admin) + operationId: adminRegenerateOauthClientSecret description: > Regenerates the client secret for a confidential OAuth client. Only available when OAuth server is enabled. This endpoint can only be used for confidential clients, not public clients. @@ -2221,6 +2274,7 @@ paths: /admin/custom-providers: get: summary: List all custom OIDC/OAuth providers + operationId: adminListCustomOauthProviders description: > Retrieves a list of all custom OAuth 2.0 and OIDC provider configurations. Optionally filter by provider type. Only available when custom OIDC/OAuth providers are enabled @@ -2271,6 +2325,7 @@ paths: $ref: "#/components/responses/ForbiddenResponse" post: summary: Create a new custom OIDC/OAuth provider + operationId: adminCreateCustomOauthProvider description: > Creates a new custom OAuth 2.0 or OIDC provider configuration. Required fields differ based on provider_type. Only available when custom OIDC/OAuth providers are enabled. @@ -2481,6 +2536,7 @@ paths: example: "custom:mycompany" get: summary: Get custom OIDC/OAuth provider details + operationId: adminGetCustomOauthProvider description: > Retrieves details of a specific custom OIDC/OAuth provider. Only available when custom OIDC/OAuth providers are enabled. @@ -2527,6 +2583,7 @@ paths: msg: "Custom OAuth provider not found" put: summary: Update custom OIDC/OAuth provider + operationId: adminUpdateCustomOauthProvider description: > Updates an existing custom OIDC/OAuth provider. All fields are optional. Only provided fields will be updated. Only available when custom OIDC/OAuth providers are enabled. @@ -2664,6 +2721,7 @@ paths: $ref: "#/components/schemas/ErrorSchema" delete: summary: Delete custom OIDC/OAuth provider + operationId: adminDeleteCustomOauthProvider description: > Permanently removes a custom OIDC/OAuth provider configuration. Only available when custom OIDC/OAuth providers are enabled. @@ -2708,6 +2766,7 @@ paths: /oauth/clients/register: post: summary: Register a new OAuth client dynamically (public endpoint). + operationId: registerOauthClient description: > Allows applications to register as OAuth clients with this server dynamically. This follows the OAuth 2.0 Dynamic Client Registration Protocol. Only available when OAuth server is enabled and dynamic registration is allowed (set `GOTRUE_OAUTH_SERVER_ENABLED=true` and `GOTRUE_OAUTH_SERVER_ALLOW_DYNAMIC_REGISTRATION=true` for self-hosted or enable both settings in Supabase Dashboard). tags: @@ -2790,6 +2849,7 @@ paths: /oauth/token: post: summary: OAuth 2.1 Token endpoint + operationId: oauthToken description: > Issues access tokens in exchange for authorization codes or refresh tokens. Supports authorization_code and refresh_token grant types. Only available when OAuth server is enabled (set `GOTRUE_OAUTH_SERVER_ENABLED=true` for self-hosted or enable in Supabase Dashboard). tags: @@ -2859,6 +2919,7 @@ paths: /oauth/authorize: get: summary: OAuth 2.1 Authorization endpoint + operationId: oauthAuthorize description: > Initiates the OAuth authorization code flow. Redirects users to login and authorize the requesting application. Only available when OAuth server is enabled (set `GOTRUE_OAUTH_SERVER_ENABLED=true` for self-hosted or enable in Supabase Dashboard). tags: @@ -2928,6 +2989,7 @@ paths: type: string get: summary: Get OAuth authorization details + operationId: getOauthAuthorization description: > Retrieves details about a pending OAuth authorization request. Only available when OAuth server is enabled (set `GOTRUE_OAUTH_SERVER_ENABLED=true` for self-hosted or enable in Supabase Dashboard). tags: @@ -2991,6 +3053,7 @@ paths: type: string post: summary: Approve or deny OAuth authorization + operationId: oauthAuthorizationConsent description: > User approves or denies authorization to the OAuth client. Only available when OAuth server is enabled (set `GOTRUE_OAUTH_SERVER_ENABLED=true` for self-hosted or enable in Supabase Dashboard). tags: @@ -3031,6 +3094,7 @@ paths: /health: get: summary: Service healthcheck. + operationId: healthCheck description: Ping this endpoint to receive information about the health of the service. tags: - general @@ -3071,6 +3135,7 @@ paths: /settings: get: summary: Retrieve some of the public settings of the server. + operationId: getSettings description: > Use this endpoint to configure parts of any authentication UIs depending on the configured settings. tags: From 81ea0d600966ad76231368c4432696a00f01fd5a Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Wed, 8 Jul 2026 17:46:38 -0300 Subject: [PATCH 2/6] fix(openapi): standardize code_challenge_method casing to S256 Legacy endpoints documented lowercase "s256" while /oauth/authorize documented uppercase "S256" for the same parameter. Server parses this case-insensitively (ParseCodeChallengeMethod, oauthserver authorize.go) and the discovery document already advertises "S256", so standardize all docs on that casing. --- openapi.yaml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/openapi.yaml b/openapi.yaml index ba9703b50..210d1168f 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -353,7 +353,7 @@ paths: type: string enum: - plain - - s256 + - S256 responses: 302: $ref: "#/components/responses/OAuthAuthorizeRedirectResponse" @@ -389,7 +389,7 @@ paths: value: email: user@example.com password: password1 - code_challenge_method: s256 + code_challenge_method: S256 code_challenge: elU6u5zyqQT2f92GRQUq6PautAeNDf4DQPayyR0ek_c& schema: type: object @@ -415,7 +415,7 @@ paths: type: string enum: - plain - - s256 + - S256 gotrue_meta_security: $ref: "#/components/schemas/GoTrueSecurity" responses: @@ -460,7 +460,7 @@ paths: type: string enum: - plain - - s256 + - S256 gotrue_meta_security: $ref: "#/components/schemas/GoTrueSecurity" responses: @@ -613,7 +613,7 @@ paths: code_challenge_method: type: string enum: - - s256 + - S256 - plain code_challenge: type: string @@ -741,7 +741,7 @@ paths: type: string enum: - plain - - s256 + - S256 responses: 302: $ref: "#/components/responses/OAuthAuthorizeRedirectResponse" @@ -1228,7 +1228,7 @@ paths: type: string enum: - plain - - s256 + - S256 gotrue_meta_security: $ref: "#/components/schemas/GoTrueSecurity" responses: From e88200ded76be646af201fd11dddb62155827f5d Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Wed, 8 Jul 2026 17:51:00 -0300 Subject: [PATCH 3/6] fix(openapi): dedupe OAuth client create request body POST /admin/oauth/clients and POST /oauth/clients/register carried a byte-identical inline request schema. Extract it into OAuthClientCreateRequest and $ref it from both. The PUT update body stays inline since its shape genuinely differs (no client_type, nothing required). --- openapi.yaml | 182 ++++++++++++++++++--------------------------------- 1 file changed, 64 insertions(+), 118 deletions(-) diff --git a/openapi.yaml b/openapi.yaml index 210d1168f..406b4486b 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -2019,65 +2019,7 @@ paths: content: application/json: schema: - type: object - required: - - client_name - - redirect_uris - properties: - client_name: - type: string - description: Human-readable name of the client application - client_uri: - type: string - format: uri - description: URL of the client application's homepage - logo_uri: - type: string - format: uri - description: URL of the client application's logo - redirect_uris: - type: array - items: - type: string - format: uri - description: Array of redirect URIs used by the client (maximum 10) - client_type: - type: string - enum: - - public - - confidential - description: > - Type of the client. Optional. If not provided, will be inferred from token_endpoint_auth_method or defaults to 'confidential'. - Public clients are used for applications that cannot securely store credentials (e.g., SPAs, mobile apps). - Confidential clients can securely store credentials (e.g., server-side applications). - token_endpoint_auth_method: - type: string - enum: - - none - - client_secret_basic - - client_secret_post - description: > - Authentication method for the token endpoint. Optional. - 'none' is for public clients, 'client_secret_basic' and 'client_secret_post' are for confidential clients. - If provided, must be consistent with client_type. If not provided, will be inferred from client_type. - grant_types: - type: array - items: - type: string - enum: - - authorization_code - - refresh_token - description: OAuth grant types the client will use (defaults to both if not specified) - response_types: - type: array - items: - type: string - enum: - - code - description: OAuth response types the client can use - scope: - type: string - description: Space-separated list of scope values + $ref: "#/components/schemas/OAuthClientCreateRequest" responses: 201: description: OAuth client created @@ -2775,65 +2717,7 @@ paths: content: application/json: schema: - type: object - required: - - client_name - - redirect_uris - properties: - client_name: - type: string - description: Human-readable name of the client application - client_uri: - type: string - format: uri - description: URL of the client application's homepage - logo_uri: - type: string - format: uri - description: URL of the client application's logo - redirect_uris: - type: array - items: - type: string - format: uri - description: Array of redirect URIs used by the client (maximum 10) - client_type: - type: string - enum: - - public - - confidential - description: > - Type of the client. Optional. If not provided, will be inferred from token_endpoint_auth_method or defaults to 'confidential'. - Public clients are used for applications that cannot securely store credentials (e.g., SPAs, mobile apps). - Confidential clients can securely store credentials (e.g., server-side applications). - token_endpoint_auth_method: - type: string - enum: - - none - - client_secret_basic - - client_secret_post - description: > - Authentication method for the token endpoint. Optional. - 'none' is for public clients, 'client_secret_basic' and 'client_secret_post' are for confidential clients. - If provided, must be consistent with client_type. If not provided, will be inferred from client_type. - grant_types: - type: array - items: - type: string - enum: - - authorization_code - - refresh_token - description: OAuth grant types the client will use (defaults to both if not specified) - response_types: - type: array - items: - type: string - enum: - - code - description: OAuth response types the client will use - scope: - type: string - description: Space-separated list of scope values + $ref: "#/components/schemas/OAuthClientCreateRequest" responses: 201: description: OAuth client registered successfully @@ -3799,6 +3683,68 @@ components: type: string format: date-time + OAuthClientCreateRequest: + type: object + description: Fields accepted when registering a new OAuth 2.1 client, either via the admin API or OAuth 2.0 Dynamic Client Registration. + required: + - client_name + - redirect_uris + properties: + client_name: + type: string + description: Human-readable name of the client application + client_uri: + type: string + format: uri + description: URL of the client application's homepage + logo_uri: + type: string + format: uri + description: URL of the client application's logo + redirect_uris: + type: array + items: + type: string + format: uri + description: Array of redirect URIs used by the client (maximum 10) + client_type: + type: string + enum: + - public + - confidential + description: > + Type of the client. Optional. If not provided, will be inferred from token_endpoint_auth_method or defaults to 'confidential'. + Public clients are used for applications that cannot securely store credentials (e.g., SPAs, mobile apps). + Confidential clients can securely store credentials (e.g., server-side applications). + token_endpoint_auth_method: + type: string + enum: + - none + - client_secret_basic + - client_secret_post + description: > + Authentication method for the token endpoint. Optional. + 'none' is for public clients, 'client_secret_basic' and 'client_secret_post' are for confidential clients. + If provided, must be consistent with client_type. If not provided, will be inferred from client_type. + grant_types: + type: array + items: + type: string + enum: + - authorization_code + - refresh_token + description: OAuth grant types the client will use (defaults to both if not specified) + response_types: + type: array + items: + type: string + enum: + - code + description: OAuth response types the client will use + scope: + type: string + description: Space-separated list of scope values + CustomOAuthProviderSchema: type: object description: Represents a custom OAuth 2.0 or OIDC provider configuration From a275722c7da0bdd329e14da14c8d555d138c52ed Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Wed, 8 Jul 2026 17:55:26 -0300 Subject: [PATCH 4/6] fix(openapi): clear remaining redocly lint errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replace invalid patternProperties (SAMLAttributeMappingSchema.keys, /settings external) with additionalProperties. - Drop invalid `optional: true` keyword on /settings sms_provider (properties are optional by default unless in `required`). - Add missing `security: [APIKeyAuth]` to POST /callback, POST /oauth/clients/register, POST /oauth/token, GET /oauth/authorize — all were oversights vs. sibling operations that already declare it; none of these bypass the gateway apikey requirement. --- openapi.yaml | 44 +++++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/openapi.yaml b/openapi.yaml index 406b4486b..026bab9aa 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1190,6 +1190,8 @@ paths: When an OAuth sign-in flow fails for any reason, the error message needs to be delivered to the frontend app requesting the flow. This callback delivers the errors as `error` and `error_description` query params. Usually this request is not called directly. tags: - oauth-client + security: + - APIKeyAuth: [] responses: 302: $ref: "#/components/responses/OAuthCallbackRedirectResponse" @@ -2713,6 +2715,8 @@ paths: Allows applications to register as OAuth clients with this server dynamically. This follows the OAuth 2.0 Dynamic Client Registration Protocol. Only available when OAuth server is enabled and dynamic registration is allowed (set `GOTRUE_OAUTH_SERVER_ENABLED=true` and `GOTRUE_OAUTH_SERVER_ALLOW_DYNAMIC_REGISTRATION=true` for self-hosted or enable both settings in Supabase Dashboard). tags: - oauth-server + security: + - APIKeyAuth: [] requestBody: content: application/json: @@ -2738,6 +2742,8 @@ paths: Issues access tokens in exchange for authorization codes or refresh tokens. Supports authorization_code and refresh_token grant types. Only available when OAuth server is enabled (set `GOTRUE_OAUTH_SERVER_ENABLED=true` for self-hosted or enable in Supabase Dashboard). tags: - oauth-server + security: + - APIKeyAuth: [] requestBody: content: application/x-www-form-urlencoded: @@ -2808,6 +2814,8 @@ paths: Initiates the OAuth authorization code flow. Redirects users to login and authorize the requesting application. Only available when OAuth server is enabled (set `GOTRUE_OAUTH_SERVER_ENABLED=true` for self-hosted or enable in Supabase Dashboard). tags: - oauth-server + security: + - APIKeyAuth: [] parameters: - name: response_type in: query @@ -3049,7 +3057,6 @@ paths: description: Whether new phone numbers need to be confirmed before sign-in is possible. sms_provider: type: string - optional: true example: twilio description: Which SMS provider is being used to send messages to phone numbers. saml_enabled: @@ -3064,9 +3071,8 @@ paths: apple: true email: true phone: true - patternProperties: - "[a-zA-Z0-9]+": - type: boolean + additionalProperties: + type: boolean components: securitySchemes: @@ -3228,22 +3234,22 @@ components: properties: keys: type: object - patternProperties: - ".+": - type: object - properties: - name: + description: Maps a destination user attribute name to its SAML assertion source. + additionalProperties: + type: object + properties: + name: + type: string + names: + type: array + items: type: string - names: - type: array - items: - type: string - default: - oneOf: - - type: string - - type: number - - type: boolean - - type: object + default: + oneOf: + - type: string + - type: number + - type: boolean + - type: object SSOProviderSchema: type: object From 1f86bd2ed5b6a275d009188450a762b748b9d319 Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Wed, 8 Jul 2026 18:02:36 -0300 Subject: [PATCH 5/6] fix(openapi): add missing 2xx/4xx responses, ignore by-design cases Verified each flagged operation against its Go handler before touching anything -- only added responses that are real, and left redirect-only flows alone rather than fabricating a fake 2xx. Genuine gaps fixed: - GET /verify, GET /authorize: add 400 (GetExternalProviderRedirectURL/ verifyTokenHash return real validation errors); /authorize also gets 404 for a missing invite_token. - GET /user: add 401 (UserAuth-guarded, was undocumented). - GET /user/identities/authorize: LinkIdentity actually returns a 200 JSON {url} when skip_http_redirect=true (mirrors the existing /sso pattern) but that query param and response were never documented. Added both, plus 400/401. - GET /admin/sso/providers: add 401/403 to match every sibling admin list endpoint. For the remaining 11 warnings the operations genuinely have no 2xx or no 4xx path (redirect-only success, or no rejectable input) -- added .redocly.lint-ignore.yaml with comments explaining why each is intentional instead of inventing fake responses. --- .redocly.lint-ignore.yaml | 25 +++++++++++++++++++++++++ openapi.yaml | 38 +++++++++++++++++++++++++++++++++++++- 2 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 .redocly.lint-ignore.yaml diff --git a/.redocly.lint-ignore.yaml b/.redocly.lint-ignore.yaml new file mode 100644 index 000000000..3e7905e78 --- /dev/null +++ b/.redocly.lint-ignore.yaml @@ -0,0 +1,25 @@ +# This file instructs Redocly's linter to ignore the rules contained for specific parts of your API. +# See https://redocly.com/docs/cli/ for more information. +# +# Entries below are intentional, not oversights, verified against the Go handlers: +# - operation-2xx-response: these operations only ever succeed via a redirect (3xx), +# they have no JSON 2xx success path (GET /verify, GET /authorize, GET/POST /callback, +# POST /saml/acs, GET /oauth/authorize). +# - operation-4xx-response: these operations take no caller-supplied input that the +# handler can reject, so they have no client-error path (GET /callback -- the callback +# handler always redirects, converting any internal error into query params on the +# redirect target rather than returning JSON -- GET /saml/metadata, GET /health, GET /settings). +openapi.yaml: + operation-2xx-response: + - '#/paths/~1verify/get/responses' + - '#/paths/~1authorize/get/responses' + - '#/paths/~1callback/get/responses' + - '#/paths/~1callback/post/responses' + - '#/paths/~1saml~1acs/post/responses' + - '#/paths/~1oauth~1authorize/get/responses' + operation-4xx-response: + - '#/paths/~1callback/get/responses' + - '#/paths/~1callback/post/responses' + - '#/paths/~1saml~1metadata/get/responses' + - '#/paths/~1health/get/responses' + - '#/paths/~1settings/get/responses' diff --git a/openapi.yaml b/openapi.yaml index 026bab9aa..9d2c9c738 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -255,6 +255,8 @@ paths: responses: 302: $ref: "#/components/responses/AccessRefreshTokenRedirectResponse" + 400: + $ref: "#/components/responses/BadRequestResponse" post: summary: Authenticate by verifying the possession of a one-time token. operationId: verifyOtp @@ -357,6 +359,14 @@ paths: responses: 302: $ref: "#/components/responses/OAuthAuthorizeRedirectResponse" + 400: + $ref: "#/components/responses/BadRequestResponse" + 404: + description: Returned when `invite_token` is provided but no matching invitation could be found. + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorSchema" /signup: post: @@ -657,6 +667,8 @@ paths: application/json: schema: $ref: "#/components/schemas/UserSchema" + 401: + $ref: "#/components/responses/UnauthorizedResponse" put: summary: Update certain properties of the current user account. operationId: updateUser @@ -742,10 +754,30 @@ paths: enum: - plain - S256 + - name: skip_http_redirect + in: query + description: Set to `true` if the response to this request should not be a HTTP redirect -- useful for browser-based applications. + schema: + type: boolean responses: + 200: + description: > + Returned only when `skip_http_redirect` is `true`. Client libraries should use the returned URL to redirect or open a browser. + content: + application/json: + schema: + type: object + properties: + url: + type: string + format: uri 302: $ref: "#/components/responses/OAuthAuthorizeRedirectResponse" - + 400: + $ref: "#/components/responses/BadRequestResponse" + 401: + $ref: "#/components/responses/UnauthorizedResponse" + /user/identities/{identityId}: parameters: - name: identityId @@ -1813,6 +1845,10 @@ paths: type: array items: $ref: "#/components/schemas/SSOProviderSchema" + 401: + $ref: "#/components/responses/UnauthorizedResponse" + 403: + $ref: "#/components/responses/ForbiddenResponse" post: summary: Register a new SSO provider. operationId: adminCreateSsoProvider From 890bafbc003011cc04aac138fa3ab39d3527708e Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Wed, 8 Jul 2026 19:14:13 -0300 Subject: [PATCH 6/6] fix(openapi): split /token, /verify, /factors into discriminated request schemas Each of these endpoints crammed every grant-type/verification-type/ factor-type's fields into one flat, all-optional object, so generated SDKs got a single loosely-typed request struct instead of a real choice of shapes. Split each into named request schemas per real Go handler struct/validation (PasswordGrantParams, RefreshTokenGrantParams, IdTokenGrantParams, PKCEGrantParams, Web3GrantParams, VerifyParams, EnrollFactorParams), wired as oneOf. /token and /verify dispatch on grant_type/token_hash-vs-token which live outside (query param) or across (token vs token_hash) the request body, so no discriminator applies there. /factors dispatches on factor_type inside the body, so that one gets a real discriminator. Also: - fixed /token's 401/403 responses, which pointed at the wrong response ref (401 was ForbiddenResponse, 403 was UnauthorizedResponse). - documented link_identity on the id_token grant and issuer's real default on TOTP enrollment -- both real, previously undocumented fields found while reading the handlers. --- openapi.yaml | 335 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 220 insertions(+), 115 deletions(-) diff --git a/openapi.yaml b/openapi.yaml index 9d2c9c738..734ed8e63 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -113,67 +113,13 @@ paths: signature: "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1b" chain: "ethereum" schema: - type: object - description: |- - For the refresh token flow, supply only `refresh_token`. - For the email/phone with password flow, supply `email`, `phone` and `password` with an optional `gotrue_meta_security`. - For the OIDC ID token flow, supply `id_token`, `nonce`, `provider`, `client_id`, `issuer` with an optional `gotrue_meta_security`. - For the Web3 flow, supply `message`, `signature`, and `chain`. - properties: - refresh_token: - type: string - password: - type: string - email: - type: string - format: email - phone: - type: string - format: phone - id_token: - type: string - access_token: - type: string - description: Provide only when `grant_type` is `id_token` and the provided ID token requires the presence of an access token to be accepted (usually by having an `at_hash` claim). - nonce: - type: string - provider: - type: string - enum: - - google - - apple - - azure - - facebook - - keycloak - client_id: - type: string - issuer: - type: string - description: If `provider` is `azure` then you can specify any Azure OIDC issuer string here, which will be used for verification. - gotrue_meta_security: - $ref: "#/components/schemas/GoTrueSecurity" - auth_code: - type: string - format: uuid - code_verifier: - type: string - message: - type: string - description: | - Signed message for Web3 authentication following the Sign in with Solana (SIWS) or Sign in with Ethereum (SIWE) standard. Must include: `Issued At`, `URI`, `Version`. - signature: - type: string - description: | - The signature of the message for Web3 authentication. - For Solana: Base64 or Base64-URL encoded. - For Ethereum: hexadecimal string with 0x prefix. - chain: - type: string - description: What blockchain is the Web3 message and signature for. - enum: - - solana - - ethereum - example: solana + description: The request shape depends on the `grant_type` query parameter. + oneOf: + - $ref: "#/components/schemas/PasswordGrantRequest" + - $ref: "#/components/schemas/RefreshTokenGrantRequest" + - $ref: "#/components/schemas/IdTokenGrantRequest" + - $ref: "#/components/schemas/PKCEGrantRequest" + - $ref: "#/components/schemas/Web3GrantRequest" responses: 200: description: > @@ -186,9 +132,9 @@ paths: 400: $ref: "#/components/responses/BadRequestResponse" 401: - $ref: "#/components/responses/ForbiddenResponse" - 403: $ref: "#/components/responses/UnauthorizedResponse" + 403: + $ref: "#/components/responses/ForbiddenResponse" 500: $ref: "#/components/responses/InternalServerErrorResponse" 429: @@ -268,40 +214,10 @@ paths: content: application/json: schema: - type: object - properties: - type: - type: string - enum: - - signup - - recovery - - invite - - magiclink - - email_change - - sms - - phone_change - token: - type: string - token_hash: - type: string - description: > - The hashed value of token. Applicable only if used with `type` and nothing else. - email: - type: string - format: email - description: > - Applicable only if `type` is with regards to an email address. - phone: - type: string - format: phone - description: > - Applicable only if `type` is with regards to an phone number. - redirect_to: - type: string - format: uri - description: > - (Optional) URL to redirect back into the app on after verification completes successfully. If not specified will use the "Site URL" configuration option. If not allowed per the allow list it will use the "Site URL" configuration option. - + description: Provide either a plaintext `token` (with `email` or `phone`) or a `token_hash`, never both. + oneOf: + - $ref: "#/components/schemas/VerifyTokenRequest" + - $ref: "#/components/schemas/VerifyTokenHashRequest" responses: 200: description: An access and refresh token. @@ -1012,24 +928,16 @@ paths: content: application/json: schema: - type: object - required: - - factor_type - properties: - factor_type: - type: string - enum: - - totp - - phone - - webauthn - friendly_name: - type: string - issuer: - type: string - format: uri - phone: - type: string - format: phone + oneOf: + - $ref: "#/components/schemas/EnrollTOTPFactorRequest" + - $ref: "#/components/schemas/EnrollPhoneFactorRequest" + - $ref: "#/components/schemas/EnrollWebAuthnFactorRequest" + discriminator: + propertyName: factor_type + mapping: + totp: "#/components/schemas/EnrollTOTPFactorRequest" + phone: "#/components/schemas/EnrollPhoneFactorRequest" + webauthn: "#/components/schemas/EnrollWebAuthnFactorRequest" responses: 200: description: > @@ -3140,6 +3048,203 @@ components: captcha_token: type: string + PasswordGrantRequest: + type: object + description: Sign in with an email or phone number and password. Provide exactly one of `email` or `phone`. + required: + - password + properties: + email: + type: string + format: email + phone: + type: string + format: phone + password: + type: string + gotrue_meta_security: + $ref: "#/components/schemas/GoTrueSecurity" + + RefreshTokenGrantRequest: + type: object + description: Exchange a refresh token for a new access and refresh token. CAPTCHA protection does not apply to this grant. + required: + - refresh_token + properties: + refresh_token: + type: string + + IdTokenGrantRequest: + type: object + description: Sign in using an OIDC ID token, e.g. one obtained from Sign in with Apple or Google. Only offered in experimental mode. + required: + - id_token + - provider + properties: + id_token: + type: string + access_token: + type: string + description: Provide only when the provided ID token requires the presence of an access token to be accepted (usually by having an `at_hash` claim). + nonce: + type: string + provider: + type: string + enum: + - google + - apple + - azure + - facebook + - keycloak + client_id: + type: string + issuer: + type: string + description: If `provider` is `azure` then you can specify any Azure OIDC issuer string here, which will be used for verification. + link_identity: + type: boolean + description: (Optional) Link this identity to the currently signed-in user instead of signing in as the identity's owner. + gotrue_meta_security: + $ref: "#/components/schemas/GoTrueSecurity" + + PKCEGrantRequest: + type: object + description: Exchange a PKCE authorization code for an access and refresh token. + required: + - auth_code + - code_verifier + properties: + auth_code: + type: string + format: uuid + code_verifier: + type: string + gotrue_meta_security: + $ref: "#/components/schemas/GoTrueSecurity" + + Web3GrantRequest: + type: object + description: Sign in with a Web3 wallet by proving possession of a signed Sign-In-With-Solana (SIWS) or Sign-In-With-Ethereum (SIWE) message. + required: + - message + - signature + - chain + properties: + message: + type: string + description: | + Signed message for Web3 authentication following the Sign in with Solana (SIWS) or Sign in with Ethereum (SIWE) standard. Must include: `Issued At`, `URI`, `Version`. + signature: + type: string + description: | + The signature of the message for Web3 authentication. + For Solana: Base64 or Base64-URL encoded. + For Ethereum: hexadecimal string with 0x prefix. + chain: + type: string + description: What blockchain is the Web3 message and signature for. + enum: + - solana + - ethereum + example: solana + gotrue_meta_security: + $ref: "#/components/schemas/GoTrueSecurity" + + VerifyTokenRequest: + type: object + description: Verify a plaintext one-time password (OTP) sent to an email address or phone number. + required: + - type + - token + properties: + type: + type: string + enum: + - signup + - recovery + - invite + - magiclink + - email_change + - sms + - phone_change + token: + type: string + email: + type: string + format: email + description: Provide when `type` concerns an email address. Exactly one of `email` or `phone` must be set. + phone: + type: string + format: phone + description: Provide when `type` concerns a phone number. Exactly one of `email` or `phone` must be set. + redirect_to: + type: string + format: uri + description: > + (Optional) URL to redirect back into the app on after verification completes successfully. If not specified will use the "Site URL" configuration option. If not allowed per the allow list it will use the "Site URL" configuration option. + + VerifyTokenHashRequest: + type: object + description: Verify a token hash previously issued to this server, e.g. the `token_hash` embedded in a confirmation link. No other property may be provided alongside `token_hash`. + required: + - type + - token_hash + properties: + type: + type: string + enum: + - signup + - recovery + - invite + - magiclink + - email_change + - sms + - phone_change + token_hash: + type: string + description: The hashed value of token. + + EnrollTOTPFactorRequest: + type: object + required: + - factor_type + properties: + factor_type: + type: string + enum: [totp] + friendly_name: + type: string + issuer: + type: string + format: uri + description: (Optional) Overrides the issuer name shown in the authenticator app. Defaults to the site URL's host. + + EnrollPhoneFactorRequest: + type: object + required: + - factor_type + - phone + properties: + factor_type: + type: string + enum: [phone] + friendly_name: + type: string + phone: + type: string + format: phone + + EnrollWebAuthnFactorRequest: + type: object + required: + - factor_type + properties: + factor_type: + type: string + enum: [webauthn] + friendly_name: + type: string + ErrorSchema: type: object properties: